Make flushing more lazy in the draw module.
This commit is contained in:
@@ -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 );
|
||||
}
|
||||
|
||||
|
@@ -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];
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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 */
|
||||
|
115
src/mesa/pipe/draw/draw_debug.c
Normal file
115
src/mesa/pipe/draw/draw_debug.c
Normal 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 ));
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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
|
||||
|
124
src/mesa/pipe/draw/draw_validate.c
Normal file
124
src/mesa/pipe/draw/draw_validate.c
Normal 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;
|
||||
}
|
@@ -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);
|
||||
|
@@ -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*/
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
*/
|
||||
|
@@ -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
|
||||
|
@@ -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 \
|
||||
|
Reference in New Issue
Block a user