Yea, it's quite bonkers, but that's the way it has to be to make it work right now. Personally I'd really like to write a new version of draw, without the 5 emit paths, 4 different vertex shading paths, with interface that is capable of emitting more than just float[4]'s... For now though this works, even if it is very ugly.
z ----- Original Message ----- > Am 02.08.2013 08:28, schrieb Zack Rusin: > > we used to have a face primitive assembler that we ran after if > > the gs was missing but we had adjacency primitives in the pipeline, > > lets convert it to a pipeline stage, which allows us to use it > > to inject outputs (primitive id) into the vertices. it's also > > a lot cleaner because the decomposition is already handled for us. > > > > Signed-off-by: Zack Rusin <za...@vmware.com> > > --- > > src/gallium/auxiliary/Makefile.sources | 2 +- > > src/gallium/auxiliary/draw/draw_context.c | 1 + > > src/gallium/auxiliary/draw/draw_pipe.c | 4 + > > src/gallium/auxiliary/draw/draw_pipe.h | 5 + > > src/gallium/auxiliary/draw/draw_pipe_ia.c | 253 > > ++++++++++++++++++++ > > src/gallium/auxiliary/draw/draw_pipe_validate.c | 15 +- > > src/gallium/auxiliary/draw/draw_prim_assembler.c | 225 > > ----------------- > > src/gallium/auxiliary/draw/draw_prim_assembler.h | 62 ----- > > .../auxiliary/draw/draw_prim_assembler_tmp.h | 31 --- > > src/gallium/auxiliary/draw/draw_private.h | 1 + > > .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 18 +- > > .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 18 +- > > 12 files changed, 283 insertions(+), 352 deletions(-) > > create mode 100644 src/gallium/auxiliary/draw/draw_pipe_ia.c > > delete mode 100644 src/gallium/auxiliary/draw/draw_prim_assembler.c > > delete mode 100644 src/gallium/auxiliary/draw/draw_prim_assembler.h > > delete mode 100644 src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h > > > > diff --git a/src/gallium/auxiliary/Makefile.sources > > b/src/gallium/auxiliary/Makefile.sources > > index acbcef7..ee93e8b 100644 > > --- a/src/gallium/auxiliary/Makefile.sources > > +++ b/src/gallium/auxiliary/Makefile.sources > > @@ -13,6 +13,7 @@ C_SOURCES := \ > > draw/draw_pipe_clip.c \ > > draw/draw_pipe_cull.c \ > > draw/draw_pipe_flatshade.c \ > > + draw/draw_pipe_ia.c \ > Formatting looks off here. > > > draw/draw_pipe_offset.c \ > > draw/draw_pipe_pstipple.c \ > > draw/draw_pipe_stipple.c \ > > @@ -23,7 +24,6 @@ C_SOURCES := \ > > draw/draw_pipe_vbuf.c \ > > draw/draw_pipe_wide_line.c \ > > draw/draw_pipe_wide_point.c \ > > - draw/draw_prim_assembler.c \ > > draw/draw_pt.c \ > > draw/draw_pt_emit.c \ > > draw/draw_pt_fetch.c \ > > diff --git a/src/gallium/auxiliary/draw/draw_context.c > > b/src/gallium/auxiliary/draw/draw_context.c > > index 8bf3596..bbb2904 100644 > > --- a/src/gallium/auxiliary/draw/draw_context.c > > +++ b/src/gallium/auxiliary/draw/draw_context.c > > @@ -555,6 +555,7 @@ draw_get_shader_info(const struct draw_context *draw) > > void > > draw_prepare_shader_outputs(struct draw_context *draw) > > { > > + draw_ia_prepare_outputs(draw, draw->pipeline.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 f1ee6cb..8140299 100644 > > --- a/src/gallium/auxiliary/draw/draw_pipe.c > > +++ b/src/gallium/auxiliary/draw/draw_pipe.c > > @@ -49,6 +49,7 @@ 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; > > > > @@ -61,6 +62,7 @@ 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; > > > > @@ -95,6 +97,8 @@ 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 70c286f..70822a4 100644 > > --- a/src/gallium/auxiliary/draw/draw_pipe.h > > +++ b/src/gallium/auxiliary/draw/draw_pipe.h > > @@ -91,7 +91,10 @@ 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 ); > > @@ -105,6 +108,8 @@ 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); > > > > > > /** > > diff --git a/src/gallium/auxiliary/draw/draw_pipe_ia.c > > b/src/gallium/auxiliary/draw/draw_pipe_ia.c > > new file mode 100644 > > index 0000000..9bdab8f > > --- /dev/null > > +++ b/src/gallium/auxiliary/draw/draw_pipe_ia.c > > @@ -0,0 +1,253 @@ > > +/************************************************************************** > > + * > > + * 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]; > > + /*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));*/ > > + v->data[slot][0] = primid; > > + v->data[slot][1] = primid; > > + v->data[slot][2] = primid; > > + v->data[slot][3] = primid; > > + } > holy crap we're really expecting a float prim id??? How the hell is that > going to work??? Also this is never going to be conformant (as we need a > 32bit uint we don't have enough mantissa bits). > And I believe it is a mistake to make those explicitly assign all 4 > values - this is a scalar not a vector! We really really need to make > these things scalar at some point so it's better to make some code which > could get away with accepting the wrong component to fail now imho. > > > + ++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 2dbb95c..1ce89eb 100644 > > --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c > > +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c > > @@ -53,6 +53,7 @@ static boolean triangles( unsigned prim ) > > return prim >= PIPE_PRIM_TRIANGLES; > > } > > > > + > > /** > > * Default version of a function to check if we need any special > > * pipeline stages, or whether prims/verts can go through untouched. > > @@ -76,6 +77,13 @@ 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. > > @@ -280,7 +288,12 @@ 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 > > deleted file mode 100644 > > index 9bedeea..0000000 > > --- a/src/gallium/auxiliary/draw/draw_prim_assembler.c > > +++ /dev/null > > @@ -1,225 +0,0 @@ > > -/************************************************************************** > > - * > > - * Copyright 2013 VMware, Inc. > > - * 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 VMWARE 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. > > - * > > - > > **************************************************************************/ > > - > > -#include "draw_prim_assembler.h" > > - > > -#include "util/u_debug.h" > > -#include "util/u_memory.h" > > -#include "util/u_prim.h" > > - > > -#include "pipe/p_defines.h" > > - > > -struct draw_assembler > > -{ > > - struct draw_context *draw; > > - > > - struct draw_prim_info *output_prims; > > - struct draw_vertex_info *output_verts; > > - > > - const struct draw_prim_info *input_prims; > > - const struct draw_vertex_info *input_verts; > > -}; > > - > > -boolean > > -draw_prim_assembler_is_required(const struct draw_context *draw, > > - const struct draw_prim_info *prim_info, > > - const struct draw_vertex_info *vert_info) > > -{ > > - switch (prim_info->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; > > - } > > -} > > - > > -/* > > - * Copy the vertex header along with its data from the current > > - * vertex buffer into a buffer holding vertices arranged > > - * into decomposed primitives (i.e. buffer without the > > - * adjacency vertices) > > - */ > > -static void > > -copy_verts(struct draw_assembler *asmblr, > > - unsigned *indices, unsigned num_indices) > > -{ > > - unsigned i; > > - > > - char *output = (char*)asmblr->output_verts->verts; > > - const char *input = (const char*)asmblr->input_verts->verts; > > - > > - for (i = 0; i < num_indices; ++i) { > > - unsigned idx = indices[i]; > > - unsigned output_offset = > > - asmblr->output_verts->count * asmblr->output_verts->stride; > > - unsigned input_offset = asmblr->input_verts->stride * idx; > > - memcpy(output + output_offset, input + input_offset, > > - asmblr->input_verts->vertex_size); > > - asmblr->output_verts->count += 1; > > - } > > -} > > - > > -static void > > -prim_point(struct draw_assembler *asmblr, > > - unsigned idx) > > -{ > > - unsigned indices[1]; > > - > > - indices[0] = idx; > > - > > - copy_verts(asmblr, indices, 1); > > -} > > - > > -static void > > -prim_line(struct draw_assembler *asmblr, > > - unsigned i0, unsigned i1) > > -{ > > - unsigned indices[2]; > > - > > - indices[0] = i0; > > - indices[1] = i1; > > - > > - copy_verts(asmblr, indices, 2); > > -} > > - > > -static void > > -prim_line_adj(struct draw_assembler *asmblr, > > - unsigned i0, unsigned i1, unsigned i2, unsigned i3) > > -{ > > - unsigned indices[2]; > > - > > - indices[0] = i1; > > - indices[1] = i2; > > - > > - copy_verts(asmblr, indices, 2); > > -} > > - > > -static void > > -prim_tri(struct draw_assembler *asmblr, > > - unsigned i0, unsigned i1, unsigned i2) > > -{ > > - unsigned indices[3]; > > - > > - indices[0] = i0; > > - indices[1] = i1; > > - indices[2] = i2; > > - > > - copy_verts(asmblr, indices, 3); > > -} > > - > > -static void > > -prim_tri_adj(struct draw_assembler *asmblr, > > - unsigned i0, unsigned i1, unsigned i2, > > - unsigned i3, unsigned i4, unsigned i5) > > -{ > > - unsigned indices[3]; > > - > > - indices[0] = i0; > > - indices[1] = i2; > > - indices[2] = i4; > > - > > - copy_verts(asmblr, indices, 3); > > -} > > - > > - > > - > > -#define FUNC assembler_run_linear > > -#define GET_ELT(idx) (start + (idx)) > > -#include "draw_prim_assembler_tmp.h" > > - > > -#define FUNC assembler_run_elts > > -#define LOCAL_VARS const ushort *elts = input_prims->elts; > > -#define GET_ELT(idx) (elts[start + (idx)]) > > -#include "draw_prim_assembler_tmp.h" > > - > > - > > - > > -/* > > - * Primitive assembler breaks up adjacency primitives and assembles > > - * the base primitives they represent, e.g. vertices forming > > - * PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY > > - * become vertices forming PIPE_PRIM_TRIANGLES > > - * This is needed because specification says that the adjacency > > - * primitives are only visible in the geometry shader so we need > > - * to get rid of them so that the rest of the pipeline can > > - * process the inputs. > > - */ > > -void > > -draw_prim_assembler_run(struct draw_context *draw, > > - const struct draw_prim_info *input_prims, > > - const struct draw_vertex_info *input_verts, > > - struct draw_prim_info *output_prims, > > - struct draw_vertex_info *output_verts) > > -{ > > - struct draw_assembler asmblr; > > - 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; > > - > > - output_prims->linear = TRUE; > > - output_prims->elts = NULL; > > - output_prims->start = 0; > > - output_prims->prim = u_assembled_prim(input_prims->prim); > > - output_prims->flags = 0x0; > > - output_prims->primitive_lengths = MALLOC(sizeof(unsigned)); > > - output_prims->primitive_lengths[0] = 0; > > - output_prims->primitive_count = 1; > > - > > - output_verts->vertex_size = input_verts->vertex_size; > > - output_verts->stride = input_verts->stride; > > - output_verts->verts = (struct vertex_header*)MALLOC( > > - input_verts->vertex_size * max_verts); > > - output_verts->count = 0; > > - > > - > > - for (start = i = 0; i < input_prims->primitive_count; > > - start += input_prims->primitive_lengths[i], i++) > > - { > > - unsigned count = input_prims->primitive_lengths[i]; > > - if (input_prims->linear) { > > - assembler_run_linear(&asmblr, input_prims, input_verts, > > - start, count); > > - } else { > > - assembler_run_elts(&asmblr, input_prims, input_verts, > > - start, count); > > - } > > - } > > - > > - output_prims->primitive_lengths[0] = output_verts->count; > > - output_prims->count = output_verts->count; > > -} > > diff --git a/src/gallium/auxiliary/draw/draw_prim_assembler.h > > b/src/gallium/auxiliary/draw/draw_prim_assembler.h > > deleted file mode 100644 > > index 2ef7c51..0000000 > > --- a/src/gallium/auxiliary/draw/draw_prim_assembler.h > > +++ /dev/null > > @@ -1,62 +0,0 @@ > > -/************************************************************************** > > - * > > - * Copyright 2013 VMware, Inc. > > - * 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 VMWARE 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. > > - * > > - > > **************************************************************************/ > > - > > -/* > > - * Input assembler needs to be able to decompose adjacency primitives > > - * into something that can be understood by the rest of the pipeline. > > - * The specs say that the adjacency primitives are *only* visible > > - * in the geometry shader, for everything else they need to be > > - * decomposed. Which in most of the cases is not an issue, because the > > - * geometry shader always decomposes them for us, but without geometry > > - * shader we were passing unchanged adjacency primitives to the > > - * rest of the pipeline and causing crashes everywhere. > > - * If geometry shader is missing and the input primitive is one of > > - * the adjacency primitives we use the code from this file to > > - * decompose them into something that the rest of the pipeline can > > - * understand. > > - * > > - */ > > - > > -#ifndef DRAW_PRIM_ASSEMBLER_H > > -#define DRAW_PRIM_ASSEMBLER_H > > - > > -#include "draw/draw_private.h" > > - > > -boolean > > -draw_prim_assembler_is_required(const struct draw_context *draw, > > - const struct draw_prim_info *prim_info, > > - const struct draw_vertex_info *vert_info); > > - > > -void > > -draw_prim_assembler_run(struct draw_context *draw, > > - const struct draw_prim_info *in_prim_info, > > - const struct draw_vertex_info *in_vert_info, > > - struct draw_prim_info *out_prim_info, > > - struct draw_vertex_info *out_vert_info); > > - > > - > > -#endif > > diff --git a/src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h > > b/src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h > > deleted file mode 100644 > > index 5bbacff..0000000 > > --- a/src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h > > +++ /dev/null > > @@ -1,31 +0,0 @@ > > -#define FUNC_VARS \ > > - struct draw_assembler *asmblr, \ > > - const struct draw_prim_info *input_prims, \ > > - const struct draw_vertex_info *input_verts, \ > > - unsigned start, \ > > - unsigned count > > - > > -#define FUNC_ENTER \ > > - /* declare more local vars */ \ > > - const unsigned prim = input_prims->prim; \ > > - const unsigned prim_flags = input_prims->flags; \ > > - const boolean quads_flatshade_last = FALSE; \ > > - const boolean last_vertex_last = > > !asmblr->draw->rasterizer->flatshade_first; \ > > - switch (prim) { \ > > - case PIPE_PRIM_QUADS: \ > > - case PIPE_PRIM_QUAD_STRIP: \ > > - case PIPE_PRIM_POLYGON: \ > > - debug_assert(!"unexpected primitive type in prim assembler"); \ > > - return; \ > > - default: \ > > - break; \ > > - } \ > > - > > - > > -#define POINT(i0) prim_point(asmblr, i0) > > -#define LINE(flags, i0, i1) prim_line(asmblr, i0, i1) > > -#define TRIANGLE(flags, i0, i1, i2) prim_tri(asmblr, i0, i1, i2) > > -#define LINE_ADJ(flags, i0, i1, i2, i3) prim_line_adj(asmblr, i0, > > i1, i2, i3) > > -#define TRIANGLE_ADJ(flags,i0,i1,i2,i3,i4,i5) > > prim_tri_adj(asmblr,i0,i1,i2,i3,i4,i5) > > - > > -#include "draw_decompose_tmp.h" > > diff --git a/src/gallium/auxiliary/draw/draw_private.h > > b/src/gallium/auxiliary/draw/draw_private.h > > index 868b6c7..b21e795 100644 > > --- a/src/gallium/auxiliary/draw/draw_private.h > > +++ b/src/gallium/auxiliary/draw/draw_private.h > > @@ -130,6 +130,7 @@ 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 */ > > diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c > > b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c > > index 7f23d0b..71c075f 100644 > > --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c > > +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c > > @@ -31,7 +31,6 @@ > > #include "draw/draw_context.h" > > #include "draw/draw_vbuf.h" > > #include "draw/draw_vertex.h" > > -#include "draw/draw_prim_assembler.h" > > #include "draw/draw_pt.h" > > #include "draw/draw_vs.h" > > #include "draw/draw_gs.h" > > @@ -223,8 +222,6 @@ static void fetch_pipeline_generic( struct > > draw_pt_middle_end *middle, > > struct draw_vertex_info vs_vert_info; > > struct draw_vertex_info gs_vert_info; > > struct draw_vertex_info *vert_info; > > - struct draw_prim_info ia_prim_info; > > - struct draw_vertex_info ia_vert_info; > > const struct draw_prim_info *prim_info = in_prim_info; > > boolean free_prim_info = FALSE; > > unsigned opt = fpme->opt; > > @@ -282,21 +279,10 @@ static void fetch_pipeline_generic( struct > > draw_pt_middle_end *middle, > > FREE(vert_info->verts); > > vert_info = &gs_vert_info; > > prim_info = &gs_prim_info; > > - } else { > > - if (draw_prim_assembler_is_required(draw, prim_info, vert_info)) { > > - draw_prim_assembler_run(draw, prim_info, vert_info, > > - &ia_prim_info, &ia_vert_info); > > - > > - if (ia_vert_info.count) { > > - FREE(vert_info->verts); > > - vert_info = &ia_vert_info; > > - prim_info = &ia_prim_info; > > - free_prim_info = TRUE; > > - } > > - } > > } > > + > > if (prim_info->count == 0) { > > - debug_printf("GS/IA didn't emit any vertices!\n"); > > + debug_printf("GS didn't emit any vertices!\n"); > > > > FREE(vert_info->verts); > > if (free_prim_info) { > > diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > > b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > > index f6ef5fd..fc69391 100644 > > --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > > +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > > @@ -33,7 +33,6 @@ > > #include "draw/draw_vbuf.h" > > #include "draw/draw_vertex.h" > > #include "draw/draw_pt.h" > > -#include "draw/draw_prim_assembler.h" > > #include "draw/draw_vs.h" > > #include "draw/draw_llvm.h" > > #include "gallivm/lp_bld_init.h" > > @@ -316,8 +315,6 @@ llvm_pipeline_generic( struct draw_pt_middle_end > > *middle, > > struct draw_vertex_info llvm_vert_info; > > struct draw_vertex_info gs_vert_info; > > struct draw_vertex_info *vert_info; > > - struct draw_prim_info ia_prim_info; > > - struct draw_vertex_info ia_vert_info; > > const struct draw_prim_info *prim_info = in_prim_info; > > boolean free_prim_info = FALSE; > > unsigned opt = fpme->opt; > > @@ -383,21 +380,10 @@ llvm_pipeline_generic( struct draw_pt_middle_end > > *middle, > > FREE(vert_info->verts); > > vert_info = &gs_vert_info; > > prim_info = &gs_prim_info; > > - } else { > > - if (draw_prim_assembler_is_required(draw, prim_info, vert_info)) { > > - draw_prim_assembler_run(draw, prim_info, vert_info, > > - &ia_prim_info, &ia_vert_info); > > - > > - if (ia_vert_info.count) { > > - FREE(vert_info->verts); > > - vert_info = &ia_vert_info; > > - prim_info = &ia_prim_info; > > - free_prim_info = TRUE; > > - } > > - } > > } > > + > > if (prim_info->count == 0) { > > - debug_printf("GS/IA didn't emit any vertices!\n"); > > + debug_printf("GS didn't emit any vertices!\n"); > > > > FREE(vert_info->verts); > > if (free_prim_info) { > > > > Otherwise the ia stage looks good to me. I think though we _really_ > reached the limits of our vec4 float interface between stages - we just > keep adding more and more d3d10 hacks on top of that legacy inteface. > > Roland > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev