draw: rewrite primitive assembler
authorZack Rusin <zackr@vmware.com>
Thu, 8 Aug 2013 19:44:10 +0000 (15:44 -0400)
committerZack Rusin <zackr@vmware.com>
Fri, 9 Aug 2013 00:54:25 +0000 (20:54 -0400)
We can't be injecting the primitive id's in the pipeline because
by that time the primitives have already been decomposed. To
properly number the primitives we need to handle the adjacency
primitives by hand. This patch moves the prim id injection into
the original primitive assembler and completely removes the
useless pipeline stage.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/Makefile.sources
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_pipe.c
src/gallium/auxiliary/draw/draw_pipe.h
src/gallium/auxiliary/draw/draw_pipe_ia.c [deleted file]
src/gallium/auxiliary/draw/draw_pipe_validate.c
src/gallium/auxiliary/draw/draw_prim_assembler.c
src/gallium/auxiliary/draw/draw_prim_assembler.h
src/gallium/auxiliary/draw/draw_private.h

index b0172de5270cb1b5da57bbbe4bce8b638ee9005a..acbcef7e2ed48635c89b99b9b4abc716b212a29b 100644 (file)
@@ -13,7 +13,6 @@ C_SOURCES := \
        draw/draw_pipe_clip.c \
        draw/draw_pipe_cull.c \
        draw/draw_pipe_flatshade.c \
-        draw/draw_pipe_ia.c \
        draw/draw_pipe_offset.c \
        draw/draw_pipe_pstipple.c \
        draw/draw_pipe_stipple.c \
index 2dc6772e7fb84a168448ada2ae49c3530186bacf..2d4843ebe252310ed28dfe6007c0eaf1e4379023 100644 (file)
@@ -40,6 +40,7 @@
 #include "util/u_prim.h"
 #include "draw_context.h"
 #include "draw_pipe.h"
+#include "draw_prim_assembler.h"
 #include "draw_vs.h"
 #include "draw_gs.h"
 
@@ -95,6 +96,10 @@ draw_create_context(struct pipe_context *pipe, boolean try_llvm)
    if (!draw_init(draw))
       goto err_destroy;
 
+   draw->ia = draw_prim_assembler_create(draw);
+   if (!draw->ia)
+      goto err_destroy;
+
    return draw;
 
 err_destroy:
@@ -206,6 +211,7 @@ void draw_destroy( struct draw_context *draw )
       draw->render->destroy( draw->render );
    */
 
+   draw_prim_assembler_destroy(draw->ia);
    draw_pipeline_destroy( draw );
    draw_pt_destroy( draw );
    draw_vs_destroy( draw );
@@ -556,7 +562,7 @@ void
 draw_prepare_shader_outputs(struct draw_context *draw)
 {
    draw_remove_extra_vertex_attribs(draw);
-   draw_ia_prepare_outputs(draw, draw->pipeline.ia);
+   draw_prim_assembler_prepare_outputs(draw->ia);
    draw_unfilled_prepare_outputs(draw, draw->pipeline.unfilled);
 }
 
index 81402997f82e2ac1bd9ac176037e21b183702f34..f1ee6cb1b0adb219040228b9c06449237d7c663a 100644 (file)
@@ -49,7 +49,6 @@ boolean draw_pipeline_init( struct draw_context *draw )
    draw->pipeline.clip      = draw_clip_stage( draw );
    draw->pipeline.flatshade = draw_flatshade_stage( draw );
    draw->pipeline.cull      = draw_cull_stage( draw );
-   draw->pipeline.ia        = draw_ia_stage( draw );
    draw->pipeline.validate  = draw_validate_stage( draw );
    draw->pipeline.first     = draw->pipeline.validate;
 
@@ -62,7 +61,6 @@ boolean draw_pipeline_init( struct draw_context *draw )
        !draw->pipeline.clip ||
        !draw->pipeline.flatshade ||
        !draw->pipeline.cull ||
-       !draw->pipeline.ia ||
        !draw->pipeline.validate)
       return FALSE;
 
@@ -97,8 +95,6 @@ void draw_pipeline_destroy( struct draw_context *draw )
       draw->pipeline.flatshade->destroy( draw->pipeline.flatshade );
    if (draw->pipeline.cull)
       draw->pipeline.cull->destroy( draw->pipeline.cull );
-   if (draw->pipeline.ia)
-      draw->pipeline.ia->destroy( draw->pipeline.ia );
    if (draw->pipeline.validate)
       draw->pipeline.validate->destroy( draw->pipeline.validate );
    if (draw->pipeline.aaline)
index 70822a41901e6a8c024772a4e2a5357ada23be59..7c9ed6c31d928b3d3ad1534497ba74cb2dab3720 100644 (file)
@@ -91,10 +91,6 @@ extern struct draw_stage *draw_stipple_stage( struct draw_context *context );
 extern struct draw_stage *draw_wide_line_stage( struct draw_context *context );
 extern struct draw_stage *draw_wide_point_stage( struct draw_context *context );
 extern struct draw_stage *draw_validate_stage( struct draw_context *context );
-extern struct draw_stage *draw_ia_stage(struct draw_context *context);
-
-boolean draw_ia_stage_required(const struct draw_context *context,
-                               unsigned prim);
 
 extern void draw_free_temp_verts( struct draw_stage *stage );
 extern boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr );
@@ -108,9 +104,6 @@ void draw_pipe_passthrough_point(struct draw_stage *stage, struct prim_header *h
 
 void draw_unfilled_prepare_outputs(struct draw_context *context,
                                    struct draw_stage *stage);
-void draw_ia_prepare_outputs(struct draw_context *context,
-                             struct draw_stage *stage);
-
 
 /**
  * Get a writeable copy of a vertex.
diff --git a/src/gallium/auxiliary/draw/draw_pipe_ia.c b/src/gallium/auxiliary/draw/draw_pipe_ia.c
deleted file mode 100644 (file)
index d64f19b..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2013 VMware
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \brief  Used to decompose adjacency primitives and inject the prim id
- */
-
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "pipe/p_defines.h"
-#include "draw_pipe.h"
-#include "draw_fs.h"
-#include "draw_gs.h"
-
-
-struct ia_stage {
-   struct draw_stage stage;
-   int primid_slot;
-   unsigned primid;
-};
-
-
-static INLINE struct ia_stage *
-ia_stage(struct draw_stage *stage)
-{
-   return (struct ia_stage *)stage;
-}
-
-
-static void
-inject_primid(struct draw_stage *stage,
-              struct prim_header *header,
-              unsigned num_verts)
-{
-   struct ia_stage *ia = ia_stage(stage);
-   unsigned slot = ia->primid_slot;
-   unsigned i;
-   unsigned primid = ia->primid;
-
-   /* In case the backend doesn't care about it */
-   if (slot < 0) {
-      return;
-   }
-
-   for (i = 0; i < num_verts; ++i) {
-      struct vertex_header *v = header->v[i];
-      /* We have to reset the vertex_id because it's used by
-       * vbuf to figure out if the vertex had already been
-       * emitted. For line/tri strips the first vertex of
-       * subsequent primitives would already be emitted,
-       * but since we're changing the primitive id on the vertex
-       * we want to make sure it's reemitted with the correct
-       * data.
-       */
-      v->vertex_id = UNDEFINED_VERTEX_ID;
-      memcpy(&v->data[slot][0], &primid, sizeof(primid));
-      memcpy(&v->data[slot][1], &primid, sizeof(primid));
-      memcpy(&v->data[slot][2], &primid, sizeof(primid));
-      memcpy(&v->data[slot][3], &primid, sizeof(primid));
-   }
-   ++ia->primid;
-}
-
-
-static void
-ia_point(struct draw_stage *stage,
-         struct prim_header *header)
-{
-   inject_primid(stage, header, 1);
-   stage->next->point(stage->next, header);
-}
-
-static void
-ia_line(struct draw_stage *stage,
-        struct prim_header *header)
-{
-   inject_primid(stage, header, 2);
-   stage->next->line(stage->next, header);
-}
-
-static void
-ia_tri(struct draw_stage *stage,
-       struct prim_header *header)
-{
-   inject_primid(stage, header, 3);
-   stage->next->tri(stage->next, header);
-}
-
-static void
-ia_first_point(struct draw_stage *stage,
-               struct prim_header *header)
-{
-   struct ia_stage *ia = ia_stage(stage);
-
-   if (ia->primid_slot >= 0) {
-      stage->point = ia_point;
-   } else {
-      stage->point = draw_pipe_passthrough_point;
-   }
-
-   stage->point(stage, header);
-}
-
-static void
-ia_first_line(struct draw_stage *stage,
-              struct prim_header *header)
-{
-   struct ia_stage *ia = ia_stage(stage);
-
-   if (ia->primid_slot >= 0) {
-      stage->line = ia_line;
-   } else {
-      stage->line = draw_pipe_passthrough_line;
-   }
-
-   stage->line(stage, header);
-}
-
-static void
-ia_first_tri(struct draw_stage *stage,
-             struct prim_header *header)
-{
-   struct ia_stage *ia = ia_stage(stage);
-
-   if (ia->primid_slot >= 0) {
-      stage->tri = ia_tri;
-   } else {
-      stage->tri = draw_pipe_passthrough_tri;
-   }
-
-   stage->tri(stage, header);
-}
-
-
-static void
-ia_flush(struct draw_stage *stage, unsigned flags)
-{
-   stage->point = ia_first_point;
-   stage->line = ia_first_line;
-   stage->tri = ia_first_tri;
-   stage->next->flush(stage->next, flags);
-}
-
-
-static void
-ia_reset_stipple_counter(struct draw_stage *stage)
-{
-   stage->next->reset_stipple_counter(stage->next);
-}
-
-
-static void
-ia_destroy(struct draw_stage *stage)
-{
-   draw_free_temp_verts(stage);
-   FREE(stage);
-}
-
-
-static boolean
-needs_primid(const struct draw_context *draw)
-{
-   const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
-   const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
-   if (fs && fs->info.uses_primid) {
-      return !gs || !gs->info.uses_primid;
-   }
-   return FALSE;
-}
-
-boolean
-draw_ia_stage_required(const struct draw_context *draw, unsigned prim)
-{
-   const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
-   if (needs_primid(draw)) {
-      return TRUE;
-   }
-
-   if (gs) {
-      return FALSE;
-   }
-
-   switch (prim) {
-   case PIPE_PRIM_LINES_ADJACENCY:
-   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
-   case PIPE_PRIM_TRIANGLES_ADJACENCY:
-   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
-      return TRUE;
-   default:
-      return FALSE;
-   }
-}
-
-void
-draw_ia_prepare_outputs(struct draw_context *draw,
-                        struct draw_stage *stage)
-{
-   struct ia_stage *ia = ia_stage(stage);
-   if (needs_primid(draw)) {
-      ia->primid_slot = draw_alloc_extra_vertex_attrib(
-         stage->draw, TGSI_SEMANTIC_PRIMID, 0);
-   } else {
-      ia->primid_slot = -1;
-   }
-   ia->primid = 0;
-}
-
-struct draw_stage *
-draw_ia_stage(struct draw_context *draw)
-{
-   struct ia_stage *ia = CALLOC_STRUCT(ia_stage);
-   if (ia == NULL)
-      goto fail;
-
-   ia->stage.draw = draw;
-   ia->stage.name = "ia";
-   ia->stage.next = NULL;
-   ia->stage.point = ia_first_point;
-   ia->stage.line = ia_first_line;
-   ia->stage.tri = ia_first_tri;
-   ia->stage.flush = ia_flush;
-   ia->stage.reset_stipple_counter = ia_reset_stipple_counter;
-   ia->stage.destroy = ia_destroy;
-
-   if (!draw_alloc_temp_verts(&ia->stage, 0))
-      goto fail;
-
-   return &ia->stage;
-
-fail:
-   if (ia)
-      ia->stage.destroy(&ia->stage);
-
-   return NULL;
-}
index 9b2f5845e09eafa319473f4d5768c4441e123d74..3562acdbcdca6246f40f0f1a47888dbba1531daa 100644 (file)
@@ -76,14 +76,6 @@ draw_need_pipeline(const struct draw_context *draw,
                                           prim );
    }
 
-   /* If we need to decompose the primitives or inject
-    * primitive id information then we have to run
-    * the pipeline.
-    */
-   if (draw_ia_stage_required(draw, prim)) {
-      return TRUE;
-   }
-
    /* Don't have to worry about triangles turning into lines/points
     * and triggering the pipeline, because we have to trigger the
     * pipeline *anyway* if unfilled mode is active.
@@ -288,12 +280,6 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
       next = draw->pipeline.clip;
    }
 
-   /* Input assembler */
-   if (draw_ia_stage_required(draw, draw->pt.prim)) {
-      draw->pipeline.ia->next = next;
-      next = draw->pipeline.ia;
-   }
-
    draw->pipeline.first = next;
 
    if (0) {
index 9bedeeadb44596cbb2902744c534ac74f4454d0c..eba441c17ade3be37b2e8a0f2c861bafada87385 100644 (file)
@@ -27,6 +27,9 @@
 
 #include "draw_prim_assembler.h"
 
+#include "draw_fs.h"
+#include "draw_gs.h"
+
 #include "util/u_debug.h"
 #include "util/u_memory.h"
 #include "util/u_prim.h"
@@ -42,8 +45,28 @@ struct draw_assembler
 
    const struct draw_prim_info *input_prims;
    const struct draw_vertex_info *input_verts;
+
+   boolean needs_primid;
+   int primid_slot;
+   unsigned primid;
+
+   boolean is_strip;
+   boolean is_first_prim;
+   unsigned num_prims;
 };
 
+
+static boolean
+needs_primid(const struct draw_context *draw)
+{
+   const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
+   const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
+   if (fs && fs->info.uses_primid) {
+      return !gs || !gs->info.uses_primid;
+   }
+   return FALSE;
+}
+
 boolean
 draw_prim_assembler_is_required(const struct draw_context *draw,
                                 const struct draw_prim_info *prim_info,
@@ -56,7 +79,7 @@ draw_prim_assembler_is_required(const struct draw_context *draw,
    case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
       return TRUE;
    default:
-      return FALSE;
+      return needs_primid(draw);
    }
 }
 
@@ -84,16 +107,43 @@ copy_verts(struct draw_assembler *asmblr,
              asmblr->input_verts->vertex_size);
       asmblr->output_verts->count += 1;
    }
+   ++asmblr->num_prims;
+}
+
+
+static void
+inject_primid(struct draw_assembler *asmblr,
+                      unsigned idx,
+                      unsigned primid)
+{
+   int slot = asmblr->primid_slot;
+   char *input = (char*)asmblr->input_verts->verts;
+   unsigned input_offset = asmblr->input_verts->stride * idx;
+   struct vertex_header *v = (struct vertex_header*)(input + input_offset);
+
+   /* In case the backend doesn't care about it */
+   if (slot < 0) {
+      return;
+   }
+
+   memcpy(&v->data[slot][0], &primid, sizeof(primid));
+   memcpy(&v->data[slot][1], &primid, sizeof(primid));
+   memcpy(&v->data[slot][2], &primid, sizeof(primid));
+   memcpy(&v->data[slot][3], &primid, sizeof(primid));
 }
 
+
 static void
 prim_point(struct draw_assembler *asmblr,
            unsigned idx)
 {
    unsigned indices[1];
 
+   if (asmblr->needs_primid) {
+      inject_primid(asmblr, idx, asmblr->primid++);
+   }
    indices[0] = idx;
-
+   
    copy_verts(asmblr, indices, 1);
 }
 
@@ -103,6 +153,18 @@ prim_line(struct draw_assembler *asmblr,
 {
    unsigned indices[2];
 
+   if (asmblr->needs_primid) {
+      if (asmblr->is_strip && asmblr->is_first_prim) {
+         inject_primid(asmblr, i0, asmblr->primid++);
+         inject_primid(asmblr, i1, asmblr->primid++);
+         asmblr->is_first_prim = FALSE;
+      } else if (asmblr->is_strip) {
+            inject_primid(asmblr, i1, asmblr->primid++);
+      } else {
+         inject_primid(asmblr, i0, asmblr->primid);
+         inject_primid(asmblr, i1, asmblr->primid++);
+      }
+   }
    indices[0] = i0;
    indices[1] = i1;
 
@@ -115,6 +177,19 @@ prim_line_adj(struct draw_assembler *asmblr,
 {
    unsigned indices[2];
 
+   if (asmblr->needs_primid) {
+      if (asmblr->is_strip && asmblr->is_first_prim) {
+         inject_primid(asmblr, i1, asmblr->primid++);
+         inject_primid(asmblr, i2, asmblr->primid++);
+         asmblr->is_first_prim = FALSE;
+      } else if (asmblr->is_strip) {
+         inject_primid(asmblr, i2, asmblr->primid++);
+      } else {
+         inject_primid(asmblr, i1, asmblr->primid);
+         inject_primid(asmblr, i2, asmblr->primid++);
+      }
+   }
+
    indices[0] = i1;
    indices[1] = i2;
 
@@ -127,6 +202,24 @@ prim_tri(struct draw_assembler *asmblr,
 {
    unsigned indices[3];
 
+   if (asmblr->needs_primid) {
+      if (asmblr->is_strip && asmblr->is_first_prim) {
+         inject_primid(asmblr, i0, asmblr->primid++);
+         inject_primid(asmblr, i1, asmblr->primid++);
+         inject_primid(asmblr, i2, asmblr->primid++);
+         asmblr->is_first_prim = FALSE;
+      } else if (asmblr->is_strip) {
+         if (asmblr->num_prims & 1) {
+            inject_primid(asmblr, i1, asmblr->primid++);
+         } else {
+            inject_primid(asmblr, i2, asmblr->primid++);
+         }
+      } else {
+         inject_primid(asmblr, i0, asmblr->primid);
+         inject_primid(asmblr, i1, asmblr->primid);
+         inject_primid(asmblr, i2, asmblr->primid++);
+      }
+   }
    indices[0] = i0;
    indices[1] = i1;
    indices[2] = i2;
@@ -141,6 +234,25 @@ prim_tri_adj(struct draw_assembler *asmblr,
 {
    unsigned indices[3];
 
+   if (asmblr->needs_primid) {
+      if (asmblr->is_strip && asmblr->is_first_prim) {
+         inject_primid(asmblr, i0, asmblr->primid++);
+         inject_primid(asmblr, i2, asmblr->primid++);
+         inject_primid(asmblr, i4, asmblr->primid++);
+         asmblr->is_first_prim = FALSE;
+      } else if (asmblr->is_strip) {
+         if (asmblr->num_prims & 1) {
+            inject_primid(asmblr, i2, asmblr->primid++);
+         } else {
+            inject_primid(asmblr, i4, asmblr->primid++);
+         }
+      } else {
+         inject_primid(asmblr, i0, asmblr->primid);
+         inject_primid(asmblr, i2, asmblr->primid);
+         inject_primid(asmblr, i4, asmblr->primid);
+         asmblr->primid++;
+      }
+   }
    indices[0] = i0;
    indices[1] = i2;
    indices[2] = i4;
@@ -148,6 +260,18 @@ prim_tri_adj(struct draw_assembler *asmblr,
    copy_verts(asmblr, indices, 3);
 }
 
+void
+draw_prim_assembler_prepare_outputs(struct draw_assembler *ia)
+{
+   struct draw_context *draw = ia->draw;
+   if (needs_primid(draw)) {
+      ia->primid_slot = draw_alloc_extra_vertex_attrib(
+         ia->draw, TGSI_SEMANTIC_PRIMID, 0);
+   } else {
+      ia->primid_slot = -1;
+   }
+   ia->primid = 0;
+}
 
 
 #define FUNC assembler_run_linear
@@ -178,18 +302,26 @@ draw_prim_assembler_run(struct draw_context *draw,
                         struct draw_prim_info *output_prims,
                         struct draw_vertex_info *output_verts)
 {
-   struct draw_assembler asmblr;
+   struct draw_assembler *asmblr = draw->ia;
    unsigned start, i;
    unsigned assembled_prim = u_assembled_prim(input_prims->prim);
    unsigned max_primitives = u_decomposed_prims_for_vertices(
       input_prims->prim, input_prims->count);
    unsigned max_verts = u_vertices_per_prim(assembled_prim) * max_primitives;
 
-   asmblr.draw = draw;
-   asmblr.output_prims = output_prims;
-   asmblr.output_verts = output_verts;
-   asmblr.input_prims = input_prims;
-   asmblr.input_verts = input_verts;
+   asmblr->output_prims = output_prims;
+   asmblr->output_verts = output_verts;
+   asmblr->input_prims = input_prims;
+   asmblr->input_verts = input_verts;
+   asmblr->is_strip =
+      (input_prims->prim == PIPE_PRIM_TRIANGLE_STRIP ||
+       input_prims->prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) ||
+      (input_prims->prim == PIPE_PRIM_LINE_STRIP ||
+       input_prims->prim == PIPE_PRIM_LINE_STRIP_ADJACENCY);
+   asmblr->needs_primid = needs_primid(asmblr->draw);
+   asmblr->is_first_prim = asmblr->is_strip;
+   asmblr->primid = 0;
+   asmblr->num_prims = 0;
 
    output_prims->linear = TRUE;
    output_prims->elts = NULL;
@@ -212,10 +344,10 @@ draw_prim_assembler_run(struct draw_context *draw,
    {
       unsigned count = input_prims->primitive_lengths[i];
       if (input_prims->linear) {
-         assembler_run_linear(&asmblr, input_prims, input_verts,
+         assembler_run_linear(asmblr, input_prims, input_verts,
                               start, count);
       } else {
-         assembler_run_elts(&asmblr, input_prims, input_verts,
+         assembler_run_elts(asmblr, input_prims, input_verts,
                             start, count);
       }
    }
@@ -223,3 +355,19 @@ draw_prim_assembler_run(struct draw_context *draw,
    output_prims->primitive_lengths[0] = output_verts->count;
    output_prims->count = output_verts->count;
 }
+
+struct draw_assembler *
+draw_prim_assembler_create(struct draw_context *draw)
+{
+   struct draw_assembler *ia = CALLOC_STRUCT( draw_assembler );
+
+   ia->draw = draw;
+
+   return ia;
+}
+
+void
+draw_prim_assembler_destroy(struct draw_assembler *ia)
+{
+   FREE(ia);
+}
index 2ef7c518063fda7c3f79d6a548f5a03c16bb1943..5ba715b8135ea760caedbfe4013d6ea562f45260 100644 (file)
 
 #include "draw/draw_private.h"
 
+struct draw_assembler;
+
+struct draw_assembler *
+draw_prim_assembler_create(struct draw_context *draw);
+
+void
+draw_prim_assembler_destroy(struct draw_assembler *ia);
+
 boolean
 draw_prim_assembler_is_required(const struct draw_context *draw,
                                 const struct draw_prim_info *prim_info,
@@ -59,4 +67,8 @@ draw_prim_assembler_run(struct draw_context *draw,
                         struct draw_vertex_info *out_vert_info);
 
 
+void
+draw_prim_assembler_prepare_outputs(struct draw_assembler *ia);
+
+
 #endif
index b21e79568453b078773d7dda2d079d2366b5e80f..ba93b09337753508e413aca2ca075a25d6a96265 100644 (file)
@@ -68,6 +68,7 @@ struct vbuf_render;
 struct tgsi_exec_machine;
 struct tgsi_sampler;
 struct draw_pt_front_end;
+struct draw_assembler;
 
 
 /**
@@ -130,7 +131,6 @@ struct draw_context
       struct draw_stage *wide_line;
       struct draw_stage *wide_point;
       struct draw_stage *rasterize;
-      struct draw_stage *ia;
 
       float wide_point_threshold; /**< convert pnts to tris if larger than this */
       float wide_line_threshold;  /**< convert lines to tris if wider than this */
@@ -331,6 +331,8 @@ struct draw_context
    struct pipe_query_data_pipeline_statistics statistics;
    boolean collect_statistics;
 
+   struct draw_assembler *ia;
+
    void *driver_private;
 };