draw: no need to rearrange most primitives in vcache for flatshade-first

The driver/pipeline will still be applying flatshade-first state to the
triangles emitted from vcache, so there's no need to rotate the vertices
of most primitives.  The only exception is POLYGON, as explained in the
code.
This commit is contained in:
Keith Whitwell 2008-06-10 14:46:25 +01:00
parent 14a13e3767
commit ad44e68706
2 changed files with 72 additions and 56 deletions

View File

@ -114,7 +114,10 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
fetch->translate = translate_cache_find(fetch->cache, &key);
{
static struct vertex_header vh = { 0, 1, 0, 0xffff };
static struct vertex_header vh = { 0,
1, /* edgeflag */
0,
0xffff };
fetch->translate->set_buffer(fetch->translate,
draw->pt.nr_vertex_buffers,
&vh,

View File

@ -7,15 +7,18 @@ static void FUNC( struct draw_pt_front_end *frontend,
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
struct draw_context *draw = vcache->draw;
boolean flatfirst = (draw->rasterizer->flatshade &&
draw->rasterizer->flatshade_first);
unsigned i;
ushort flags;
if (0) debug_printf("%s %d\n", __FUNCTION__, count);
/* Note that no adjustment is made here for flatshade provoking
* vertex. This was previously the case, but was incorrect as the
* same logic would be applied twice both here & in the pipeline
* code or driver. The rule is now that we just preserve the
* original order in this code, and leave identification of the PV
* to the pipeline and driver.
*/
switch (vcache->input_prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
@ -72,45 +75,23 @@ static void FUNC( struct draw_pt_front_end *frontend,
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 0),
get_elt(elts, i + 1 + (i&1)),
get_elt(elts, i + 2 - (i&1)));
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 0 + (i&1)),
get_elt(elts, i + 1 - (i&1)),
get_elt(elts, i + 2 ));
}
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 0 + (i&1)),
get_elt(elts, i + 1 - (i&1)),
get_elt(elts, i + 2 ));
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 1),
get_elt(elts, i + 2),
get_elt(elts, 0 ));
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, 0),
get_elt(elts, i + 1),
get_elt(elts, i + 2 ));
}
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 1),
get_elt(elts, i + 2),
get_elt(elts, 0 ));
}
}
break;
@ -138,26 +119,58 @@ static void FUNC( struct draw_pt_front_end *frontend,
case PIPE_PRIM_POLYGON:
{
boolean flatfirst = (draw->rasterizer->flatshade &&
draw->rasterizer->flatshade_first);
/* These bitflags look a little odd because we submit the
* vertices as (1,2,0) to satisfy flatshade requirements.
*
* Polygon is defined has having vertex 0 be the provoking
* flatshade vertex and all known API's match this usage.
* However, the PV's for the triangles we emit from this
* decomposition vary according to the API, and hence we have
* to choose between two ways of emitting the triangles.
*/
const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2;
const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0;
const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1;
flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
for (i = 0; i+2 < count; i++, flags = edge_middle) {
if (i + 3 == count)
flags |= edge_last;
TRIANGLE( vcache,
flags,
get_elt(elts, i + 1),
get_elt(elts, i + 2),
get_elt(elts, 0));
}
if (flatfirst) {
const ushort edge_first = DRAW_PIPE_EDGE_FLAG_0;
const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_1;
const ushort edge_last = DRAW_PIPE_EDGE_FLAG_2;
flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
for (i = 0; i+2 < count; i++, flags = edge_middle) {
if (i + 3 == count)
flags |= edge_last;
/* PV is first vertex */
TRIANGLE( vcache,
flags,
get_elt(elts, 0),
get_elt(elts, i + 1),
get_elt(elts, i + 2));
}
}
else {
const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2;
const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0;
const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1;
flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
for (i = 0; i+2 < count; i++, flags = edge_middle) {
if (i + 3 == count)
flags |= edge_last;
/* PV is third vertex */
TRIANGLE( vcache,
flags,
get_elt(elts, i + 1),
get_elt(elts, i + 2),
get_elt(elts, 0));
}
}
}
break;