From 219407fd0138d5e5febcf9b2d0595d5b6b2cdeb3 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Fri, 22 Jan 2021 16:14:32 +0100 Subject: [PATCH] zink: clone shader before lowering clip_halfz If we don't clone the shader before lowering clip_halfz, we risk ending up performing the same lowering multiple times, each time we compile a new variant. This fixes rendering in Neverball. Fixes: 15f478fe840 ("zink: only run nir_lower_clip_halfz for last vertex processing stage") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4147 Reviewed-By: Mike Blumenkrantz Part-of: (cherry picked from commit 92ec7b577c8cb47b308bba1d21b4c2ec05f35f9f) --- .pick_status.json | 2 +- src/gallium/drivers/zink/zink_compiler.c | 35 +++++++++++++----------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 51b0136816e..fbdd8fff0d9 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -94,7 +94,7 @@ "description": "zink: clone shader before lowering clip_halfz", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": "15f478fe840c29ba118fbb4fa49118f85fb208c6" }, diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 832ba9a210e..8eedbeeb5d2 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -313,6 +313,17 @@ update_so_info(struct zink_shader *sh, } } +static bool +last_vertex_stage(struct zink_shader *zs) +{ + assert(zs->nir->info.stage != MESA_SHADER_FRAGMENT); + if (zs->has_geometry_shader) + return zs->nir->info.stage == MESA_SHADER_GEOMETRY; + if (zs->has_tess_shader) + return zs->nir->info.stage == MESA_SHADER_TESS_EVAL; + return true; +} + VkShaderModule zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, struct zink_shader_key *key, unsigned char *shader_slot_map, unsigned char *shader_slots_reserved) @@ -321,26 +332,18 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, struct z void *streamout = NULL; nir_shader *nir = zs->nir; /* TODO: use a separate mem ctx here for ralloc */ - if (zs->has_geometry_shader) { - if (zs->nir->info.stage == MESA_SHADER_GEOMETRY) { - streamout = &zs->streamout; - NIR_PASS_V(nir, nir_lower_clip_halfz); - } - } else if (zs->has_tess_shader) { - if (zs->nir->info.stage == MESA_SHADER_TESS_EVAL) { - streamout = &zs->streamout; + if (zs->nir->info.stage != MESA_SHADER_FRAGMENT) { + if (last_vertex_stage(zs)) { + if (zs->streamout.so_info_slots) + streamout = &zs->streamout; + + nir = nir_shader_clone(NULL, zs->nir); NIR_PASS_V(nir, nir_lower_clip_halfz); } } else { - streamout = &zs->streamout; - NIR_PASS_V(nir, nir_lower_clip_halfz); - } - if (!zs->streamout.so_info_slots) - streamout = NULL; - if (zs->nir->info.stage == MESA_SHADER_FRAGMENT) { - nir = nir_shader_clone(NULL, nir); if (!zink_fs_key(key)->samples && nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) { + nir = nir_shader_clone(NULL, zs->nir); /* VK will always use gl_SampleMask[] values even if sample count is 0, * so we need to skip this write here to mimic GL's behavior of ignoring it */ @@ -376,7 +379,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, struct z if (vkCreateShaderModule(screen->dev, &smci, NULL, &mod) != VK_SUCCESS) mod = VK_NULL_HANDLE; - if (zs->nir->info.stage == MESA_SHADER_FRAGMENT) + if (nir != zs->nir) ralloc_free(nir); /* TODO: determine if there's any reason to cache spirv output? */