From 3b1b1af6942e7d38cd35d4d47c2e37c3cce2b32f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 13 Aug 2021 15:00:13 +1000 Subject: [PATCH] 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 Reviewed-by: Roland Scheidegger Reviewed-by: Adam Jackson Part-of: --- src/gallium/auxiliary/draw/draw_decompose_tmp.h | 22 ++++++++++++++++-- src/gallium/auxiliary/draw/draw_gs_tmp.h | 2 +- src/gallium/auxiliary/draw/draw_prim_assembler.c | 26 +++++++++++++++++++++- .../auxiliary/draw/draw_prim_assembler_tmp.h | 5 ++--- src/gallium/auxiliary/util/u_prim.h | 8 +++++-- 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_decompose_tmp.h b/src/gallium/auxiliary/draw/draw_decompose_tmp.h index e9f3b1d..7686afe 100644 --- a/src/gallium/auxiliary/draw/draw_decompose_tmp.h +++ b/src/gallium/auxiliary/draw/draw_decompose_tmp.h @@ -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 } } } diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h index 5a5b9e2..9f54bbe 100644 --- a/src/gallium/auxiliary/draw/draw_gs_tmp.h +++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h @@ -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" diff --git a/src/gallium/auxiliary/draw/draw_prim_assembler.c b/src/gallium/auxiliary/draw/draw_prim_assembler.c index e628a14..9a957f3 100644 --- a/src/gallium/auxiliary/draw/draw_prim_assembler.c +++ b/src/gallium/auxiliary/draw/draw_prim_assembler.c @@ -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; diff --git a/src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h b/src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h index 145a8ca..bcd0f3f 100644 --- a/src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h +++ b/src/gallium/auxiliary/draw/draw_prim_assembler_tmp.h @@ -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" diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index b9d4a9e..1fbb2f5 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -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; -- 2.7.4