From 2a91e83b7f5d2822c3fc06d0edba1d0f70cadff9 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 22 Oct 2021 13:24:40 -0400 Subject: [PATCH] zink: detect prim type more accurately for tess/gs lines u_reduced_prim() can't determine the output primitive when vs isn't the last vertex stage, so store this from the appropriate shader info and use it when it's available fixes #5547 cc: mesa-stable Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_compiler.c | 33 ++++++++++++++++++++++++ src/gallium/drivers/zink/zink_compiler.h | 1 + src/gallium/drivers/zink/zink_draw.cpp | 4 ++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 6a4da25523d..1715ce2c2d1 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -1292,6 +1292,38 @@ handle_bindless_var(nir_shader *nir, nir_variable *var, const struct glsl_type * var->data.mode = nir_var_shader_temp; } +static enum pipe_prim_type +gl_prim_to_pipe(unsigned primitive_type) +{ + switch (primitive_type) { + case GL_POINTS: + return PIPE_PRIM_POINTS; + case GL_LINES: + case GL_LINE_LOOP: + case GL_LINE_STRIP: + case GL_LINES_ADJACENCY: + case GL_LINE_STRIP_ADJACENCY: + case GL_ISOLINES: + return PIPE_PRIM_LINES; + default: + return PIPE_PRIM_TRIANGLES; + } +} + +static enum pipe_prim_type +get_shader_base_prim_type(struct nir_shader *nir) +{ + switch (nir->info.stage) { + case MESA_SHADER_GEOMETRY: + return gl_prim_to_pipe(nir->info.gs.output_primitive); + case MESA_SHADER_TESS_EVAL: + return nir->info.tess.point_mode ? PIPE_PRIM_POINTS : gl_prim_to_pipe(nir->info.tess.primitive_mode); + default: + break; + } + return PIPE_PRIM_MAX; +} + struct zink_shader * zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, const struct pipe_stream_output_info *so_info) @@ -1300,6 +1332,7 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, bool have_psiz = false; ret->hash = _mesa_hash_pointer(ret); + ret->reduced_prim = get_shader_base_prim_type(nir); ret->programs = _mesa_pointer_set_create(NULL); simple_mtx_init(&ret->lock, mtx_plain); diff --git a/src/gallium/drivers/zink/zink_compiler.h b/src/gallium/drivers/zink/zink_compiler.h index bab443d069a..49834164fec 100644 --- a/src/gallium/drivers/zink/zink_compiler.h +++ b/src/gallium/drivers/zink/zink_compiler.h @@ -70,6 +70,7 @@ struct zink_shader { struct util_live_shader base; uint32_t hash; struct nir_shader *nir; + enum pipe_prim_type reduced_prim; // PIPE_PRIM_MAX for vs struct zink_so_info streamout; diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 0a38c339ab2..c1bbe5d49ee 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -681,7 +681,9 @@ zink_draw_vbo(struct pipe_context *pctx, VKCTX(CmdSetLineStippleEXT)(batch->state->cmdbuf, rast_state->base.line_stipple_factor, rast_state->base.line_stipple_pattern); if (BATCH_CHANGED || ctx->rast_state_changed || mode_changed) { - enum pipe_prim_type reduced_prim = u_reduced_prim(mode); + enum pipe_prim_type reduced_prim = ctx->last_vertex_stage->reduced_prim; + if (reduced_prim == PIPE_PRIM_MAX) + reduced_prim = u_reduced_prim(mode); bool depth_bias = false; switch (reduced_prim) {