draw: remove draw_vertex_cache.c
This commit is contained in:
parent
b11d89dc6d
commit
6689182642
|
@ -31,7 +31,6 @@ C_SOURCES = \
|
|||
draw_validate.c \
|
||||
draw_vbuf.c \
|
||||
draw_vertex.c \
|
||||
draw_vertex_cache.c \
|
||||
draw_vertex_fetch.c \
|
||||
draw_vertex_shader.c \
|
||||
draw_wide_line.c \
|
||||
|
|
|
@ -103,7 +103,6 @@ struct draw_context *draw_create( void )
|
|||
|
||||
draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */
|
||||
|
||||
draw_vertex_cache_invalidate( draw );
|
||||
draw_set_mapped_element_buffer( draw, 0, NULL );
|
||||
|
||||
tgsi_exec_machine_init(&draw->machine);
|
||||
|
@ -446,7 +445,6 @@ void draw_reset_vertex_ids(struct draw_context *draw)
|
|||
stage = stage->next;
|
||||
}
|
||||
|
||||
draw_vertex_cache_reset_vertex_ids(draw); /* going away soon */
|
||||
draw_pt_reset_vertex_ids(draw);
|
||||
}
|
||||
|
||||
|
@ -473,3 +471,21 @@ boolean draw_get_edgeflag( struct draw_context *draw,
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tell the drawing context about the index/element buffer to use
|
||||
* (ala glDrawElements)
|
||||
* If no element buffer is to be used (i.e. glDrawArrays) then this
|
||||
* should be called with eltSize=0 and elements=NULL.
|
||||
*
|
||||
* \param draw the drawing context
|
||||
* \param eltSize size of each element (1, 2 or 4 bytes)
|
||||
* \param elements the element buffer ptr
|
||||
*/
|
||||
void
|
||||
draw_set_mapped_element_buffer( struct draw_context *draw,
|
||||
unsigned eltSize, void *elements )
|
||||
{
|
||||
draw->user.elts = elements;
|
||||
draw->user.eltSize = eltSize;
|
||||
}
|
||||
|
|
|
@ -1,500 +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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "pipe/p_debug.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
#include "draw_private.h"
|
||||
#include "draw_context.h"
|
||||
|
||||
|
||||
|
||||
#define RP_NONE 0
|
||||
#define RP_POINT 1
|
||||
#define RP_LINE 2
|
||||
#define RP_TRI 3
|
||||
|
||||
|
||||
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
|
||||
RP_POINT,
|
||||
RP_LINE,
|
||||
RP_LINE,
|
||||
RP_LINE,
|
||||
RP_TRI,
|
||||
RP_TRI,
|
||||
RP_TRI,
|
||||
RP_TRI,
|
||||
RP_TRI,
|
||||
RP_TRI
|
||||
};
|
||||
|
||||
|
||||
static void draw_prim_queue_flush( struct draw_context *draw )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (0)
|
||||
debug_printf("Flushing with %d prims, %d verts\n",
|
||||
draw->pq.queue_nr, draw->vs.queue_nr);
|
||||
|
||||
assert (draw->pq.queue_nr != 0);
|
||||
|
||||
/* NOTE: we cannot save draw->pipeline->first in a local var because
|
||||
* draw->pipeline->first is often changed by the first call to tri(),
|
||||
* line(), etc.
|
||||
*/
|
||||
if (draw->rasterizer->line_stipple_enable) {
|
||||
switch (draw->reduced_prim) {
|
||||
case RP_TRI:
|
||||
for (i = 0; i < draw->pq.queue_nr; i++) {
|
||||
if (draw->pq.queue[i].reset_line_stipple)
|
||||
draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
|
||||
|
||||
draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] );
|
||||
}
|
||||
break;
|
||||
case RP_LINE:
|
||||
for (i = 0; i < draw->pq.queue_nr; i++) {
|
||||
if (draw->pq.queue[i].reset_line_stipple)
|
||||
draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
|
||||
|
||||
draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] );
|
||||
}
|
||||
break;
|
||||
case RP_POINT:
|
||||
draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
|
||||
for (i = 0; i < draw->pq.queue_nr; i++)
|
||||
draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (draw->reduced_prim) {
|
||||
case RP_TRI:
|
||||
for (i = 0; i < draw->pq.queue_nr; i++)
|
||||
draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] );
|
||||
break;
|
||||
case RP_LINE:
|
||||
for (i = 0; i < draw->pq.queue_nr; i++)
|
||||
draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] );
|
||||
break;
|
||||
case RP_POINT:
|
||||
for (i = 0; i < draw->pq.queue_nr; i++)
|
||||
draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
draw->pq.queue_nr = 0;
|
||||
draw->vs.post_nr = 0;
|
||||
draw_vertex_cache_unreference( draw );
|
||||
}
|
||||
|
||||
void draw_do_flush( struct draw_context *draw, unsigned flags )
|
||||
{
|
||||
if (0)
|
||||
debug_printf("Flushing with %d verts, %d prims\n",
|
||||
draw->vs.queue_nr,
|
||||
draw->pq.queue_nr );
|
||||
|
||||
if (draw->flushing)
|
||||
return;
|
||||
|
||||
draw->flushing = TRUE;
|
||||
|
||||
if (flags >= DRAW_FLUSH_SHADER_QUEUE) {
|
||||
if (draw->vs.queue_nr) {
|
||||
(*draw->shader_queue_flush)(draw);
|
||||
}
|
||||
|
||||
if (flags >= DRAW_FLUSH_PRIM_QUEUE) {
|
||||
if (draw->pq.queue_nr)
|
||||
draw_prim_queue_flush(draw);
|
||||
|
||||
if (flags >= DRAW_FLUSH_VERTEX_CACHE) {
|
||||
draw_vertex_cache_invalidate(draw);
|
||||
|
||||
if (flags >= DRAW_FLUSH_STATE_CHANGE) {
|
||||
draw->pipeline.first->flush( draw->pipeline.first, flags );
|
||||
draw->pipeline.first = draw->pipeline.validate;
|
||||
draw->reduced_prim = ~0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw->flushing = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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
|
||||
* vertices. Flush primitive and/or vertex queues if necessary to
|
||||
* make space.
|
||||
*/
|
||||
static struct prim_header *get_queued_prim( struct draw_context *draw,
|
||||
unsigned nr_verts )
|
||||
{
|
||||
if (!draw_vertex_cache_check_space( draw, nr_verts )) {
|
||||
// debug_printf("v");
|
||||
draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE );
|
||||
}
|
||||
else if (draw->pq.queue_nr == PRIM_QUEUE_LENGTH) {
|
||||
// debug_printf("p");
|
||||
draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE );
|
||||
}
|
||||
|
||||
assert(draw->pq.queue_nr < PRIM_QUEUE_LENGTH);
|
||||
|
||||
return &draw->pq.queue[draw->pq.queue_nr++];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a point to the primitive queue.
|
||||
* \param i0 index into user's vertex arrays
|
||||
*/
|
||||
static void do_point( struct draw_context *draw,
|
||||
unsigned i0 )
|
||||
{
|
||||
struct prim_header *prim = get_queued_prim( draw, 1 );
|
||||
|
||||
prim->reset_line_stipple = 0;
|
||||
prim->edgeflags = 1;
|
||||
prim->pad = 0;
|
||||
prim->v[0] = draw->vcache.get_vertex( draw, i0 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a line to the primitive queue.
|
||||
* \param i0 index into user's vertex arrays
|
||||
* \param i1 index into user's vertex arrays
|
||||
*/
|
||||
static void do_line( struct draw_context *draw,
|
||||
boolean reset_stipple,
|
||||
unsigned i0,
|
||||
unsigned i1 )
|
||||
{
|
||||
struct prim_header *prim = get_queued_prim( draw, 2 );
|
||||
|
||||
prim->reset_line_stipple = reset_stipple;
|
||||
prim->edgeflags = 1;
|
||||
prim->pad = 0;
|
||||
prim->v[0] = draw->vcache.get_vertex( draw, i0 );
|
||||
prim->v[1] = draw->vcache.get_vertex( draw, i1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a triangle to the primitive queue.
|
||||
*/
|
||||
static void do_triangle( struct draw_context *draw,
|
||||
unsigned i0,
|
||||
unsigned i1,
|
||||
unsigned i2 )
|
||||
{
|
||||
struct prim_header *prim = get_queued_prim( draw, 3 );
|
||||
|
||||
// _mesa_printf("tri %d %d %d\n", i0, i1, i2);
|
||||
prim->reset_line_stipple = 1;
|
||||
prim->edgeflags = ~0;
|
||||
prim->pad = 0;
|
||||
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,
|
||||
boolean reset_stipple,
|
||||
unsigned ef_mask,
|
||||
unsigned i0,
|
||||
unsigned i1,
|
||||
unsigned i2 )
|
||||
{
|
||||
struct prim_header *prim = get_queued_prim( draw, 3 );
|
||||
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;
|
||||
|
||||
prim->edgeflags = ef_mask & ((v0->edgeflag << 0) |
|
||||
(v1->edgeflag << 1) |
|
||||
(v2->edgeflag << 2));
|
||||
prim->pad = 0;
|
||||
prim->v[0] = v0;
|
||||
prim->v[1] = v1;
|
||||
prim->v[2] = v2;
|
||||
}
|
||||
|
||||
|
||||
static void do_ef_quad( struct draw_context *draw,
|
||||
unsigned v0,
|
||||
unsigned v1,
|
||||
unsigned v2,
|
||||
unsigned v3 )
|
||||
{
|
||||
const unsigned omitEdge2 = ~(1 << 1);
|
||||
const unsigned omitEdge3 = ~(1 << 2);
|
||||
do_ef_triangle( draw, 1, omitEdge2, v0, v1, v3 );
|
||||
do_ef_triangle( draw, 0, omitEdge3, v1, v2, v3 );
|
||||
}
|
||||
|
||||
static void do_quad( struct draw_context *draw,
|
||||
unsigned v0,
|
||||
unsigned v1,
|
||||
unsigned v2,
|
||||
unsigned v3 )
|
||||
{
|
||||
do_triangle( draw, v0, v1, v3 );
|
||||
do_triangle( draw, v1, v2, v3 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main entrypoint to draw some number of points/lines/triangles
|
||||
*/
|
||||
static void
|
||||
draw_prim( struct draw_context *draw,
|
||||
unsigned prim, unsigned start, unsigned count )
|
||||
{
|
||||
unsigned i;
|
||||
boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
|
||||
draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL);
|
||||
boolean flatfirst =
|
||||
(draw->rasterizer->flatshade & draw->rasterizer->flatshade_first) ? TRUE : FALSE;
|
||||
|
||||
// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
|
||||
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
for (i = 0; i < count; i ++) {
|
||||
do_point( draw,
|
||||
start + i );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINES:
|
||||
for (i = 0; i+1 < count; i += 2) {
|
||||
do_line( draw,
|
||||
TRUE,
|
||||
start + i + 0,
|
||||
start + i + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (count >= 2) {
|
||||
for (i = 1; i < count; i++) {
|
||||
do_line( draw,
|
||||
i == 1, /* XXX: only if vb not split */
|
||||
start + i - 1,
|
||||
start + i );
|
||||
}
|
||||
|
||||
do_line( draw,
|
||||
0,
|
||||
start + count - 1,
|
||||
start + 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
for (i = 1; i < count; i++) {
|
||||
do_line( draw,
|
||||
i == 1,
|
||||
start + i - 1,
|
||||
start + i );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
if (unfilled) {
|
||||
for (i = 0; i+2 < count; i += 3) {
|
||||
do_ef_triangle( draw,
|
||||
1,
|
||||
~0,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 2 );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+2 < count; i += 3) {
|
||||
do_triangle( draw,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 2 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
if (flatfirst) {
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
if (i & 1) {
|
||||
do_triangle( draw,
|
||||
start + i + 0,
|
||||
start + i + 2,
|
||||
start + i + 1 );
|
||||
}
|
||||
else {
|
||||
do_triangle( draw,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
if (i & 1) {
|
||||
do_triangle( draw,
|
||||
start + i + 1,
|
||||
start + i + 0,
|
||||
start + i + 2 );
|
||||
}
|
||||
else {
|
||||
do_triangle( draw,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
if (count >= 3) {
|
||||
if (flatfirst) {
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
do_triangle( draw,
|
||||
start + i + 1,
|
||||
start + i + 2,
|
||||
start + 0 );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
do_triangle( draw,
|
||||
start + 0,
|
||||
start + i + 1,
|
||||
start + i + 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
if (unfilled) {
|
||||
for (i = 0; i+3 < count; i += 4) {
|
||||
do_ef_quad( draw,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 2,
|
||||
start + i + 3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+3 < count; i += 4) {
|
||||
do_quad( draw,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 2,
|
||||
start + i + 3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
if (unfilled) {
|
||||
for (i = 0; i+3 < count; i += 2) {
|
||||
do_ef_quad( draw,
|
||||
start + i + 2,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+3 < count; i += 2) {
|
||||
do_quad( draw,
|
||||
start + i + 2,
|
||||
start + i + 0,
|
||||
start + i + 1,
|
||||
start + i + 3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
if (unfilled) {
|
||||
unsigned ef_mask = (1<<2) | (1<<0);
|
||||
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
|
||||
if (i + 3 >= count)
|
||||
ef_mask |= (1<<1);
|
||||
|
||||
do_ef_triangle( draw,
|
||||
i == 0,
|
||||
ef_mask,
|
||||
start + i + 1,
|
||||
start + i + 2,
|
||||
start + 0);
|
||||
|
||||
ef_mask &= ~(1<<2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
do_triangle( draw,
|
||||
start + i + 1,
|
||||
start + i + 2,
|
||||
start + 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,219 +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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "draw_private.h"
|
||||
#include "draw_context.h"
|
||||
|
||||
|
||||
void draw_vertex_cache_invalidate( struct draw_context *draw )
|
||||
{
|
||||
assert(draw->pq.queue_nr == 0);
|
||||
assert(draw->vs.queue_nr == 0);
|
||||
assert(draw->vcache.referenced == 0);
|
||||
|
||||
/* There's an error somewhere in the vcache code that requires this
|
||||
* memset. The bug is exposed in q3demo demo001, but probably
|
||||
* elsewhere as well. Will track it down later.
|
||||
*/
|
||||
memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if vertex is in cache, otherwise add it. It won't go through
|
||||
* VS yet, not until there is a flush operation or the VS queue fills up.
|
||||
*
|
||||
* Note that cache entries are basically just two pointers: the first
|
||||
* an index into the user's vertex arrays, the second a location in
|
||||
* the vertex shader cache for the post-transformed vertex.
|
||||
*
|
||||
* \return pointer to location of (post-transformed) vertex header in the cache
|
||||
*/
|
||||
static struct vertex_header *get_vertex( struct draw_context *draw,
|
||||
unsigned i )
|
||||
{
|
||||
unsigned slot = (i + (i>>5)) % VCACHE_SIZE;
|
||||
|
||||
assert(slot < 32); /* so we don't exceed the bitfield size below */
|
||||
|
||||
if (draw->vcache.referenced & (1<<slot))
|
||||
{
|
||||
/* Cache hit?
|
||||
*/
|
||||
if (draw->vcache.idx[slot].in == i) {
|
||||
/*debug_printf("HIT %d %d\n", slot, i);*/
|
||||
assert(draw->vcache.idx[slot].out < draw->vs.queue_nr);
|
||||
return draw_header_from_block(draw->vs.vertex_cache,
|
||||
MAX_VERTEX_ALLOCATION,
|
||||
draw->vcache.idx[slot].out);
|
||||
}
|
||||
|
||||
/* Otherwise a collision
|
||||
*/
|
||||
slot = VCACHE_SIZE + draw->vcache.overflow++;
|
||||
/*debug_printf("XXX %d --> %d\n", i, slot);*/
|
||||
}
|
||||
|
||||
/* Deal with the cache miss:
|
||||
*/
|
||||
{
|
||||
unsigned out;
|
||||
struct vertex_header *header;
|
||||
|
||||
assert(slot < Elements(draw->vcache.idx));
|
||||
|
||||
/*debug_printf("NEW %d %d\n", slot, i);*/
|
||||
draw->vcache.idx[slot].in = i;
|
||||
draw->vcache.idx[slot].out = out = draw->vs.queue_nr++;
|
||||
draw->vcache.referenced |= (1 << slot);
|
||||
|
||||
|
||||
/* Add to vertex shader queue:
|
||||
*/
|
||||
assert(draw->vs.queue_nr < VS_QUEUE_LENGTH);
|
||||
|
||||
header = draw_header_from_block(draw->vs.vertex_cache, MAX_VERTEX_ALLOCATION,
|
||||
out);
|
||||
draw->vs.elts[out] = i;
|
||||
header->clipmask = 0;
|
||||
header->edgeflag = draw_get_edgeflag(draw, i);
|
||||
header->pad = 0;
|
||||
header->vertex_id = UNDEFINED_VERTEX_ID;
|
||||
|
||||
/* Need to set the vertex's edge flag here. If we're being called
|
||||
* by do_ef_triangle(), that function needs edge flag info!
|
||||
*/
|
||||
|
||||
return draw_header_from_block(draw->vs.vertex_cache,
|
||||
MAX_VERTEX_ALLOCATION,
|
||||
draw->vcache.idx[slot].out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw,
|
||||
unsigned i )
|
||||
{
|
||||
const unsigned *elts = (const unsigned *) draw->user.elts;
|
||||
return get_vertex( draw, elts[i] );
|
||||
}
|
||||
|
||||
|
||||
static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw,
|
||||
unsigned i )
|
||||
{
|
||||
const ushort *elts = (const ushort *) draw->user.elts;
|
||||
return get_vertex( draw, elts[i] );
|
||||
}
|
||||
|
||||
|
||||
static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw,
|
||||
unsigned i )
|
||||
{
|
||||
const ubyte *elts = (const ubyte *) draw->user.elts;
|
||||
return get_vertex( draw, elts[i] );
|
||||
}
|
||||
|
||||
|
||||
void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < draw->vs.post_nr; i++) {
|
||||
struct vertex_header * header =
|
||||
draw_header_from_block(draw->vs.vertex_cache,
|
||||
MAX_VERTEX_ALLOCATION, i);
|
||||
header->vertex_id = UNDEFINED_VERTEX_ID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw_vertex_cache_unreference( struct draw_context *draw )
|
||||
{
|
||||
draw->vcache.referenced = 0;
|
||||
draw->vcache.overflow = 0;
|
||||
}
|
||||
|
||||
|
||||
int draw_vertex_cache_check_space( struct draw_context *draw,
|
||||
unsigned nr_verts )
|
||||
{
|
||||
if (draw->vcache.overflow + nr_verts < VCACHE_OVERFLOW) {
|
||||
/* The vs queue is sized so that this can never happen:
|
||||
*/
|
||||
assert(draw->vs.queue_nr + nr_verts < VS_QUEUE_LENGTH);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tell the drawing context about the index/element buffer to use
|
||||
* (ala glDrawElements)
|
||||
* If no element buffer is to be used (i.e. glDrawArrays) then this
|
||||
* should be called with eltSize=0 and elements=NULL.
|
||||
*
|
||||
* \param draw the drawing context
|
||||
* \param eltSize size of each element (1, 2 or 4 bytes)
|
||||
* \param elements the element buffer ptr
|
||||
*/
|
||||
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->vcache.get_vertex = get_vertex;
|
||||
break;
|
||||
case 1:
|
||||
draw->vcache.get_vertex = get_ubyte_elt_vertex;
|
||||
break;
|
||||
case 2:
|
||||
draw->vcache.get_vertex = get_ushort_elt_vertex;
|
||||
break;
|
||||
case 4:
|
||||
draw->vcache.get_vertex = get_uint_elt_vertex;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
draw->user.elts = elements;
|
||||
draw->user.eltSize = eltSize;
|
||||
}
|
||||
|
Loading…
Reference in New Issue