[12/15] nir/spirv: add spirv_to_nir_cl

Submitted by Karol Herbst on May 11, 2019, 2:07 p.m.

Details

Message ID 20190511140712.27095-13-kherbst@redhat.com
State New
Headers show
Series "Clover: support CL through SPIR-V" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Karol Herbst May 11, 2019, 2:07 p.m.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
---
 src/compiler/Makefile.sources        |   1 +
 src/compiler/nir/meson.build         |   1 +
 src/compiler/spirv/nir_spirv.h       |   4 +
 src/compiler/spirv/spirv_to_nir_cl.c | 124 +++++++++++++++++++++++++++
 4 files changed, 130 insertions(+)
 create mode 100644 src/compiler/spirv/spirv_to_nir_cl.c

Patch hide | download patch | download mbox

diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index 1b6dc25f1ed..6265bdca359 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -346,6 +346,7 @@  SPIRV_FILES = \
 	spirv/spirv.h \
 	spirv/spirv_info.h \
 	spirv/spirv_to_nir.c \
+	spirv/spirv_to_nir_cl.c \
 	spirv/vtn_alu.c \
 	spirv/vtn_amd.c \
 	spirv/vtn_cfg.c \
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
index 69de4121a73..d115022d134 100644
--- a/src/compiler/nir/meson.build
+++ b/src/compiler/nir/meson.build
@@ -221,6 +221,7 @@  files_libnir = files(
   '../spirv/spirv.h',
   '../spirv/spirv_info.h',
   '../spirv/spirv_to_nir.c',
+  '../spirv/spirv_to_nir_cl.c',
   '../spirv/vtn_alu.c',
   '../spirv/vtn_amd.c',
   '../spirv/vtn_cfg.c',
diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 7a16422b291..1ce7cbaf998 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -101,6 +101,10 @@  nir_function *spirv_to_nir(const uint32_t *words, size_t word_count,
                            const struct spirv_to_nir_options *options,
                            const nir_shader_compiler_options *nir_options);
 
+nir_shader * spirv_to_nir_cl(const uint32_t *words, size_t word_count,
+                             const char *entry_point_name,
+                             const nir_shader_compiler_options *nir_options);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/compiler/spirv/spirv_to_nir_cl.c b/src/compiler/spirv/spirv_to_nir_cl.c
new file mode 100644
index 00000000000..de9bcaf0d20
--- /dev/null
+++ b/src/compiler/spirv/spirv_to_nir_cl.c
@@ -0,0 +1,124 @@ 
+/*
+ * Copyright © 2019 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Karol Herbst (kherbst@redhat.com)
+ *
+ */
+
+#include "util/u_math.h"
+
+#include "nir/nir.h"
+#include "spirv/nir_spirv.h"
+
+nir_shader *
+spirv_to_nir_cl(const uint32_t *words, size_t word_count,
+                const char *entry_point_name,
+                const nir_shader_compiler_options *nir_options)
+{
+   struct spirv_to_nir_options spirv_options = {
+      .caps = {
+         .address = true,
+         .float64 = true,
+         .int8 = true,
+         .int16 = true,
+         .int64 = true,
+         .kernel = true,
+      },
+   };
+
+   nir_function *entry_point =
+      spirv_to_nir(words, word_count, NULL, 0, MESA_SHADER_KERNEL,
+                   entry_point_name, &spirv_options, nir_options);
+
+   if (!entry_point)
+      return NULL;
+
+   nir_shader *nir = entry_point->shader;
+   nir->info.cs.local_size_variable = true;
+
+   nir_validate_shader(nir, "clover");
+
+   /* calculate input offsets */
+   unsigned offset = 0;
+   nir_foreach_variable_safe(var, &nir->inputs) {
+      offset = align(offset, glsl_get_cl_alignment(var->type));
+      var->data.driver_location = offset;
+      offset += glsl_get_cl_size(var->type);
+   }
+
+   /* inline all functions first */
+   NIR_PASS_V(nir, nir_lower_constant_initializers,
+              (nir_variable_mode)(nir_var_function_temp));
+   NIR_PASS_V(nir, nir_lower_returns);
+   NIR_PASS_V(nir, nir_inline_functions);
+   NIR_PASS_V(nir, nir_copy_prop);
+
+   /* Pick off the single entrypoint that we want */
+   foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
+      if (func != entry_point)
+         exec_node_remove(&func->node);
+   }
+   assert(exec_list_length(&nir->functions) == 1);
+
+   nir_validate_shader(nir, "clover after function inlining");
+
+   NIR_PASS_V(nir, nir_lower_global_vars_to_local);
+   NIR_PASS_V(nir, nir_lower_system_values);
+   NIR_PASS_V(nir, nir_lower_global_vars_to_local);
+
+   bool progress;
+   do {
+      progress = false;
+      NIR_PASS(progress, nir, nir_opt_find_array_copies);
+      NIR_PASS(progress, nir, nir_opt_deref);
+      NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
+      NIR_PASS(progress, nir, nir_opt_dce);
+      NIR_PASS(progress, nir, nir_split_var_copies);
+      NIR_PASS(progress, nir, nir_lower_var_copies);
+      NIR_PASS(progress, nir, nir_opt_dead_write_vars);
+
+      if (nir_options->lower_all_io_to_temps)
+         NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
+
+      NIR_PASS(progress, nir, nir_lower_constant_initializers,
+               (nir_variable_mode)(~0));
+      NIR_PASS(progress, nir, nir_copy_prop);
+      NIR_PASS(progress, nir, nir_opt_dce);
+      NIR_PASS(progress, nir, nir_opt_cse);
+      NIR_PASS(progress, nir, nir_opt_dead_cf);
+      NIR_PASS(progress, nir, nir_opt_if, false);
+   } while (progress);
+
+   NIR_PASS_V(nir, nir_remove_dead_variables, (nir_variable_mode)(~0));
+   NIR_PASS_V(nir, nir_propagate_invariant);
+
+   nir_variable_mode modes = (nir_variable_mode)(
+      nir_var_shader_in |
+      nir_var_mem_global |
+      nir_var_mem_shared);
+   nir_address_format format = nir->info.cs.ptr_size == 64 ?
+      nir_address_format_64bit_global : nir_address_format_32bit_global;
+   NIR_PASS_V(nir, nir_lower_explicit_io, modes, format);
+
+   return nir;
+}