summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/Makefile.sources1
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_ia.c259
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_validate.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_prim_assembler.c168
-rw-r--r--src/gallium/auxiliary/draw/draw_prim_assembler.h12
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h4
9 files changed, 180 insertions, 297 deletions
diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources
index b0172de5270..acbcef7e2ed 100644
--- a/src/gallium/auxiliary/Makefile.sources
+++ b/src/gallium/auxiliary/Makefile.sources
@@ -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 \
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 2dc6772e7fb..2d4843ebe25 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -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);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 81402997f82..f1ee6cb1b0a 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -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)
diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h
index 70822a41901..7c9ed6c31d9 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.h
+++ b/src/gallium/auxiliary/draw/draw_pipe.h
@@ -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
index d64f19b38cb..00000000000
--- a/src/gallium/auxiliary/draw/draw_pipe_ia.c
+++ /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;
-}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c
index 9b2f5845e09..3562acdbcdc 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_validate.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c
@@ -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) {
diff --git a/src/gallium/auxiliary/draw/draw_prim_assembler.c b/src/gallium/auxiliary/draw/draw_prim_assembler.c
index 9bedeeadb44..eba441c17ad 100644
--- a/src/gallium/auxiliary/draw/draw_prim_assembler.c
+++ b/src/gallium/auxiliary/draw/draw_prim_assembler.c
@@ -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);
+}
diff --git a/src/gallium/auxiliary/draw/draw_prim_assembler.h b/src/gallium/auxiliary/draw/draw_prim_assembler.h
index 2ef7c518063..5ba715b8135 100644
--- a/src/gallium/auxiliary/draw/draw_prim_assembler.h
+++ b/src/gallium/auxiliary/draw/draw_prim_assembler.h
@@ -46,6 +46,14 @@
#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
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index b21e7956845..ba93b093377 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -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;
};