From 08589f71051e588b0bb7d0c8b529976c85398dd1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 26 Sep 2007 11:56:17 +0100 Subject: [PATCH] Make flushing more lazy in the draw module. --- src/mesa/pipe/draw/draw_arrays.c | 76 ----------- src/mesa/pipe/draw/draw_clip.c | 4 - src/mesa/pipe/draw/draw_context.c | 118 ++++++++-------- src/mesa/pipe/draw/draw_context.h | 24 ++-- src/mesa/pipe/draw/draw_debug.c | 115 ++++++++++++++++ src/mesa/pipe/draw/draw_feedback.c | 2 + src/mesa/pipe/draw/draw_prim.c | 172 ++++++++++-------------- src/mesa/pipe/draw/draw_prim.h | 5 - src/mesa/pipe/draw/draw_private.h | 23 +++- src/mesa/pipe/draw/draw_validate.c | 124 +++++++++++++++++ src/mesa/pipe/draw/draw_vertex_cache.c | 17 +-- src/mesa/pipe/draw/draw_vertex_fetch.c | 2 + src/mesa/pipe/draw/draw_vertex_shader.c | 5 +- src/mesa/pipe/softpipe/sp_draw_arrays.c | 17 ++- src/mesa/pipe/softpipe/sp_prim_setup.c | 2 +- src/mesa/sources | 3 +- 16 files changed, 430 insertions(+), 279 deletions(-) delete mode 100644 src/mesa/pipe/draw/draw_arrays.c create mode 100644 src/mesa/pipe/draw/draw_debug.c create mode 100644 src/mesa/pipe/draw/draw_validate.c diff --git a/src/mesa/pipe/draw/draw_arrays.c b/src/mesa/pipe/draw/draw_arrays.c deleted file mode 100644 index bbb243c469e..00000000000 --- a/src/mesa/pipe/draw/draw_arrays.c +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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. - * - **************************************************************************/ - -/* Author: - * Brian Paul - * Keith Whitwell - */ - - -#include "pipe/p_defines.h" -#include "pipe/p_context.h" -#include "pipe/p_winsys.h" -#include "pipe/p_util.h" - -#include "pipe/draw/draw_private.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_prim.h" - - -/** - * Draw vertex arrays - * This is the main entrypoint into the drawing module. - * \param prim one of PIPE_PRIM_x - * \param start index of first vertex to draw - * \param count number of vertices to draw - */ -void -draw_arrays(struct draw_context *draw, unsigned prim, - unsigned start, unsigned count) -{ - /* tell drawing pipeline we're beginning drawing */ - draw->pipeline.first->begin( draw->pipeline.first ); - - /* XXX: Shouldn't really be needed - cache should be invalidated - * after setting new vertex buffers, vertex elements, but not - * between draws. - */ - draw_vertex_cache_invalidate( draw ); - - draw_set_prim( draw, prim ); - - /* drawing done here: */ - draw_prim(draw, start, count); - - /* draw any left-over buffered prims */ - draw_flush(draw); - - /* tell drawing pipeline we're done drawing */ - draw->pipeline.first->end( draw->pipeline.first ); -} - - diff --git a/src/mesa/pipe/draw/draw_clip.c b/src/mesa/pipe/draw/draw_clip.c index 3ccc408bc0b..a5051460479 100644 --- a/src/mesa/pipe/draw/draw_clip.c +++ b/src/mesa/pipe/draw/draw_clip.c @@ -248,8 +248,6 @@ do_clip_tri( struct draw_stage *stage, inlist[1] = header->v[1]; inlist[2] = header->v[2]; - clipmask &= ~CLIP_CULL_BIT; - while (clipmask && n >= 3) { const unsigned plane_idx = ffs(clipmask)-1; const float *plane = clipper->plane[plane_idx]; @@ -331,8 +329,6 @@ do_clip_line( struct draw_stage *stage, float t1 = 0.0F; struct prim_header newprim; - clipmask &= ~CLIP_CULL_BIT; - while (clipmask) { const unsigned plane_idx = ffs(clipmask)-1; const float *plane = clipper->plane[plane_idx]; diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c index 9acbc53742b..66c66ff698e 100644 --- a/src/mesa/pipe/draw/draw_context.c +++ b/src/mesa/pipe/draw/draw_context.c @@ -49,6 +49,8 @@ struct draw_context *draw_create( void ) draw->pipeline.flatshade = draw_flatshade_stage( draw ); draw->pipeline.cull = draw_cull_stage( draw ); draw->pipeline.feedback = draw_feedback_stage( draw ); + draw->pipeline.validate = draw_validate_stage( draw ); + draw->pipeline.first = draw->pipeline.validate; ASSIGN_4V( draw->plane[0], -1, 0, 0, 1 ); ASSIGN_4V( draw->plane[1], 1, 0, 0, 1 ); @@ -73,6 +75,8 @@ struct draw_context *draw_create( void ) draw->attrib_front1 = -1; draw->attrib_back1 = -1; + draw_vertex_cache_invalidate( draw ); + return draw; } @@ -84,75 +88,19 @@ void draw_destroy( struct draw_context *draw ) } -/** - * Rebuild the rendering pipeline. - */ -static void validate_pipeline( struct draw_context *draw ) -{ - struct draw_stage *next = draw->pipeline.rasterize; - - /* - * NOTE: we build up the pipeline in end-to-start order. - * - * TODO: make the current primitive part of the state and build - * shorter pipelines for lines & points. - */ - - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { - draw->pipeline.unfilled->next = next; - next = draw->pipeline.unfilled; - } - - if (draw->rasterizer->offset_cw || - draw->rasterizer->offset_ccw) { - draw->pipeline.offset->next = next; - next = draw->pipeline.offset; - } - - if (draw->rasterizer->light_twoside) { - draw->pipeline.twoside->next = next; - next = draw->pipeline.twoside; - } - - /* Always run the cull stage as we calculate determinant there - * also. Fix this.. - */ - { - draw->pipeline.cull->next = next; - next = draw->pipeline.cull; - } - - /* Clip stage - */ - { - draw->pipeline.clip->next = next; - next = draw->pipeline.clip; - } - - /* Do software flatshading prior to clipping. XXX: should only do - * this for clipped primitives, ie it is a part of the clip - * routine. - */ - if (draw->rasterizer->flatshade) { - draw->pipeline.flatshade->next = next; - next = draw->pipeline.flatshade; - } - - if (draw->feedback.enabled || draw->feedback.discard) { - draw->pipeline.feedback->next = next; - next = draw->pipeline.feedback; - } - draw->pipeline.first = next; +void draw_flush( struct draw_context *draw ) +{ + if (draw->drawing) + draw_do_flush( draw, DRAW_FLUSH_DRAW ); } void draw_set_feedback_state( struct draw_context *draw, const struct pipe_feedback_state *feedback ) { + draw_flush( draw ); draw->feedback = *feedback; - validate_pipeline( draw ); } @@ -163,8 +111,8 @@ void draw_set_feedback_state( struct draw_context *draw, void draw_set_rasterizer_state( struct draw_context *draw, const struct pipe_rasterizer_state *raster ) { + draw_flush( draw ); draw->rasterizer = raster; - validate_pipeline( draw ); } @@ -175,6 +123,7 @@ void draw_set_rasterizer_state( struct draw_context *draw, void draw_set_rasterize_stage( struct draw_context *draw, struct draw_stage *stage ) { + draw_flush( draw ); draw->pipeline.rasterize = stage; } @@ -185,6 +134,8 @@ void draw_set_rasterize_stage( struct draw_context *draw, void draw_set_clip_state( struct draw_context *draw, const struct pipe_clip_state *clip ) { + draw_flush( draw ); + assert(clip->nr <= PIPE_MAX_CLIP_PLANES); memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0])); draw->nr_planes = 6 + clip->nr; @@ -199,6 +150,7 @@ void draw_set_clip_state( struct draw_context *draw, void draw_set_viewport_state( struct draw_context *draw, const struct pipe_viewport_state *viewport ) { + draw_flush( draw ); draw->viewport = *viewport; /* struct copy */ } @@ -207,6 +159,7 @@ void draw_set_vertex_shader(struct draw_context *draw, const struct pipe_shader_state *shader) { + draw_flush( draw ); draw->vertex_shader = *shader; } @@ -216,6 +169,8 @@ draw_set_vertex_buffer(struct draw_context *draw, unsigned attr, const struct pipe_vertex_buffer *buffer) { + draw_flush( draw ); + assert(attr < PIPE_ATTRIB_MAX); draw->vertex_buffer[attr] = *buffer; } @@ -226,6 +181,8 @@ draw_set_vertex_element(struct draw_context *draw, unsigned attr, const struct pipe_vertex_element *element) { + draw_flush( draw ); + assert(attr < PIPE_ATTRIB_MAX); draw->vertex_element[attr] = *element; } @@ -238,6 +195,8 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer) { + draw_flush( draw ); + draw->mapped_vbuffer[attr] = buffer; } @@ -246,6 +205,8 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer) { + draw_flush( draw ); + draw->mapped_constants = buffer; } @@ -254,8 +215,41 @@ void draw_set_mapped_feedback_buffer(struct draw_context *draw, uint index, void *buffer, uint size) { + draw_flush( draw ); + assert(index < PIPE_MAX_FEEDBACK_ATTRIBS); draw->mapped_feedback_buffer[index] = buffer; draw->mapped_feedback_buffer_size[index] = size; /* in bytes */ } + + + + +/** + * Allocate space for temporary post-transform vertices, such as for clipping. + */ +void draw_alloc_tmps( struct draw_stage *stage, unsigned nr ) +{ + stage->nr_tmps = nr; + + if (nr) { + ubyte *store = (ubyte *) malloc(MAX_VERTEX_SIZE * nr); + unsigned i; + + stage->tmp = (struct vertex_header **) malloc(sizeof(struct vertex_header *) * nr); + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + } +} + +void draw_free_tmps( struct draw_stage *stage ) +{ + if (stage->tmp) { + free(stage->tmp[0]); + free(stage->tmp); + } +} + + diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h index 4eb59aab010..0ccf5f60466 100644 --- a/src/mesa/pipe/draw/draw_context.h +++ b/src/mesa/pipe/draw/draw_context.h @@ -57,7 +57,6 @@ struct draw_stage; #define CLIP_BOTTOM_BIT 0x08 #define CLIP_NEAR_BIT 0x10 #define CLIP_FAR_BIT 0x20 -#define CLIP_CULL_BIT (1 << (6 + PIPE_MAX_CLIP_PLANES)) /*unused? */ /*@}*/ /** @@ -92,10 +91,6 @@ void draw_set_rasterizer_state( struct draw_context *draw, void draw_set_rasterize_stage( struct draw_context *draw, struct draw_stage *stage ); -unsigned draw_prim_info( unsigned prim, unsigned *first, unsigned *incr ); - -unsigned draw_trim( unsigned count, unsigned first, unsigned incr ); - void draw_set_vertex_shader(struct draw_context *draw, @@ -125,9 +120,22 @@ void draw_set_mapped_feedback_buffer(struct draw_context *draw, uint index, void *buffer, uint size); -void -draw_arrays(struct draw_context *draw, unsigned prim, - unsigned start, unsigned count); + +/*********************************************************************** + * draw_prim.c + */ + +void draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count); + +void draw_flush(struct draw_context *draw); + +/*********************************************************************** + * draw_debug.c + */ +boolean draw_validate_prim( unsigned prim, unsigned length ); +unsigned draw_trim_prim( unsigned mode, unsigned count ); + #endif /* DRAW_CONTEXT_H */ diff --git a/src/mesa/pipe/draw/draw_debug.c b/src/mesa/pipe/draw/draw_debug.c new file mode 100644 index 00000000000..246e20fb305 --- /dev/null +++ b/src/mesa/pipe/draw/draw_debug.c @@ -0,0 +1,115 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw_private.h" +#include "draw_context.h" +#include "draw_prim.h" + + + +static void +draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) +{ + assert(prim >= PIPE_PRIM_POINTS); + assert(prim <= PIPE_PRIM_POLYGON); + + switch (prim) { + case PIPE_PRIM_POINTS: + *first = 1; + *incr = 1; + break; + case PIPE_PRIM_LINES: + *first = 2; + *incr = 2; + break; + case PIPE_PRIM_LINE_STRIP: + *first = 2; + *incr = 1; + break; + case PIPE_PRIM_LINE_LOOP: + *first = 2; + *incr = 1; + break; + case PIPE_PRIM_TRIANGLES: + *first = 3; + *incr = 3; + break; + case PIPE_PRIM_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + break; + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + *first = 3; + *incr = 1; + break; + case PIPE_PRIM_QUADS: + *first = 4; + *incr = 4; + break; + case PIPE_PRIM_QUAD_STRIP: + *first = 4; + *incr = 2; + break; + default: + assert(0); + *first = 1; + *incr = 1; + break; + } +} + + +unsigned +draw_trim_prim( unsigned mode, unsigned count ) +{ + unsigned length, first, incr; + + draw_prim_info( mode, &first, &incr ); + + if (count < first) + length = 0; + else + length = count - (count - first) % incr; + + return length; +} + + +boolean +draw_validate_prim( unsigned mode, unsigned count ) +{ + return (count > 0 && + count == draw_trim_prim( mode, count )); +} + diff --git a/src/mesa/pipe/draw/draw_feedback.c b/src/mesa/pipe/draw/draw_feedback.c index ee54db0ad5c..15fad4da807 100644 --- a/src/mesa/pipe/draw/draw_feedback.c +++ b/src/mesa/pipe/draw/draw_feedback.c @@ -69,6 +69,8 @@ static void feedback_vertex(struct draw_stage *stage, const struct vertex_header *vertex) { struct feedback_stage *fs = (struct feedback_stage *) stage; + +#if 0 const struct pipe_feedback_state *feedback = &stage->draw->feedback; const uint select = feedback->interleaved ? 0 : 1; uint i; diff --git a/src/mesa/pipe/draw/draw_prim.c b/src/mesa/pipe/draw/draw_prim.c index be2f987b9a0..a497a350f7d 100644 --- a/src/mesa/pipe/draw/draw_prim.c +++ b/src/mesa/pipe/draw/draw_prim.c @@ -58,14 +58,15 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { }; -void draw_flush( struct draw_context *draw ) +static void draw_prim_queue_flush( struct draw_context *draw ) { struct draw_stage *first = draw->pipeline.first; unsigned i; /* Make sure all vertices are available: */ - draw_vertex_cache_validate(draw); + if (draw->vs.queue_nr) + draw_vertex_shader_queue_flush(draw); switch (draw->reduced_prim) { case RP_TRI: @@ -91,12 +92,41 @@ void draw_flush( struct draw_context *draw ) break; } - draw->pq.queue_nr = 0; - + draw->pq.queue_nr = 0; draw_vertex_cache_unreference( draw ); } +void draw_do_flush( struct draw_context *draw, + unsigned flush ) +{ + if ((flush & (DRAW_FLUSH_PRIM_QUEUE | + DRAW_FLUSH_VERTEX_CACHE_INVALIDATE | + DRAW_FLUSH_DRAW)) && + draw->pq.queue_nr) + { + draw_prim_queue_flush(draw); + } + + if ((flush & (DRAW_FLUSH_VERTEX_CACHE_INVALIDATE | + DRAW_FLUSH_DRAW)) && + draw->drawing) + { + draw_vertex_cache_invalidate(draw); + } + + if ((flush & DRAW_FLUSH_DRAW) && + draw->drawing) + { + draw->pipeline.first->end( draw->pipeline.first ); + draw->drawing = 0; + draw->prim = ~0; + draw->pipeline.first = draw->pipeline.validate; + } + +} + + /* Return a pointer to a freshly queued primitive header. Ensure that * there is room in the vertex cache for a maximum of "nr_verts" new @@ -106,13 +136,13 @@ void draw_flush( struct draw_context *draw ) static struct prim_header *get_queued_prim( struct draw_context *draw, unsigned nr_verts ) { - if (draw->pq.queue_nr + 1 >= PRIM_QUEUE_LENGTH) { -// fprintf(stderr, "p"); - draw_flush( draw ); - } - else if (!draw_vertex_cache_check_space( draw, nr_verts )) { + if (!draw_vertex_cache_check_space( draw, nr_verts )) { // fprintf(stderr, "v"); - draw_flush( draw ); + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE_INVALIDATE ); + } + else if (draw->pq.queue_nr + 1 >= PRIM_QUEUE_LENGTH) { +// fprintf(stderr, "p"); + draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE ); } return &draw->pq.queue[draw->pq.queue_nr++]; @@ -129,7 +159,7 @@ static void do_point( struct draw_context *draw, prim->reset_line_stipple = 0; prim->edgeflags = 1; prim->pad = 0; - prim->v[0] = draw->get_vertex( draw, i0 ); + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); } @@ -143,8 +173,8 @@ static void do_line( struct draw_context *draw, prim->reset_line_stipple = reset_stipple; prim->edgeflags = 1; prim->pad = 0; - prim->v[0] = draw->get_vertex( draw, i0 ); - prim->v[1] = draw->get_vertex( draw, i1 ); + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); + prim->v[1] = draw->vcache.get_vertex( draw, i1 ); } static void do_triangle( struct draw_context *draw, @@ -157,9 +187,9 @@ static void do_triangle( struct draw_context *draw, prim->reset_line_stipple = 1; prim->edgeflags = ~0; prim->pad = 0; - prim->v[0] = draw->get_vertex( draw, i0 ); - prim->v[1] = draw->get_vertex( draw, i1 ); - prim->v[2] = draw->get_vertex( draw, i2 ); + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); + prim->v[1] = draw->vcache.get_vertex( draw, i1 ); + prim->v[2] = draw->vcache.get_vertex( draw, i2 ); } static void do_ef_triangle( struct draw_context *draw, @@ -170,9 +200,9 @@ static void do_ef_triangle( struct draw_context *draw, unsigned i2 ) { struct prim_header *prim = get_queued_prim( draw, 3 ); - struct vertex_header *v0 = draw->get_vertex( draw, i0 ); - struct vertex_header *v1 = draw->get_vertex( draw, i1 ); - struct vertex_header *v2 = draw->get_vertex( draw, i2 ); + struct vertex_header *v0 = draw->vcache.get_vertex( draw, i0 ); + struct vertex_header *v1 = draw->vcache.get_vertex( draw, i1 ); + struct vertex_header *v2 = draw->vcache.get_vertex( draw, i2 ); prim->reset_line_stipple = reset_stipple; @@ -202,7 +232,7 @@ static void do_quad( struct draw_context *draw, /** * Main entrypoint to draw some number of points/lines/triangles */ -void +static void draw_prim( struct draw_context *draw, unsigned start, unsigned count ) { unsigned i; @@ -341,14 +371,15 @@ draw_prim( struct draw_context *draw, unsigned start, unsigned count ) } -void +static void draw_set_prim( struct draw_context *draw, unsigned prim ) { + _mesa_printf("%s %d\n", __FUNCTION__, prim); assert(prim >= PIPE_PRIM_POINTS); assert(prim <= PIPE_PRIM_POLYGON); if (reduced_prim[prim] != draw->reduced_prim) { - draw_flush( draw ); + draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE ); draw->reduced_prim = reduced_prim[prim]; } @@ -356,91 +387,32 @@ draw_set_prim( struct draw_context *draw, unsigned prim ) } -unsigned -draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) -{ - assert(prim >= PIPE_PRIM_POINTS); - assert(prim <= PIPE_PRIM_POLYGON); - - switch (prim) { - case PIPE_PRIM_POINTS: - *first = 1; - *incr = 1; - return 0; - case PIPE_PRIM_LINES: - *first = 2; - *incr = 2; - return 0; - case PIPE_PRIM_LINE_STRIP: - *first = 2; - *incr = 1; - return 0; - case PIPE_PRIM_LINE_LOOP: - *first = 2; - *incr = 1; - return 1; - case PIPE_PRIM_TRIANGLES: - *first = 3; - *incr = 3; - return 0; - case PIPE_PRIM_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - return 0; - case PIPE_PRIM_TRIANGLE_FAN: - case PIPE_PRIM_POLYGON: - *first = 3; - *incr = 1; - return 1; - case PIPE_PRIM_QUADS: - *first = 4; - *incr = 4; - return 0; - case PIPE_PRIM_QUAD_STRIP: - *first = 4; - *incr = 2; - return 0; - default: - assert(0); - *first = 1; - *incr = 1; - return 0; - } -} - - -unsigned -draw_trim( unsigned count, unsigned first, unsigned incr ) -{ - if (count < first) - return 0; - else - return count - (count - first) % incr; -} /** - * Allocate space for temporary post-transform vertices, such as for clipping. + * Draw vertex arrays + * This is the main entrypoint into the drawing module. + * \param prim one of PIPE_PRIM_x + * \param start index of first vertex to draw + * \param count number of vertices to draw */ -void draw_alloc_tmps( struct draw_stage *stage, unsigned nr ) +void +draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count) { - stage->nr_tmps = nr; - - if (nr) { - ubyte *store = (ubyte *) malloc(MAX_VERTEX_SIZE * nr); - unsigned i; + if (!draw->drawing) { + draw->drawing = 1; - stage->tmp = (struct vertex_header **) malloc(sizeof(struct vertex_header *) * nr); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + /* tell drawing pipeline we're beginning drawing */ + draw->pipeline.first->begin( draw->pipeline.first ); } -} -void draw_free_tmps( struct draw_stage *stage ) -{ - if (stage->tmp) { - free(stage->tmp[0]); - free(stage->tmp); + if (draw->prim != prim) { + draw_set_prim( draw, prim ); } + + /* drawing done here: */ + draw_prim(draw, start, count); } + + diff --git a/src/mesa/pipe/draw/draw_prim.h b/src/mesa/pipe/draw/draw_prim.h index 4c55b029786..07cd3e2c9f7 100644 --- a/src/mesa/pipe/draw/draw_prim.h +++ b/src/mesa/pipe/draw/draw_prim.h @@ -6,11 +6,6 @@ void draw_invalidate_vcache( struct draw_context *draw ); -void draw_set_prim( struct draw_context *draw, unsigned prim ); - -void draw_prim( struct draw_context *draw, unsigned start, unsigned count ); - -void draw_flush( struct draw_context *draw ); #endif /* DRAW_PRIM_H */ diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index 04d38c4e0c2..ebef5347ab9 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -126,6 +126,8 @@ struct draw_context struct { struct draw_stage *first; /**< one of the following */ + struct draw_stage *validate; + /* stages (in logical order) */ struct draw_stage *feedback; struct draw_stage *flatshade; @@ -171,13 +173,10 @@ struct draw_context uint attrib_front0, attrib_back0; uint attrib_front1, attrib_back1; - unsigned nr_vertices; - + unsigned drawing; unsigned prim; /**< current prim type: PIPE_PRIM_x */ unsigned reduced_prim; - struct vertex_header *(*get_vertex)( struct draw_context *draw, - unsigned i ); /* Post-tnl vertex cache: */ @@ -186,6 +185,9 @@ struct draw_context unsigned idx[VCACHE_SIZE + VCACHE_OVERFLOW]; struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; unsigned overflow; + + struct vertex_header *(*get_vertex)( struct draw_context *draw, + unsigned i ); } vcache; /* Vertex shader queue: @@ -219,6 +221,7 @@ extern struct draw_stage *draw_offset_stage( struct draw_context *context ); extern struct draw_stage *draw_clip_stage( struct draw_context *context ); extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); extern struct draw_stage *draw_cull_stage( struct draw_context *context ); +extern struct draw_stage *draw_validate_stage( struct draw_context *context ); extern void draw_free_tmps( struct draw_stage *stage ); @@ -228,7 +231,6 @@ extern void draw_alloc_tmps( struct draw_stage *stage, unsigned nr ); extern int draw_vertex_cache_check_space( struct draw_context *draw, unsigned nr_verts ); -extern void draw_vertex_cache_validate( struct draw_context *draw ); extern void draw_vertex_cache_invalidate( struct draw_context *draw ); extern void draw_vertex_cache_unreference( struct draw_context *draw ); extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); @@ -244,6 +246,17 @@ extern void draw_vertex_fetch( struct draw_context *draw, unsigned count ); +#define DRAW_FLUSH_PRIM_QUEUE 0x1 +#define DRAW_FLUSH_VERTEX_CACHE_INVALIDATE 0x2 +#define DRAW_FLUSH_DRAW 0x4 + + +void draw_do_flush( struct draw_context *draw, + unsigned flags ); + + + + /** * Get a writeable copy of a vertex. * \param stage drawing stage info diff --git a/src/mesa/pipe/draw/draw_validate.c b/src/mesa/pipe/draw/draw_validate.c new file mode 100644 index 00000000000..7c5a9dcecad --- /dev/null +++ b/src/mesa/pipe/draw/draw_validate.c @@ -0,0 +1,124 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + + + + +/** + * Rebuild the rendering pipeline. + */ +static void validate_begin( struct draw_stage *stage ) +{ + struct draw_context *draw = stage->draw; + struct draw_stage *next = draw->pipeline.rasterize; + + /* + * NOTE: we build up the pipeline in end-to-start order. + * + * TODO: make the current primitive part of the state and build + * shorter pipelines for lines & points. + */ + + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { + draw->pipeline.unfilled->next = next; + next = draw->pipeline.unfilled; + } + + if (draw->rasterizer->offset_cw || + draw->rasterizer->offset_ccw) { + draw->pipeline.offset->next = next; + next = draw->pipeline.offset; + } + + if (draw->rasterizer->light_twoside) { + draw->pipeline.twoside->next = next; + next = draw->pipeline.twoside; + } + + /* Always run the cull stage as we calculate determinant there + * also. Fix this.. + */ + { + draw->pipeline.cull->next = next; + next = draw->pipeline.cull; + } + + /* Clip stage + */ + { + draw->pipeline.clip->next = next; + next = draw->pipeline.clip; + } + + /* Do software flatshading prior to clipping. XXX: should only do + * this for clipped primitives, ie it is a part of the clip + * routine. + */ + if (draw->rasterizer->flatshade) { + draw->pipeline.flatshade->next = next; + next = draw->pipeline.flatshade; + } + + if (draw->feedback.enabled || draw->feedback.discard) { + draw->pipeline.feedback->next = next; + next = draw->pipeline.feedback; + } + + draw->pipeline.first = next; + draw->pipeline.first->begin( draw->pipeline.first ); +} + + + + +/** + * Create validate pipeline stage. + */ +struct draw_stage *draw_validate_stage( struct draw_context *draw ) +{ + struct draw_stage *stage = CALLOC_STRUCT(draw_stage); + + stage->draw = draw; + stage->next = NULL; + stage->begin = validate_begin; + stage->point = NULL; + stage->line = NULL; + stage->tri = NULL; + stage->end = NULL; + stage->reset_stipple_counter = NULL; + + return stage; +} diff --git a/src/mesa/pipe/draw/draw_vertex_cache.c b/src/mesa/pipe/draw/draw_vertex_cache.c index a226798123c..1f4adededee 100644 --- a/src/mesa/pipe/draw/draw_vertex_cache.c +++ b/src/mesa/pipe/draw/draw_vertex_cache.c @@ -90,6 +90,9 @@ static struct vertex_header *get_vertex( struct draw_context *draw, draw->vcache.vertex[slot]->pad = 0; draw->vcache.vertex[slot]->vertex_id = ~0; } + else { +// fprintf(stderr, "*"); + } return draw->vcache.vertex[slot]; } @@ -127,10 +130,6 @@ void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) draw->vcache.vertex[i]->vertex_id = ~0; } -void draw_vertex_cache_validate( struct draw_context *draw ) -{ - draw_vertex_shader_queue_flush( draw ); -} void draw_vertex_cache_unreference( struct draw_context *draw ) { @@ -168,19 +167,21 @@ void draw_set_mapped_element_buffer( struct draw_context *draw, unsigned eltSize, void *elements ) { +// draw_statechange( draw ); + /* choose the get_vertex() function to use */ switch (eltSize) { case 0: - draw->get_vertex = get_vertex; + draw->vcache.get_vertex = get_vertex; break; case 1: - draw->get_vertex = get_ubyte_elt_vertex; + draw->vcache.get_vertex = get_ubyte_elt_vertex; break; case 2: - draw->get_vertex = get_ushort_elt_vertex; + draw->vcache.get_vertex = get_ushort_elt_vertex; break; case 4: - draw->get_vertex = get_uint_elt_vertex; + draw->vcache.get_vertex = get_uint_elt_vertex; break; default: assert(0); diff --git a/src/mesa/pipe/draw/draw_vertex_fetch.c b/src/mesa/pipe/draw/draw_vertex_fetch.c index 62e8d61be4c..2b839d641eb 100644 --- a/src/mesa/pipe/draw/draw_vertex_fetch.c +++ b/src/mesa/pipe/draw/draw_vertex_fetch.c @@ -99,6 +99,8 @@ void draw_vertex_fetch( struct draw_context *draw, /*printf(" %u: %f %f %f %f\n", attr, p[0], p[1], p[2], p[3]);*/ + /* Transform to AoS xxxx/yyyy/zzzz/wwww representation: + */ machine->Inputs[attr].xyzw[0].f[j] = p[0]; /*X*/ machine->Inputs[attr].xyzw[1].f[j] = p[1]; /*Y*/ machine->Inputs[attr].xyzw[2].f[j] = p[2]; /*Z*/ diff --git a/src/mesa/pipe/draw/draw_vertex_shader.c b/src/mesa/pipe/draw/draw_vertex_shader.c index fe4f124dd2f..b9e4cc13cca 100644 --- a/src/mesa/pipe/draw/draw_vertex_shader.c +++ b/src/mesa/pipe/draw/draw_vertex_shader.c @@ -169,13 +169,12 @@ run_vertex_program(struct draw_context *draw, vOut[j]->data[slot][1] = machine.Outputs[slot].xyzw[1].f[j]; vOut[j]->data[slot][2] = machine.Outputs[slot].xyzw[2].f[j]; vOut[j]->data[slot][3] = machine.Outputs[slot].xyzw[3].f[j]; - /* + printf("output %d: %f %f %f %f\n", slot, vOut[j]->data[slot][0], vOut[j]->data[slot][1], vOut[j]->data[slot][2], vOut[j]->data[slot][3]); - */ } } /* loop over vertices */ } @@ -189,7 +188,7 @@ void draw_vertex_shader_queue_flush( struct draw_context *draw ) { unsigned i, j; -// fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); + fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); /* run vertex shader on vertex cache entries, four per invokation */ for (i = 0; i < draw->vs.queue_nr; i += 4) { diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c index 7ea29a0a269..21c30b53f3a 100644 --- a/src/mesa/pipe/softpipe/sp_draw_arrays.c +++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c @@ -95,14 +95,16 @@ softpipe_draw_elements(struct pipe_context *pipe, { struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; - unsigned length, first, incr, i; + unsigned i; - /* first, check that the primitive is not malformed */ - draw_prim_info( mode, &first, &incr ); - length = draw_trim( count, first, incr ); - if (!length) - return TRUE; + /* first, check that the primitive is not malformed. It is the + * state tracker's responsibility to do send only correctly formed + * primitives down. + */ +// count = draw_trim_prim( mode, count ); + if (!draw_validate_prim( mode, count )) + assert(0); if (sp->dirty) softpipe_update_derived( sp ); @@ -151,6 +153,9 @@ softpipe_draw_elements(struct pipe_context *pipe, /* draw! */ draw_arrays(draw, mode, start, count); + /* always flush for now */ + draw_flush(draw); + /* * unmap vertex/index buffers */ diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index 2e27d00acfb..621a44512c4 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -41,7 +41,7 @@ #include "pipe/draw/draw_vertex.h" #include "pipe/p_util.h" -#define DEBUG_VERTS 0 +#define DEBUG_VERTS 1 /** * Triangle edge info diff --git a/src/mesa/sources b/src/mesa/sources index 985bd2dce6f..069be2e01db 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -157,15 +157,16 @@ VF_SOURCES = \ DRAW_SOURCES = \ - pipe/draw/draw_arrays.c \ pipe/draw/draw_clip.c \ pipe/draw/draw_context.c\ pipe/draw/draw_cull.c \ + pipe/draw/draw_debug.c \ pipe/draw/draw_feedback.c \ pipe/draw/draw_flatshade.c \ pipe/draw/draw_offset.c \ pipe/draw/draw_prim.c \ pipe/draw/draw_twoside.c \ + pipe/draw/draw_validate.c \ pipe/draw/draw_vertex.c \ pipe/draw/draw_vertex_cache.c \ pipe/draw/draw_vertex_fetch.c \ -- 2.30.2