Module: Mesa Branch: main Commit: 8e9262fefdfc2adbc20b92894037534a282c420a URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8e9262fefdfc2adbc20b92894037534a282c420a
Author: antonino <[email protected]> Date: Mon Feb 6 15:44:01 2023 +0100 gallium: decompose quad strips into quads if supported This changes gallium to decompose quad strips into quads instead of triangles when the driver advertises support for them. This should result in a more correct result when those are drawn with the line raster primitve (avoids showing the diagonal line). Reviewed-By: Mike Blumenkrantz <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21987> --- src/gallium/auxiliary/indices/u_indices.c | 17 +++- src/gallium/auxiliary/indices/u_indices_gen.py | 122 ++++++++++++++++--------- 2 files changed, 93 insertions(+), 46 deletions(-) diff --git a/src/gallium/auxiliary/indices/u_indices.c b/src/gallium/auxiliary/indices/u_indices.c index 53dbb760d0e..e43072351fd 100644 --- a/src/gallium/auxiliary/indices/u_indices.c +++ b/src/gallium/auxiliary/indices/u_indices.c @@ -57,6 +57,10 @@ u_index_prim_type_convert(unsigned hw_mask, enum pipe_prim_type prim, bool pv_ma case PIPE_PRIM_TRIANGLE_FAN: case PIPE_PRIM_QUADS: case PIPE_PRIM_QUAD_STRIP: + if ((hw_mask & (1<<PIPE_PRIM_QUADS)) && pv_matches) + return PIPE_PRIM_QUADS; + else + return PIPE_PRIM_TRIANGLES; case PIPE_PRIM_POLYGON: return PIPE_PRIM_TRIANGLES; case PIPE_PRIM_LINES_ADJACENCY: @@ -140,8 +144,9 @@ u_index_translator(unsigned hw_mask, return U_TRANSLATE_MEMCPY; } - *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][prim]; *out_prim = u_index_prim_type_convert(hw_mask, prim, in_pv == out_pv); + *out_translate = (*out_prim == PIPE_PRIM_QUADS ? translate_quads : translate) + [in_idx][out_idx][in_pv][out_pv][prim_restart][prim]; *out_nr = u_index_count_converted_indices(hw_mask, in_pv == out_pv, prim, nr); return ret; @@ -170,9 +175,9 @@ u_index_count_converted_indices(unsigned hw_mask, bool pv_matches, enum pipe_pri case PIPE_PRIM_TRIANGLE_FAN: return (nr - 2) * 3; case PIPE_PRIM_QUADS: - return (nr / 4) * 6; + return ((hw_mask & (1<<PIPE_PRIM_QUADS)) && pv_matches) ? nr : (nr / 4) * 6; case PIPE_PRIM_QUAD_STRIP: - return (nr - 2) * 3; + return ((hw_mask & (1<<PIPE_PRIM_QUADS)) && pv_matches) ? (nr - 2) * 2 : (nr - 2) * 3; case PIPE_PRIM_POLYGON: return (nr - 2) * 3; case PIPE_PRIM_LINES_ADJACENCY: @@ -237,9 +242,11 @@ u_index_generator(unsigned hw_mask, if ((hw_mask & (1<<prim)) && (in_pv == out_pv)) { - *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS]; + *out_generate = (*out_prim == PIPE_PRIM_QUADS ? generate_quads : generate) + [out_idx][in_pv][out_pv][PIPE_PRIM_POINTS]; return U_GENERATE_LINEAR; } - *out_generate = generate[out_idx][in_pv][out_pv][prim]; + *out_generate = (*out_prim == PIPE_PRIM_QUADS ? generate_quads : generate) + [out_idx][in_pv][out_pv][prim]; return prim == PIPE_PRIM_LINE_LOOP ? U_GENERATE_ONE_OFF : U_GENERATE_REUSABLE; } diff --git a/src/gallium/auxiliary/indices/u_indices_gen.py b/src/gallium/auxiliary/indices/u_indices_gen.py index de3bf957057..03640699cee 100644 --- a/src/gallium/auxiliary/indices/u_indices_gen.py +++ b/src/gallium/auxiliary/indices/u_indices_gen.py @@ -51,6 +51,8 @@ PRIMS=('points', 'trisadj', 'tristripadj') +OUT_TRIS, OUT_QUADS = 'tris', 'quads' + LONGPRIMS=('PIPE_PRIM_POINTS', 'PIPE_PRIM_LINES', 'PIPE_PRIM_LINE_STRIP', @@ -91,6 +93,9 @@ def prolog(f: 'T.TextIO') -> None: static u_translate_func translate[IN_COUNT][OUT_COUNT][PV_COUNT][PV_COUNT][PR_COUNT][PRIM_COUNT]; static u_generate_func generate[OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT]; +static u_translate_func translate_quads[IN_COUNT][OUT_COUNT][PV_COUNT][PV_COUNT][PR_COUNT][PRIM_COUNT]; +static u_generate_func generate_quads[OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT]; + ''') @@ -121,13 +126,21 @@ def do_tri(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, inpv, outpv ): else: shape(f, intype, outtype, ptr, v2, v0, v1 ) -def do_quad(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ): - if inpv == LAST: - do_tri(f, intype, outtype, ptr+'+0', v0, v1, v3, inpv, outpv ); - do_tri(f, intype, outtype, ptr+'+3', v1, v2, v3, inpv, outpv ); +def do_quad(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv, out_prim ): + if out_prim == OUT_TRIS: + if inpv == LAST: + do_tri(f, intype, outtype, ptr+'+0', v0, v1, v3, inpv, outpv ); + do_tri(f, intype, outtype, ptr+'+3', v1, v2, v3, inpv, outpv ); + else: + do_tri(f, intype, outtype, ptr+'+0', v0, v1, v2, inpv, outpv ); + do_tri(f, intype, outtype, ptr+'+3', v0, v2, v3, inpv, outpv ); else: - do_tri(f, intype, outtype, ptr+'+0', v0, v1, v2, inpv, outpv ); - do_tri(f, intype, outtype, ptr+'+3', v0, v2, v3, inpv, outpv ); + if inpv == outpv: + shape(f, intype, outtype, ptr, v0, v1, v2, v3) + elif inpv == FIRST: + shape(f, intype, outtype, ptr, v1, v2, v3, v0) + else: + shape(f, intype, outtype, ptr, v3, v0, v1, v2) def do_lineadj(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ): if inpv == outpv: @@ -141,14 +154,14 @@ def do_triadj(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, v3, v4, v5, inpv, else: shape(f, intype, outtype, ptr, v4, v5, v0, v1, v2, v3 ) -def name(intype, outtype, inpv, outpv, pr, prim): +def name(intype, outtype, inpv, outpv, pr, prim, out_prim): if intype == GENERATE: - return 'generate_' + prim + '_' + outtype + '_' + inpv + '2' + outpv + return 'generate_' + prim + '_' + outtype + '_' + inpv + '2' + outpv + '_' + str(out_prim) else: - return 'translate_' + prim + '_' + intype + '2' + outtype + '_' + inpv + '2' + outpv + '_' + pr + return 'translate_' + prim + '_' + intype + '2' + outtype + '_' + inpv + '2' + outpv + '_' + pr + '_' + str(out_prim) -def preamble(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, prim): - f.write('static void ' + name( intype, outtype, inpv, outpv, pr, prim ) + '(\n') +def preamble(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, prim, out_prim): + f.write('static void ' + name( intype, outtype, inpv, outpv, pr, prim, out_prim ) + '(\n') if intype != GENERATE: f.write(' const void * restrict _in,\n') f.write(' unsigned start,\n') @@ -186,28 +199,28 @@ def prim_restart(f: 'T.TextIO', in_verts, out_verts, out_prims, close_func = Non f.write(' }\n') def points(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='points') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='points') f.write(' for (i = start, j = 0; j < out_nr; j++, i++) {\n') do_point(f, intype, outtype, 'out+j', 'i' ); f.write(' }\n') postamble(f) def lines(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='lines') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='lines') f.write(' for (i = start, j = 0; j < out_nr; j+=2, i+=2) {\n') do_line(f, intype, outtype, 'out+j', 'i', 'i+1', inpv, outpv ); f.write(' }\n') postamble(f) def linestrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='linestrip') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='linestrip') f.write(' for (i = start, j = 0; j < out_nr; j+=2, i++) {\n') do_line(f, intype, outtype, 'out+j', 'i', 'i+1', inpv, outpv ); f.write(' }\n') postamble(f) def lineloop(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='lineloop') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='lineloop') f.write(' unsigned end = start;\n') f.write(' for (i = start, j = 0; j < out_nr - 2; j+=2, i++) {\n') if pr == PRENABLE: @@ -226,7 +239,7 @@ def lineloop(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): postamble(f) def tris(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='tris') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='tris') f.write(' for (i = start, j = 0; j < out_nr; j+=3, i+=3) {\n') do_tri(f, intype, outtype, 'out+j', 'i', 'i+1', 'i+2', inpv, outpv ); f.write(' }\n') @@ -234,7 +247,7 @@ def tris(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): def tristrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='tristrip') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='tristrip') f.write(' for (i = start, j = 0; j < out_nr; j+=3, i++) {\n') if inpv == FIRST: do_tri(f, intype, outtype, 'out+j', 'i', 'i+1+(i&1)', 'i+2-(i&1)', inpv, outpv ); @@ -245,7 +258,7 @@ def tristrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): def trifan(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='trifan') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='trifan') f.write(' for (i = start, j = 0; j < out_nr; j+=3, i++) {\n') if pr == PRENABLE: @@ -264,7 +277,7 @@ def trifan(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): def polygon(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='polygon') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='polygon') f.write(' for (i = start, j = 0; j < out_nr; j+=3, i++) {\n') if pr == PRENABLE: def close_func(index): @@ -279,33 +292,43 @@ def polygon(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): postamble(f) -def quads(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='quads') - f.write(' for (i = start, j = 0; j < out_nr; j+=6, i+=4) {\n') - if pr == PRENABLE: +def quads(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, out_prim): + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=out_prim, prim='quads') + if out_prim == OUT_TRIS: + f.write(' for (i = start, j = 0; j < out_nr; j+=6, i+=4) {\n') + else: + f.write(' for (i = start, j = 0; j < out_nr; j+=4, i+=4) {\n') + if pr == PRENABLE and out_prim == OUT_TRIS: prim_restart(f, 4, 3, 2) + elif pr == PRENABLE: + prim_restart(f, 4, 4, 1) - do_quad(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv ); + do_quad(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv, out_prim ); f.write(' }\n') postamble(f) -def quadstrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='quadstrip') - f.write(' for (i = start, j = 0; j < out_nr; j+=6, i+=2) {\n') - if pr == PRENABLE: +def quadstrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, out_prim): + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=out_prim, prim='quadstrip') + if out_prim == OUT_TRIS: + f.write(' for (i = start, j = 0; j < out_nr; j+=6, i+=2) {\n') + else: + f.write(' for (i = start, j = 0; j < out_nr; j+=4, i+=2) {\n') + if pr == PRENABLE and out_prim == OUT_TRIS: prim_restart(f, 4, 3, 2) + elif pr == PRENABLE: + prim_restart(f, 4, 4, 1) if inpv == LAST: - do_quad(f, intype, outtype, 'out+j', 'i+2', 'i+0', 'i+1', 'i+3', inpv, outpv ); + do_quad(f, intype, outtype, 'out+j', 'i+2', 'i+0', 'i+1', 'i+3', inpv, outpv, out_prim ); else: - do_quad(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+3', 'i+2', inpv, outpv ); + do_quad(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+3', 'i+2', inpv, outpv, out_prim ); f.write(' }\n') postamble(f) def linesadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='linesadj') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='linesadj') f.write(' for (i = start, j = 0; j < out_nr; j+=4, i+=4) {\n') do_lineadj(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv ) f.write(' }\n') @@ -313,7 +336,7 @@ def linesadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): def linestripadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='linestripadj') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='linestripadj') f.write(' for (i = start, j = 0; j < out_nr; j+=4, i++) {\n') do_lineadj(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv ) f.write(' }\n') @@ -321,7 +344,7 @@ def linestripadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): def trisadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='trisadj') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='trisadj') f.write(' for (i = start, j = 0; j < out_nr; j+=6, i+=6) {\n') do_triadj(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', 'i+4', 'i+5', inpv, outpv ) @@ -330,7 +353,7 @@ def trisadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): def tristripadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr): - preamble(f, intype, outtype, inpv, outpv, pr, prim='tristripadj') + preamble(f, intype, outtype, inpv, outpv, pr, out_prim=OUT_TRIS, prim='tristripadj') f.write(' for (i = start, j = 0; j < out_nr; i+=2, j+=6) {\n') f.write(' if (i % 4 == 0) {\n') f.write(' /* even triangle */\n') @@ -357,31 +380,44 @@ def emit_funcs(f: 'T.TextIO') -> None: tris(f, intype, outtype, inpv, outpv, pr) tristrip(f, intype, outtype, inpv, outpv, pr) trifan(f, intype, outtype, inpv, outpv, pr) - quads(f, intype, outtype, inpv, outpv, pr) - quadstrip(f, intype, outtype, inpv, outpv, pr) + quads(f, intype, outtype, inpv, outpv, pr, OUT_TRIS) + quadstrip(f, intype, outtype, inpv, outpv, pr, OUT_TRIS) polygon(f, intype, outtype, inpv, outpv, pr) linesadj(f, intype, outtype, inpv, outpv, pr) linestripadj(f, intype, outtype, inpv, outpv, pr) trisadj(f, intype, outtype, inpv, outpv, pr) tristripadj(f, intype, outtype, inpv, outpv, pr) -def init(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, prim): + for intype, outtype, inpv, outpv, pr in itertools.product( + INTYPES, OUTTYPES, [FIRST, LAST], [FIRST, LAST], [PRDISABLE, PRENABLE]): + if pr == PRENABLE and intype == GENERATE: + continue + quads(f, intype, outtype, inpv, outpv, pr, OUT_QUADS) + quadstrip(f, intype, outtype, inpv, outpv, pr, OUT_QUADS) + +def init(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, prim, out_prim=OUT_TRIS): + generate_name = 'generate' + translate_name = 'translate' + if out_prim == OUT_QUADS: + generate_name = 'generate_quads' + translate_name = 'translate_quads' + if intype == GENERATE: - f.write('generate[' + + f.write(f'{generate_name}[' + outtype_idx[outtype] + '][' + pv_idx[inpv] + '][' + pv_idx[outpv] + '][' + longprim[prim] + - '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';\n') + '] = ' + name( intype, outtype, inpv, outpv, pr, prim, out_prim ) + ';\n') else: - f.write('translate[' + + f.write(f'{translate_name}[' + intype_idx[intype] + '][' + outtype_idx[outtype] + '][' + pv_idx[inpv] + '][' + pv_idx[outpv] + '][' + pr_idx[pr] + '][' + longprim[prim] + - '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';\n') + '] = ' + name( intype, outtype, inpv, outpv, pr, prim, out_prim ) + ';\n') def emit_all_inits(f: 'T.TextIO'): @@ -389,6 +425,10 @@ def emit_all_inits(f: 'T.TextIO'): INTYPES, OUTTYPES, PVS, PVS, PRS, PRIMS): init(f,intype, outtype, inpv, outpv, pr, prim) + for intype, outtype, inpv, outpv, pr, prim in itertools.product( + INTYPES, OUTTYPES, PVS, PVS, PRS, ['quads', 'quadstrip']): + init(f,intype, outtype, inpv, outpv, pr, prim, OUT_QUADS) + def emit_init(f: 'T.TextIO'): f.write('void u_index_init( void )\n') f.write('{\n')
