radv: Link shaders.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Wed, 8 Feb 2017 23:12:10 +0000 (00:12 +0100)
committerTimothy Arceri <tarceri@itsqueeze.com>
Tue, 17 Oct 2017 22:19:35 +0000 (09:19 +1100)
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@google.com>
Signed-off-by: Timothy Arceri <tarceri@itsqueeze.com>
Acked-by: Dave Airlie <airlied@redhat.com>
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_shader.c
src/amd/vulkan/radv_shader.h

index e95925f..5598626 100644 (file)
@@ -1522,6 +1522,46 @@ static void calculate_ps_inputs(struct radv_pipeline *pipeline)
        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,
@@ -1588,6 +1628,8 @@ void radv_create_shaders(struct radv_pipeline *pipeline,
                nir_lower_tes_patch_vertices(nir[MESA_SHADER_TESS_EVAL], nir[MESA_SHADER_TESS_CTRL]->info.tess.tcs_vertices_out);
        }
 
+       radv_link_shaders(pipeline, nir);
+
        if (nir[MESA_SHADER_FRAGMENT]) {
                pipeline->shaders[MESA_SHADER_FRAGMENT] =
                        radv_shader_variant_create(device, modules[MESA_SHADER_FRAGMENT], nir[MESA_SHADER_FRAGMENT],
index d4bef97..055787a 100644 (file)
@@ -110,7 +110,7 @@ void radv_DestroyShaderModule(
        vk_free2(&device->alloc, pAllocator, module);
 }
 
-static void
+void
 radv_optimize_nir(struct nir_shader *shader)
 {
         bool progress;
index 1ef1396..3862b30 100644 (file)
@@ -67,6 +67,9 @@ struct radv_shader_slab {
        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,