draw: handle primitive ID for quads/quad strips.

In order to enable compat contexts QUADS/QUAD_STRIPS need
to support primitive ID. There are some piglit tests for this.

This adds support to the decomposer to pass quads so the prim
assembler can pick them up and add primitive IDs.

Acked-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12374>
This commit is contained in:
Dave Airlie 2021-08-13 15:00:13 +10:00
parent 441e490f5a
commit 3b1b1af694
5 changed files with 54 additions and 9 deletions

View file

@ -170,7 +170,10 @@ FUNC(FUNC_VARS)
idx[1] = GET_ELT(i + 1);
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
#ifdef PASS_QUADS
QUAD(0, idx[0], idx[1],
idx[2], idx[3]);
#else
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_2;
@ -180,6 +183,7 @@ FUNC(FUNC_VARS)
flags = DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
TRIANGLE(flags, idx[1], idx[2], idx[3]);
#endif
}
}
else {
@ -188,7 +192,10 @@ FUNC(FUNC_VARS)
idx[1] = GET_ELT(i + 1);
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
#ifdef PASS_QUADS
QUAD(0, idx[0], idx[1],
idx[2], idx[3]);
#else
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
@ -204,6 +211,7 @@ FUNC(FUNC_VARS)
TRIANGLE(flags, idx[3], idx[1], idx[2]);
else
TRIANGLE(flags, idx[0], idx[2], idx[3]);
#endif
}
}
break;
@ -220,6 +228,10 @@ FUNC(FUNC_VARS)
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
#ifdef PASS_QUADS
QUAD(0, idx[2], idx[0],
idx[1], idx[3]);
#else
/* always emit idx[3] last */
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
@ -229,6 +241,7 @@ FUNC(FUNC_VARS)
flags = DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
TRIANGLE(flags, idx[0], idx[1], idx[3]);
#endif
}
}
else {
@ -238,6 +251,10 @@ FUNC(FUNC_VARS)
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
#ifdef PASS_QUADS
QUAD(0, idx[3], idx[2],
idx[0], idx[1]);
#else
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
@ -253,6 +270,7 @@ FUNC(FUNC_VARS)
TRIANGLE(flags, idx[3], idx[0], idx[1]);
else
TRIANGLE(flags, idx[0], idx[1], idx[3]);
#endif
}
}
}

View file

@ -28,5 +28,5 @@
#define TRIANGLE(flags,i0,i1,i2) gs_tri(gs,i0,i1,i2)
#define LINE_ADJ(flags,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3)
#define TRIANGLE_ADJ(flags,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5)
#define QUAD(flags,i0,i1,i2,i3)
#include "draw_decompose_tmp.h"

View file

@ -201,6 +201,28 @@ prim_tri(struct draw_assembler *asmblr,
copy_verts(asmblr, indices, 3);
}
static void
prim_quad(struct draw_assembler *asmblr,
unsigned i0, unsigned i1,
unsigned i2, unsigned i3)
{
unsigned indices[4];
if (asmblr->needs_primid) {
inject_primid(asmblr, i0, asmblr->primid);
inject_primid(asmblr, i1, asmblr->primid);
inject_primid(asmblr, i2, asmblr->primid);
inject_primid(asmblr, i3, asmblr->primid++);
}
indices[0] = i0;
indices[1] = i1;
indices[2] = i2;
indices[3] = i3;
add_prim(asmblr, 4);
copy_verts(asmblr, indices, 4);
}
void
draw_prim_assembler_prepare_outputs(struct draw_assembler *ia)
{
@ -244,7 +266,9 @@ draw_prim_assembler_run(struct draw_context *draw,
{
struct draw_assembler *asmblr = draw->ia;
unsigned start, i;
unsigned assembled_prim = u_reduced_prim(input_prims->prim);
unsigned assembled_prim = (input_prims->prim == PIPE_PRIM_QUADS ||
input_prims->prim == PIPE_PRIM_QUAD_STRIP) ?
PIPE_PRIM_QUADS : u_reduced_prim(input_prims->prim);
unsigned max_primitives = u_decomposed_prims_for_vertices(
input_prims->prim, input_prims->count);
unsigned max_verts = u_vertices_per_prim(assembled_prim) * max_primitives;

View file

@ -9,11 +9,8 @@
/* declare more local vars */ \
const unsigned prim = input_prims->prim; \
const unsigned prim_flags = input_prims->flags; \
const boolean quads_flatshade_last = FALSE; \
const boolean last_vertex_last = !asmblr->draw->rasterizer->flatshade_first; \
switch (prim) { \
case PIPE_PRIM_QUADS: \
case PIPE_PRIM_QUAD_STRIP: \
case PIPE_PRIM_POLYGON: \
debug_assert(!"unexpected primitive type in prim assembler"); \
return; \
@ -22,8 +19,10 @@
}
#define PASS_QUADS
#define POINT(i0) prim_point(asmblr, i0)
#define LINE(flags, i0, i1) prim_line(asmblr, i0, i1)
#define TRIANGLE(flags, i0, i1, i2) prim_tri(asmblr, i0, i1, i2)
#define QUAD(flags, i0, i1, i2, i3) prim_quad(asmblr, i0, i1, i2, i3)
#include "draw_decompose_tmp.h"

View file

@ -201,12 +201,16 @@ u_vertices_per_prim(enum pipe_prim_type primitive)
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
return 6;
case PIPE_PRIM_QUADS:
case PIPE_PRIM_QUAD_STRIP:
/* these won't be seen from geometry shaders
but prim assembly might for prim id. */
return 4;
/* following primitives should never be used
* with geometry shaders abd their size is
* undefined */
case PIPE_PRIM_POLYGON:
case PIPE_PRIM_QUADS:
case PIPE_PRIM_QUAD_STRIP:
default:
debug_printf("Unrecognized geometry shader primitive");
return 3;