Mesa (master): radv/gfx10: determine if a pipeline is eligible for NGG passthrough

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 13 08:48:05 UTC 2020


Module: Mesa
Branch: master
Commit: 0758f645d0784942cd2ba99376d0224c61c4ee99
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0758f645d0784942cd2ba99376d0224c61c4ee99

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Thu Jan  9 08:23:12 2020 +0100

radv/gfx10: determine if a pipeline is eligible for NGG passthrough

It can't be enabled for geometry shaders, for NGG streamout and
for vertex shaders that export the primitive ID. NGG passthrough
requires that LDS isn't used.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

---

 src/amd/vulkan/radv_pipeline.c    | 65 +++++++++++++++++++++++++++++++--------
 src/amd/vulkan/radv_private.h     |  2 ++
 src/amd/vulkan/radv_shader.h      |  2 ++
 src/amd/vulkan/radv_shader_info.c |  2 ++
 4 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index a4cc840027a..12fea44bed8 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -149,6 +149,22 @@ bool radv_pipeline_has_ngg(const struct radv_pipeline *pipeline)
 	return variant->info.is_ngg;
 }
 
+bool radv_pipeline_has_ngg_passthrough(const struct radv_pipeline *pipeline)
+{
+	assert(radv_pipeline_has_ngg(pipeline));
+
+	struct radv_shader_variant *variant = NULL;
+	if (pipeline->shaders[MESA_SHADER_GEOMETRY])
+		variant = pipeline->shaders[MESA_SHADER_GEOMETRY];
+	else if (pipeline->shaders[MESA_SHADER_TESS_EVAL])
+		variant = pipeline->shaders[MESA_SHADER_TESS_EVAL];
+	else if (pipeline->shaders[MESA_SHADER_VERTEX])
+		variant = pipeline->shaders[MESA_SHADER_VERTEX];
+	else
+		return false;
+	return variant->info.is_ngg_passthrough;
+}
+
 bool radv_pipeline_has_gs_copy_shader(const struct radv_pipeline *pipeline)
 {
 	if (!radv_pipeline_has_gs(pipeline))
@@ -2434,20 +2450,35 @@ radv_fill_shader_keys(struct radv_device *device,
 				keys[MESA_SHADER_VERTEX].vs_common_out.as_ngg = false;
 		}
 
-		if (!device->physical_device->use_ngg_streamout) {
-			gl_shader_stage last_xfb_stage = MESA_SHADER_VERTEX;
+		gl_shader_stage last_xfb_stage = MESA_SHADER_VERTEX;
 
-			for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
-				if (nir[i])
-					last_xfb_stage = i;
-			}
+		for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_GEOMETRY; i++) {
+			if (nir[i])
+				last_xfb_stage = i;
+		}
 
-			if (nir[last_xfb_stage] &&
-			    radv_nir_stage_uses_xfb(nir[last_xfb_stage])) {
-				if (nir[MESA_SHADER_TESS_CTRL])
-					keys[MESA_SHADER_TESS_EVAL].vs_common_out.as_ngg = false;
-				else
-					keys[MESA_SHADER_VERTEX].vs_common_out.as_ngg = false;
+		bool uses_xfb = nir[last_xfb_stage] &&
+				radv_nir_stage_uses_xfb(nir[last_xfb_stage]);
+
+		if (!device->physical_device->use_ngg_streamout && uses_xfb) {
+			if (nir[MESA_SHADER_TESS_CTRL])
+				keys[MESA_SHADER_TESS_EVAL].vs_common_out.as_ngg = false;
+			else
+				keys[MESA_SHADER_VERTEX].vs_common_out.as_ngg = false;
+		}
+
+		/* Determine if the pipeline is eligible for the NGG passthrough
+		 * mode. It can't be enabled for geometry shaders, for NGG
+		 * streamout or for vertex shaders that export the primitive ID
+		 * (this is checked later because we don't have the info here.)
+		 */
+		if (!nir[MESA_SHADER_GEOMETRY] && !uses_xfb) {
+			if (nir[MESA_SHADER_TESS_CTRL] &&
+			    keys[MESA_SHADER_TESS_EVAL].vs_common_out.as_ngg) {
+				keys[MESA_SHADER_TESS_EVAL].vs_common_out.as_ngg_passthrough = true;
+			} else if (nir[MESA_SHADER_VERTEX] &&
+				   keys[MESA_SHADER_VERTEX].vs_common_out.as_ngg) {
+				keys[MESA_SHADER_VERTEX].vs_common_out.as_ngg_passthrough = true;
 			}
 		}
 	}
@@ -2523,6 +2554,16 @@ radv_fill_shader_info(struct radv_pipeline *pipeline,
 		keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_clip_dists =
 		        !!infos[MESA_SHADER_FRAGMENT].ps.num_input_clips_culls;
 
+		/* NGG passthrough mode can't be enabled for vertex shaders
+		 * that export the primitive ID.
+		 *
+		 * TODO: I should really refactor the keys logic.
+		 */
+		if (nir[MESA_SHADER_VERTEX] &&
+		    keys[MESA_SHADER_VERTEX].vs_common_out.export_prim_id) {
+			keys[MESA_SHADER_VERTEX].vs_common_out.as_ngg_passthrough = false;
+		}
+
 		filled_stages |= (1 << MESA_SHADER_FRAGMENT);
 	}
 
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 4dccf23acc7..082a8451cc0 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1656,6 +1656,8 @@ static inline bool radv_pipeline_has_tess(const struct radv_pipeline *pipeline)
 
 bool radv_pipeline_has_ngg(const struct radv_pipeline *pipeline);
 
+bool radv_pipeline_has_ngg_passthrough(const struct radv_pipeline *pipeline);
+
 bool radv_pipeline_has_gs_copy_shader(const struct radv_pipeline *pipeline);
 
 struct radv_userdata_info *radv_lookup_user_sgpr(struct radv_pipeline *pipeline,
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index 7ffce47bdd8..37b54c2f494 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -55,6 +55,7 @@ struct radv_vs_out_key {
 	uint32_t as_es:1;
 	uint32_t as_ls:1;
 	uint32_t as_ngg:1;
+	uint32_t as_ngg_passthrough:1;
 	uint32_t export_prim_id:1;
 	uint32_t export_layer_id:1;
 	uint32_t export_clip_dists:1;
@@ -241,6 +242,7 @@ struct radv_shader_info {
 	unsigned private_mem_vgprs;
 	bool need_indirect_descriptor_sets;
 	bool is_ngg;
+	bool is_ngg_passthrough;
 	struct {
 		uint64_t ls_outputs_written;
 		uint8_t input_usage_mask[VERT_ATTRIB_MAX];
diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c
index 5384d1a0d17..613746c7dde 100644
--- a/src/amd/vulkan/radv_shader_info.c
+++ b/src/amd/vulkan/radv_shader_info.c
@@ -755,6 +755,7 @@ radv_nir_shader_info_pass(const struct nir_shader *nir,
                 info->tes.as_es = key->vs_common_out.as_es;
                 info->tes.export_prim_id = key->vs_common_out.export_prim_id;
                 info->is_ngg = key->vs_common_out.as_ngg;
+                info->is_ngg_passthrough = key->vs_common_out.as_ngg_passthrough;
                 break;
         case MESA_SHADER_TESS_CTRL:
                 info->tcs.tcs_vertices_out = nir->info.tess.tcs_vertices_out;
@@ -764,6 +765,7 @@ radv_nir_shader_info_pass(const struct nir_shader *nir,
                 info->vs.as_ls = key->vs_common_out.as_ls;
                 info->vs.export_prim_id = key->vs_common_out.export_prim_id;
                 info->is_ngg = key->vs_common_out.as_ngg;
+                info->is_ngg_passthrough = key->vs_common_out.as_ngg_passthrough;
                 break;
         default:
                 break;




More information about the mesa-commit mailing list