Make flushing more lazy in the draw module.

This commit is contained in:
Keith Whitwell
2007-09-26 11:56:17 +01:00
parent 7770acf8d4
commit 08589f7105
16 changed files with 431 additions and 280 deletions

View File

@@ -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 );
}

View File

@@ -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];

View File

@@ -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 )
void draw_flush( 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;
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);
}
}

View File

@@ -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,
/***********************************************************************
* 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 */

View File

@@ -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 <keith@tungstengraphics.com>
*/
#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 ));
}

View File

@@ -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;

View File

@@ -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:
@@ -92,11 +93,40 @@ void draw_flush( struct draw_context *draw )
}
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 (!draw->drawing) {
draw->drawing = 1;
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);
/* tell drawing pipeline we're beginning drawing */
draw->pipeline.first->begin( draw->pipeline.first );
}
if (draw->prim != prim) {
draw_set_prim( draw, prim );
}
/* drawing done here: */
draw_prim(draw, start, count);
}
void draw_free_tmps( struct draw_stage *stage )
{
if (stage->tmp) {
free(stage->tmp[0]);
free(stage->tmp);
}
}

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 <keith@tungstengraphics.com>
*/
#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;
}

View File

@@ -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);

View File

@@ -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*/

View File

@@ -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) {

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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 \