[Mesa-dev] [PATCH 9/9] radv: Link shaders.

Timothy Arceri tarceri at itsqueeze.com
Sat Oct 14 23:36:47 UTC 2017


From: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

Here we make use of NIR the linking helpers to remove unused
varyings.

Sascha Willems demo results:

computecullandlod 39 -> 41 fps
pipelines ~6100 -> ~6200 fps

Signed-off-by: Bas Nieuwenhuizen <basni at google.com>
Signed-off-by: Timothy Arceri <tarceri at itsqueeze.com>
---
 src/amd/vulkan/radv_pipeline.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/amd/vulkan/radv_shader.c   |  2 +-
 src/amd/vulkan/radv_shader.h   |  3 +++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index e95925fda5..9e0b494802 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -1515,20 +1515,60 @@ static void calculate_ps_inputs(struct radv_pipeline *pipeline)
 
 		flat_shade = !!(ps->info.fs.flat_shaded_mask & (1u << ps_offset));
 
 		pipeline->graphics.ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, flat_shade);
 		++ps_offset;
 	}
 
 	pipeline->graphics.ps_input_cntl_num = ps_offset;
 }
 
+static void
+radv_link_shaders(struct radv_pipeline *pipeline, nir_shader **shaders)
+{
+	nir_shader* ordered_shaders[MESA_SHADER_STAGES];
+	int shader_count = 0;
+
+	if(shaders[MESA_SHADER_FRAGMENT]) {
+		ordered_shaders[shader_count++] = shaders[MESA_SHADER_FRAGMENT];
+	}
+	if(shaders[MESA_SHADER_GEOMETRY]) {
+		ordered_shaders[shader_count++] = shaders[MESA_SHADER_GEOMETRY];
+	}
+	if(shaders[MESA_SHADER_TESS_EVAL]) {
+		ordered_shaders[shader_count++] = shaders[MESA_SHADER_TESS_EVAL];
+	}
+	if(shaders[MESA_SHADER_TESS_CTRL]) {
+		ordered_shaders[shader_count++] = shaders[MESA_SHADER_TESS_CTRL];
+	}
+	if(shaders[MESA_SHADER_VERTEX]) {
+		ordered_shaders[shader_count++] = shaders[MESA_SHADER_VERTEX];
+	}
+
+	for (int i = 1; i < shader_count; ++i)  {
+		nir_remove_dead_variables(ordered_shaders[i],
+					  nir_var_shader_out);
+		nir_remove_dead_variables(ordered_shaders[i - 1],
+					  nir_var_shader_in);
+
+		bool progress = nir_remove_unused_varyings(ordered_shaders[i],
+							   ordered_shaders[i - 1]);
+
+		if (progress) {
+			nir_lower_global_vars_to_local(ordered_shaders[i]);
+			radv_optimize_nir(ordered_shaders[i]);
+			nir_lower_global_vars_to_local(ordered_shaders[i - 1]);
+			radv_optimize_nir(ordered_shaders[i - 1]);
+		}
+	}
+}
+
 static
 void radv_create_shaders(struct radv_pipeline *pipeline,
                          struct radv_device *device,
                          struct radv_pipeline_cache *cache,
                          struct ac_shader_variant_key *keys,
                          const VkPipelineShaderStageCreateInfo **pStages)
 {
 	struct radv_shader_module fs_m = {0};
 	struct radv_shader_module *modules[MESA_SHADER_STAGES] = { 0, };
 	nir_shader *nir[MESA_SHADER_STAGES] = {0};
@@ -1598,20 +1638,22 @@ void radv_create_shaders(struct radv_pipeline *pipeline,
 		if (keys) {
 			keys[MESA_SHADER_VERTEX].vs.export_prim_id =
 				pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input;
 			keys[MESA_SHADER_TESS_EVAL].tes.export_prim_id =
 				pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input;
 		}
 
 		pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_FRAGMENT);
 	}
 
+	radv_link_shaders(pipeline, nir);
+
 	for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
 		if(modules[i] && !pipeline->shaders[i]) {
 			pipeline->shaders[i] = radv_shader_variant_create(device, modules[i], nir[i],
 									  pipeline->layout,
 									  keys ? keys + i : 0, &codes[i],
 									  &code_sizes[i]);
 
 		pipeline->active_stages |= mesa_to_vk_shader_stage(i);
 		}
 	}
diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index d4bef9792e..055787a705 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -103,21 +103,21 @@ void radv_DestroyShaderModule(
 {
 	RADV_FROM_HANDLE(radv_device, device, _device);
 	RADV_FROM_HANDLE(radv_shader_module, module, _module);
 
 	if (!module)
 		return;
 
 	vk_free2(&device->alloc, pAllocator, module);
 }
 
-static void
+void
 radv_optimize_nir(struct nir_shader *shader)
 {
         bool progress;
 
         do {
                 progress = false;
 
                 NIR_PASS_V(shader, nir_lower_vars_to_ssa);
 		NIR_PASS_V(shader, nir_lower_64bit_pack);
                 NIR_PASS_V(shader, nir_lower_alu_to_scalar);
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index 1ef13968f9..3862b3094c 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -60,20 +60,23 @@ struct radv_shader_variant {
 };
 
 struct radv_shader_slab {
 	struct list_head slabs;
 	struct list_head shaders;
 	struct radeon_winsys_bo *bo;
 	uint64_t size;
 	char *ptr;
 };
 
+void
+radv_optimize_nir(struct nir_shader *shader);
+
 nir_shader *
 radv_shader_compile_to_nir(struct radv_device *device,
 			   struct radv_shader_module *module,
 			   const char *entrypoint_name,
 			   gl_shader_stage stage,
 			   const VkSpecializationInfo *spec_info);
 
 void *
 radv_alloc_shader_memory(struct radv_device *device,
 			  struct radv_shader_variant *shader);
-- 
2.13.6



More information about the mesa-dev mailing list