aboutsummaryrefslogtreecommitdiffstats
path: root/src/amd
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2020-01-09 08:23:12 +0100
committerSamuel Pitoiset <[email protected]>2020-01-13 08:14:40 +0100
commit0758f645d0784942cd2ba99376d0224c61c4ee99 (patch)
tree528cc3737c4694f254d3dbdc6a322bcd4ffc46fc /src/amd
parentc65015f83c3bad4c140a013bac2c9eb59abec907 (diff)
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 <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/vulkan/radv_pipeline.c65
-rw-r--r--src/amd/vulkan/radv_private.h2
-rw-r--r--src/amd/vulkan/radv_shader.h2
-rw-r--r--src/amd/vulkan/radv_shader_info.c2
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;