mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 09:48:07 +02:00
draw: streamline the varray path
- drop support for running the pipeline (ie. don't populate the flags values) - pass through all split-able primitives intact to the middle end - only primitives that can't be split are shunted on the draw-element path
This commit is contained in:
parent
f116a14916
commit
44463b2997
3 changed files with 45 additions and 230 deletions
|
|
@ -81,7 +81,7 @@ draw_pt_arrays(struct draw_context *draw,
|
|||
|
||||
/* Pick the right frontend
|
||||
*/
|
||||
if (draw->pt.user.elts) {
|
||||
if (draw->pt.user.elts || (opt & PT_PIPELINE)) {
|
||||
frontend = draw->pt.front.vcache;
|
||||
} else if (opt == PT_SHADE && draw->pt.test_fse) {
|
||||
/* should be a middle end.. */
|
||||
|
|
|
|||
|
|
@ -154,9 +154,9 @@ static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr
|
|||
|
||||
|
||||
static INLINE void add_draw_el(struct varray_frontend *varray,
|
||||
int idx, ushort flags)
|
||||
int idx)
|
||||
{
|
||||
varray->draw_elts[varray->draw_count++] = idx | flags;
|
||||
varray->draw_elts[varray->draw_count++] = idx;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -165,106 +165,47 @@ static INLINE void varray_triangle( struct varray_frontend *varray,
|
|||
unsigned i1,
|
||||
unsigned i2 )
|
||||
{
|
||||
add_draw_el(varray, i0, 0);
|
||||
add_draw_el(varray, i1, 0);
|
||||
add_draw_el(varray, i2, 0);
|
||||
}
|
||||
|
||||
static INLINE void varray_triangle_flags( struct varray_frontend *varray,
|
||||
ushort flags,
|
||||
unsigned i0,
|
||||
unsigned i1,
|
||||
unsigned i2 )
|
||||
{
|
||||
add_draw_el(varray, i0, flags);
|
||||
add_draw_el(varray, i1, 0);
|
||||
add_draw_el(varray, i2, 0);
|
||||
add_draw_el(varray, i0);
|
||||
add_draw_el(varray, i1);
|
||||
add_draw_el(varray, i2);
|
||||
}
|
||||
|
||||
static INLINE void varray_line( struct varray_frontend *varray,
|
||||
unsigned i0,
|
||||
unsigned i1 )
|
||||
{
|
||||
add_draw_el(varray, i0, 0);
|
||||
add_draw_el(varray, i1, 0);
|
||||
}
|
||||
|
||||
|
||||
static INLINE void varray_line_flags( struct varray_frontend *varray,
|
||||
ushort flags,
|
||||
unsigned i0,
|
||||
unsigned i1 )
|
||||
{
|
||||
add_draw_el(varray, i0, flags);
|
||||
add_draw_el(varray, i1, 0);
|
||||
add_draw_el(varray, i0);
|
||||
add_draw_el(varray, i1);
|
||||
}
|
||||
|
||||
|
||||
static INLINE void varray_point( struct varray_frontend *varray,
|
||||
unsigned i0 )
|
||||
{
|
||||
add_draw_el(varray, i0, 0);
|
||||
add_draw_el(varray, i0);
|
||||
}
|
||||
|
||||
static INLINE void varray_quad( struct varray_frontend *varray,
|
||||
unsigned i0,
|
||||
unsigned i1,
|
||||
unsigned i2,
|
||||
unsigned i3 )
|
||||
{
|
||||
varray_triangle( varray, i0, i1, i3 );
|
||||
varray_triangle( varray, i1, i2, i3 );
|
||||
}
|
||||
|
||||
static INLINE void varray_ef_quad( struct varray_frontend *varray,
|
||||
unsigned i0,
|
||||
unsigned i1,
|
||||
unsigned i2,
|
||||
unsigned i3 )
|
||||
{
|
||||
const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2;
|
||||
const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1;
|
||||
|
||||
varray_triangle_flags( varray,
|
||||
DRAW_PIPE_RESET_STIPPLE | omitEdge1,
|
||||
i0, i1, i3 );
|
||||
|
||||
varray_triangle_flags( varray,
|
||||
omitEdge2,
|
||||
i1, i2, i3 );
|
||||
}
|
||||
|
||||
/* At least for now, we're back to using a template include file for
|
||||
* this. The two paths aren't too different though - it may be
|
||||
* possible to reunify them.
|
||||
*/
|
||||
#define TRIANGLE(vc,flags,i0,i1,i2) varray_triangle_flags(vc,flags,i0,i1,i2)
|
||||
#define QUAD(vc,i0,i1,i2,i3) varray_ef_quad(vc,i0,i1,i2,i3)
|
||||
#define LINE(vc,flags,i0,i1) varray_line_flags(vc,flags,i0,i1)
|
||||
#define POINT(vc,i0) varray_point(vc,i0)
|
||||
#define FUNC varray_run_extras
|
||||
#include "draw_pt_varray_tmp.h"
|
||||
|
||||
#define TRIANGLE(vc,flags,i0,i1,i2) varray_triangle(vc,i0,i1,i2)
|
||||
#define QUAD(vc,i0,i1,i2,i3) varray_quad(vc,i0,i1,i2,i3)
|
||||
#define LINE(vc,flags,i0,i1) varray_line(vc,i0,i1)
|
||||
#define TRIANGLE(vc,i0,i1,i2) varray_triangle(vc,i0,i1,i2)
|
||||
#define LINE(vc,i0,i1) varray_line(vc,i0,i1)
|
||||
#define POINT(vc,i0) varray_point(vc,i0)
|
||||
#define FUNC varray_run
|
||||
#include "draw_pt_varray_tmp_linear.h"
|
||||
|
||||
|
||||
|
||||
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
|
||||
static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
|
||||
PIPE_PRIM_POINTS,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINE_STRIP,
|
||||
PIPE_PRIM_LINES, /* decomposed */
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES
|
||||
PIPE_PRIM_TRIANGLE_STRIP,
|
||||
PIPE_PRIM_TRIANGLES, /* decomposed */
|
||||
PIPE_PRIM_QUADS,
|
||||
PIPE_PRIM_QUAD_STRIP,
|
||||
PIPE_PRIM_TRIANGLES /* decomposed */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -276,17 +217,10 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
|
|||
{
|
||||
struct varray_frontend *varray = (struct varray_frontend *)frontend;
|
||||
|
||||
if (opt & PT_PIPELINE)
|
||||
{
|
||||
varray->base.run = varray_run_extras;
|
||||
}
|
||||
else
|
||||
{
|
||||
varray->base.run = varray_run;
|
||||
}
|
||||
varray->base.run = varray_run;
|
||||
|
||||
varray->input_prim = prim;
|
||||
varray->output_prim = reduced_prim[prim];
|
||||
varray->output_prim = decompose_prim[prim];
|
||||
|
||||
varray->middle = middle;
|
||||
middle->prepare(middle, varray->output_prim, opt);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
static unsigned trim( unsigned count, unsigned first, unsigned incr )
|
||||
{
|
||||
return count - (count - first) % incr;
|
||||
}
|
||||
|
||||
static void FUNC(struct draw_pt_front_end *frontend,
|
||||
pt_elt_func get_elt,
|
||||
|
|
@ -5,12 +9,9 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
unsigned count)
|
||||
{
|
||||
struct varray_frontend *varray = (struct varray_frontend *)frontend;
|
||||
struct draw_context *draw = varray->draw;
|
||||
unsigned start = (unsigned)elts;
|
||||
|
||||
boolean flatfirst = (draw->rasterizer->flatshade &&
|
||||
draw->rasterizer->flatshade_first);
|
||||
unsigned i, j, flags;
|
||||
unsigned i, j;
|
||||
unsigned first, incr;
|
||||
|
||||
varray->fetch_start = start;
|
||||
|
|
@ -27,26 +28,30 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
case PIPE_PRIM_POINTS:
|
||||
case PIPE_PRIM_LINES:
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
j = 0;
|
||||
while (j + first <= count) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
varray_flush_linear(varray, start + j, end);
|
||||
j += end;
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
case PIPE_PRIM_QUADS:
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
|
||||
for (j = 0; j < count;) {
|
||||
unsigned remaining = count - j;
|
||||
unsigned nr = trim( MIN2(FETCH_MAX, remaining), first, incr );
|
||||
varray_flush_linear(varray, start + j, nr);
|
||||
j += nr;
|
||||
if (nr != remaining)
|
||||
j -= (first - incr);
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (count >= 2) {
|
||||
flags = DRAW_PIPE_RESET_STIPPLE;
|
||||
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 1; i < end; i++, flags = 0) {
|
||||
LINE(varray, flags, i - 1, i);
|
||||
for (i = 1; i < end; i++) {
|
||||
LINE(varray, i - 1, i);
|
||||
}
|
||||
LINE(varray, flags, i - 1, 0);
|
||||
LINE(varray, i - 1, 0);
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
|
|
@ -54,144 +59,20 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
flags = DRAW_PIPE_RESET_STIPPLE;
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 1; i < end; i++, flags = 0) {
|
||||
LINE(varray, flags, i - 1, i);
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
if (flatfirst) {
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 0; i+2 < end; i++) {
|
||||
TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
|
||||
i + 0, i + 1 + (i&1), i + 2 - (i&1));
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
if (j + first + i <= count) {
|
||||
varray->fetch_start -= 2;
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 0; i+2 < end; i++) {
|
||||
TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
|
||||
i + 0 + (i&1), i + 1 - (i&1), i + 2);
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
if (j + first + i <= count) {
|
||||
varray->fetch_start -= 2;
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
if (count >= 3) {
|
||||
if (flatfirst) {
|
||||
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 0; i+2 < end; i++) {
|
||||
TRIANGLE(varray, flags, i + 1, i + 2, 0);
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
}
|
||||
}
|
||||
else {
|
||||
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 0; i+2 < end; i++) {
|
||||
TRIANGLE(varray, flags, 0, i + 1, i + 2);
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 0; i+3 < end; i += 4) {
|
||||
QUAD(varray, i + 0, i + 1, i + 2, i + 3);
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 0; i+3 < end; i += 2) {
|
||||
QUAD(varray, i + 2, i + 0, i + 1, i + 3);
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
if (j + first + i <= count) {
|
||||
varray->fetch_start -= 2;
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
{
|
||||
/* These bitflags look a little odd because we submit the
|
||||
* vertices as (1,2,0) to satisfy flatshade requirements.
|
||||
*/
|
||||
const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2;
|
||||
const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0;
|
||||
const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1;
|
||||
|
||||
flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 0; i+2 < end; i++, flags = edge_middle) {
|
||||
|
||||
if (i + 3 == count)
|
||||
flags |= edge_last;
|
||||
|
||||
TRIANGLE(varray, flags, i + 1, i + 2, 0);
|
||||
for (i = 2; i < end; i++) {
|
||||
TRIANGLE(varray, 0, i - 1, i);
|
||||
}
|
||||
i = end;
|
||||
fetch_init(varray, end);
|
||||
varray_flush(varray);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue