mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-30 18:00:24 +01:00
gallium: rework provoking vertex code
Builds on commit ddb0e18f6c and fixes
regressions in glean clipFlat test.
We assume that Gallium drivers observe flatshade_first for all triangles
and that all the assorted per-triangle calls in the 'draw' module also
follow flatshade_first. Everything else builds on those rules.
Gallium does not use follow flatshade_first for GL quads, quad strips
and polygons; the "last" vertex is always the provoking vertex for those
prims. So now there are separate QUAD_FIRST_PV and QUAD_LAST_PV macros
in the draw primitive decomposition code instead of one QUAD macro.
This commit is contained in:
parent
a8bb495629
commit
cb136a93ab
7 changed files with 321 additions and 164 deletions
|
|
@ -170,7 +170,25 @@ static void do_triangle( struct draw_context *draw,
|
|||
* Set up macros for draw_pt_decompose.h template code.
|
||||
* This code uses vertex indexes / elements.
|
||||
*/
|
||||
#define QUAD(i0,i1,i2,i3) \
|
||||
|
||||
/* emit first quad vertex as first vertex in triangles */
|
||||
#define QUAD_FIRST_PV(i0,i1,i2,i3) \
|
||||
do_triangle( draw, \
|
||||
( DRAW_PIPE_RESET_STIPPLE | \
|
||||
DRAW_PIPE_EDGE_FLAG_0 | \
|
||||
DRAW_PIPE_EDGE_FLAG_1 ), \
|
||||
verts + stride * elts[i0], \
|
||||
verts + stride * elts[i1], \
|
||||
verts + stride * elts[i2]); \
|
||||
do_triangle( draw, \
|
||||
( DRAW_PIPE_EDGE_FLAG_1 | \
|
||||
DRAW_PIPE_EDGE_FLAG_2 ), \
|
||||
verts + stride * elts[i0], \
|
||||
verts + stride * elts[i2], \
|
||||
verts + stride * elts[i3])
|
||||
|
||||
/* emit last quad vertex as last vertex in triangles */
|
||||
#define QUAD_LAST_PV(i0,i1,i2,i3) \
|
||||
do_triangle( draw, \
|
||||
( DRAW_PIPE_RESET_STIPPLE | \
|
||||
DRAW_PIPE_EDGE_FLAG_0 | \
|
||||
|
|
@ -261,9 +279,27 @@ void draw_pipeline_run( struct draw_context *draw,
|
|||
|
||||
/*
|
||||
* Set up macros for draw_pt_decompose.h template code.
|
||||
* This code is for non-indexed rendering (no elts).
|
||||
* This code is for non-indexed (aka linear) rendering (no elts).
|
||||
*/
|
||||
#define QUAD(i0,i1,i2,i3) \
|
||||
|
||||
/* emit first quad vertex as first vertex in triangles */
|
||||
#define QUAD_FIRST_PV(i0,i1,i2,i3) \
|
||||
do_triangle( draw, \
|
||||
( DRAW_PIPE_RESET_STIPPLE | \
|
||||
DRAW_PIPE_EDGE_FLAG_0 | \
|
||||
DRAW_PIPE_EDGE_FLAG_1 ), \
|
||||
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
|
||||
verts + stride * (i1), \
|
||||
verts + stride * (i2)); \
|
||||
do_triangle( draw, \
|
||||
( DRAW_PIPE_EDGE_FLAG_1 | \
|
||||
DRAW_PIPE_EDGE_FLAG_2 ), \
|
||||
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
|
||||
verts + stride * (i2), \
|
||||
verts + stride * (i3))
|
||||
|
||||
/* emit last quad vertex as last vertex in triangles */
|
||||
#define QUAD_LAST_PV(i0,i1,i2,i3) \
|
||||
do_triangle( draw, \
|
||||
( DRAW_PIPE_RESET_STIPPLE | \
|
||||
DRAW_PIPE_EDGE_FLAG_0 | \
|
||||
|
|
|
|||
|
|
@ -164,10 +164,18 @@ static void emit_poly( struct draw_stage *stage,
|
|||
{
|
||||
struct prim_header header;
|
||||
unsigned i;
|
||||
ushort edge_first, edge_middle, edge_last;
|
||||
|
||||
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;
|
||||
if (stage->draw->rasterizer->flatshade_first) {
|
||||
edge_first = DRAW_PIPE_EDGE_FLAG_0;
|
||||
edge_middle = DRAW_PIPE_EDGE_FLAG_1;
|
||||
edge_last = DRAW_PIPE_EDGE_FLAG_2;
|
||||
}
|
||||
else {
|
||||
edge_first = DRAW_PIPE_EDGE_FLAG_2;
|
||||
edge_middle = DRAW_PIPE_EDGE_FLAG_0;
|
||||
edge_last = DRAW_PIPE_EDGE_FLAG_1;
|
||||
}
|
||||
|
||||
/* later stages may need the determinant, but only the sign matters */
|
||||
header.det = origPrim->det;
|
||||
|
|
@ -301,21 +309,21 @@ do_clip_tri( struct draw_stage *stage,
|
|||
|
||||
/* If flat-shading, copy color to new provoking vertex.
|
||||
*/
|
||||
if (stage->draw->rasterizer->flatshade_first) {
|
||||
if (clipper->flat && inlist[0] != header->v[0]) {
|
||||
inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
|
||||
|
||||
copy_colors(stage, inlist[0], header->v[0]);
|
||||
if (clipper->flat) {
|
||||
if (stage->draw->rasterizer->flatshade_first) {
|
||||
if (inlist[0] != header->v[0]) {
|
||||
inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
|
||||
copy_colors(stage, inlist[0], header->v[0]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (clipper->flat && inlist[0] != header->v[2]) {
|
||||
inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
|
||||
|
||||
copy_colors(stage, inlist[0], header->v[2]);
|
||||
else {
|
||||
if (inlist[0] != header->v[2]) {
|
||||
inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
|
||||
copy_colors(stage, inlist[0], header->v[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Emit the polygon as triangles to the setup stage:
|
||||
*/
|
||||
if (n >= 3)
|
||||
|
|
|
|||
|
|
@ -159,19 +159,8 @@ vbuf_tri( struct draw_stage *stage,
|
|||
|
||||
check_space( vbuf, 3 );
|
||||
|
||||
if (vbuf->stage.draw->rasterizer->flatshade_first) {
|
||||
/* Put provoking vertex in position expected by the driver.
|
||||
* Emit last provoking vertex in first pos.
|
||||
* Swap verts 0 & 1 to preserve polygon winding.
|
||||
*/
|
||||
vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[2] );
|
||||
vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] );
|
||||
vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[1] );
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < 3; i++) {
|
||||
vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ static void FUNC( ARGS,
|
|||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
if (flatfirst) {
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
/* Emit first triangle vertex as first triangle vertex */
|
||||
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
|
||||
(i + 0),
|
||||
(i + 1 + (i&1)),
|
||||
|
|
@ -65,6 +66,7 @@ static void FUNC( ARGS,
|
|||
}
|
||||
else {
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
/* Emit last triangle vertex as last triangle vertex */
|
||||
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
|
||||
(i + 0 + (i&1)),
|
||||
(i + 1 - (i&1)),
|
||||
|
|
@ -96,24 +98,52 @@ static void FUNC( ARGS,
|
|||
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = 0; i+3 < count; i += 4) {
|
||||
QUAD( (i + 0),
|
||||
(i + 1),
|
||||
(i + 2),
|
||||
(i + 3));
|
||||
/* GL quads don't follow provoking vertex convention */
|
||||
if (flatfirst) {
|
||||
for (i = 0; i+3 < count; i += 4) {
|
||||
/* emit last quad vertex as first triangle vertex */
|
||||
QUAD_FIRST_PV( (i + 3),
|
||||
(i + 0),
|
||||
(i + 1),
|
||||
(i + 2) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+3 < count; i += 4) {
|
||||
/* emit last quad vertex as last triangle vertex */
|
||||
QUAD_LAST_PV( (i + 0),
|
||||
(i + 1),
|
||||
(i + 2),
|
||||
(i + 3) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = 0; i+3 < count; i += 2) {
|
||||
QUAD( (i + 2),
|
||||
(i + 0),
|
||||
(i + 1),
|
||||
(i + 3));
|
||||
/* GL quad strips don't follow provoking vertex convention */
|
||||
if (flatfirst) {
|
||||
for (i = 0; i+3 < count; i += 2) {
|
||||
/* emit last quad vertex as first triangle vertex */
|
||||
QUAD_FIRST_PV( (i + 3),
|
||||
(i + 2),
|
||||
(i + 0),
|
||||
(i + 1) );
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i+3 < count; i += 2) {
|
||||
/* emit last quad vertex as last triangle vertex */
|
||||
QUAD_LAST_PV( (i + 2),
|
||||
(i + 0),
|
||||
(i + 1),
|
||||
(i + 3) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
/* GL polygons don't follow provoking vertex convention */
|
||||
{
|
||||
/* These bitflags look a little odd because we submit the
|
||||
* vertices as (1,2,0) to satisfy flatshade requirements.
|
||||
|
|
@ -129,10 +159,20 @@ static void FUNC( ARGS,
|
|||
if (i + 3 == count)
|
||||
flags |= edge_last;
|
||||
|
||||
TRIANGLE( flags,
|
||||
(i + 1),
|
||||
(i + 2),
|
||||
(0));
|
||||
if (flatfirst) {
|
||||
/* emit first polygon vertex as first triangle vertex */
|
||||
TRIANGLE( flags,
|
||||
(0),
|
||||
(i + 1),
|
||||
(i + 2) );
|
||||
}
|
||||
else {
|
||||
/* emit first polygon vertex as last triangle vertex */
|
||||
TRIANGLE( flags,
|
||||
(i + 1),
|
||||
(i + 2),
|
||||
(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -147,7 +187,8 @@ static void FUNC( ARGS,
|
|||
|
||||
|
||||
#undef TRIANGLE
|
||||
#undef QUAD
|
||||
#undef QUAD_FIRST_PV
|
||||
#undef QUAD_LAST_PV
|
||||
#undef POINT
|
||||
#undef LINE
|
||||
#undef FUNC
|
||||
|
|
|
|||
|
|
@ -199,12 +199,12 @@ vcache_ef_quad( struct vcache_frontend *vcache,
|
|||
( DRAW_PIPE_RESET_STIPPLE |
|
||||
DRAW_PIPE_EDGE_FLAG_0 |
|
||||
DRAW_PIPE_EDGE_FLAG_1 ),
|
||||
i0, i1, i2 );
|
||||
i3, i0, i1 );
|
||||
|
||||
vcache_triangle_flags( vcache,
|
||||
( DRAW_PIPE_EDGE_FLAG_2 |
|
||||
DRAW_PIPE_EDGE_FLAG_1 ),
|
||||
i0, i2, i3 );
|
||||
( DRAW_PIPE_EDGE_FLAG_1 |
|
||||
DRAW_PIPE_EDGE_FLAG_2 ),
|
||||
i3, i1, i2 );
|
||||
}
|
||||
else {
|
||||
vcache_triangle_flags( vcache,
|
||||
|
|
|
|||
|
|
@ -164,20 +164,21 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
|
|||
struct softpipe_context *softpipe = cvbr->softpipe;
|
||||
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
|
||||
const void *vertex_buffer = cvbr->vertex_buffer;
|
||||
struct setup_context *setup_ctx = cvbr->setup;
|
||||
struct setup_context *setup = cvbr->setup;
|
||||
const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
|
||||
unsigned i;
|
||||
|
||||
switch (cvbr->prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
for (i = 0; i < nr; i++) {
|
||||
sp_setup_point( setup_ctx,
|
||||
sp_setup_point( setup,
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINES:
|
||||
for (i = 1; i < nr; i += 2) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
|
|
@ -185,7 +186,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
|
|||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
|
|
@ -193,48 +194,41 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
|
|||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
if (nr) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, indices[nr-1], stride),
|
||||
get_vert(vertex_buffer, indices[0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
if (softpipe->rasterizer->flatshade_first) {
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
if (softpipe->rasterizer->flatshade_first) {
|
||||
if (flatshade_first) {
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit first triangle vertex as first triangle vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-(i&1)], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride) );
|
||||
get_vert(vertex_buffer, indices[i-(i&1)], stride) );
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit last triangle vertex as last triangle vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
|
|
@ -243,17 +237,19 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
|
|||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
if (softpipe->rasterizer->flatshade_first) {
|
||||
if (flatshade_first) {
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit first non-spoke vertex as first vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride) );
|
||||
get_vert(vertex_buffer, indices[0], stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit last non-spoke vertex as last vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
|
|
@ -262,43 +258,88 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
|
|||
break;
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
/* GL quads don't follow provoking vertex convention */
|
||||
if (flatshade_first) {
|
||||
/* emit last quad vertex as first triangle vertex */
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride) );
|
||||
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* emit last quad vertex as last triangle vertex */
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
/* GL quad strips don't follow provoking vertex convention */
|
||||
if (flatshade_first) {
|
||||
/* emit last quad vertex as first triangle vertex */
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride) );
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* emit last quad vertex as last triangle vertex */
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
/* Almost same as tri fan but the _first_ vertex specifies the flat
|
||||
* shading color. Note that the first polygon vertex is passed as
|
||||
* the last triangle vertex here.
|
||||
* flatshade_first state makes no difference.
|
||||
* shading color.
|
||||
*/
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[0], stride) );
|
||||
if (flatshade_first) {
|
||||
/* emit first polygon vertex as first triangle vertex */
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* emit first polygon vertex as last triangle vertex */
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -317,23 +358,24 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
|||
{
|
||||
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
|
||||
struct softpipe_context *softpipe = cvbr->softpipe;
|
||||
struct setup_context *setup_ctx = cvbr->setup;
|
||||
struct setup_context *setup = cvbr->setup;
|
||||
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
|
||||
const void *vertex_buffer =
|
||||
(void *) get_vert(cvbr->vertex_buffer, start, stride);
|
||||
const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
|
||||
unsigned i;
|
||||
|
||||
switch (cvbr->prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
for (i = 0; i < nr; i++) {
|
||||
sp_setup_point( setup_ctx,
|
||||
sp_setup_point( setup,
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINES:
|
||||
for (i = 1; i < nr; i += 2) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
|
|
@ -341,7 +383,7 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
|||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
|
|
@ -349,48 +391,40 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
|||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
if (nr) {
|
||||
sp_setup_line( setup_ctx,
|
||||
sp_setup_line( setup,
|
||||
get_vert(vertex_buffer, nr-1, stride),
|
||||
get_vert(vertex_buffer, 0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
if (softpipe->rasterizer->flatshade_first) {
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-2, stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
if (softpipe->rasterizer->flatshade_first) {
|
||||
if (flatshade_first) {
|
||||
for (i = 2; i < nr; i++) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit first triangle vertex as first triangle vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i+(i&1)-1, stride),
|
||||
get_vert(vertex_buffer, i-(i&1), stride),
|
||||
get_vert(vertex_buffer, i-2, stride) );
|
||||
get_vert(vertex_buffer, i-(i&1), stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < nr; i++) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit last triangle vertex as last triangle vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i+(i&1)-2, stride),
|
||||
get_vert(vertex_buffer, i-(i&1)-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
|
|
@ -399,17 +433,19 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
|||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
if (softpipe->rasterizer->flatshade_first) {
|
||||
if (flatshade_first) {
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit first non-spoke vertex as first vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, 0, stride),
|
||||
get_vert(vertex_buffer, i-1, stride) );
|
||||
get_vert(vertex_buffer, 0, stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
/* emit last non-spoke vertex as last vertex */
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, 0, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
|
|
@ -418,42 +454,86 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
|||
break;
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
/* GL quads don't follow provoking vertex convention */
|
||||
if (flatshade_first) {
|
||||
/* emit last quad vertex as first triangle vertex */
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride) );
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* emit last quad vertex as last triangle vertex */
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
/* GL quad strips don't follow provoking vertex convention */
|
||||
if (flatshade_first) {
|
||||
/* emit last quad vertex as first triangle vertex */
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride) );
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-3, stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* emit last quad vertex as last triangle vertex */
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
/* Almost same as tri fan but the _first_ vertex specifies the flat
|
||||
* shading color. Note that the first polygon vertex is passed as
|
||||
* the last triangle vertex here.
|
||||
* flatshade_first state makes no difference.
|
||||
* shading color.
|
||||
*/
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, 0, stride) );
|
||||
if (flatshade_first) {
|
||||
/* emit first polygon vertex as first triangle vertex */
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, 0, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* emit first polygon vertex as last triangle vertex */
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
sp_setup_tri( setup,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, 0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,10 @@ setup_sort_vertices(struct setup_context *setup,
|
|||
const float (*v1)[4],
|
||||
const float (*v2)[4])
|
||||
{
|
||||
setup->vprovoke = v2;
|
||||
if (setup->softpipe->rasterizer->flatshade_first)
|
||||
setup->vprovoke = v0;
|
||||
else
|
||||
setup->vprovoke = v2;
|
||||
|
||||
/* determine bottom to top order of vertices */
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue