st/nir: Optionally unify inputs_read/outputs_written when linking.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 17 Jun 2019 22:10:06 +0000 (17:10 -0500)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 3 Jan 2020 00:41:50 +0000 (00:41 +0000)
i965 and iris use inputs_read/outputs_written for a shader stage to
determine the layout of input and output storage.  Adjacent stages must
agree on the layout, so adjacent input/output bitfields must match.

This patch adds a new nir_shader_compiler_options::unify_interfaces
flag which asks the linker to unify the input/output interfaces between
adjacent stages.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3249>

src/compiler/nir/nir.h
src/mesa/state_tracker/st_glsl_to_nir.cpp

index 53305ae714814848b450eee397d7fa076037c73d..976fc59bff1c61b42031018ad2a9bcd30989eaa9 100644 (file)
@@ -2839,6 +2839,12 @@ typedef struct nir_shader_compiler_options {
    bool vectorize_io;
    bool lower_to_scalar;
 
+   /**
+    * Should the linker unify inputs_read/outputs_written between adjacent
+    * shader stages which are linked into a single program?
+    */
+   bool unify_interfaces;
+
    /**
     * Should nir_lower_io() create load_interpolated_input intrinsics?
     *
index e4b509ba7a7cd980a1769560fee4987266aeacd6..322143d1e7bcc0766b1e92142e9315929a340089 100644 (file)
@@ -813,6 +813,28 @@ st_link_nir(struct gl_context *ctx,
       shader->ir = NULL;
    }
 
+   struct shader_info *prev_info = NULL;
+
+   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+      struct gl_linked_shader *shader = shader_program->_LinkedShaders[i];
+      if (!shader)
+         continue;
+
+      struct shader_info *info = &shader->Program->nir->info;
+
+      if (prev_info &&
+          ctx->Const.ShaderCompilerOptions[i].NirOptions->unify_interfaces) {
+         prev_info->outputs_written |= info->inputs_read &
+            ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
+         info->inputs_read |= prev_info->outputs_written &
+            ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
+
+         prev_info->patch_outputs_written |= info->patch_inputs_read;
+         info->patch_inputs_read |= prev_info->patch_outputs_written;
+      }
+      prev_info = info;
+   }
+
    return true;
 }