Module: Mesa
Branch: master
Commit: bafd2591771bae092edba95b2f4913b303b1668b
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=bafd2591771bae092edba95b2f4913b303b1668b

Author: Neil Roberts <[email protected]>
Date:   Fri Jul 17 09:24:02 2020 +0200

nir/schedule: Add a callback for backend-specific dependencies

Adds a callback function to nir_schedule_options to give the backend a
chance to add custom dependencies between certain intrinsics. The
callback can assign a class number to the intrinsic and then set a read
or write dependency on that class.

v2: Use a linked-list of schedule nodes for the dependency classes
    instead of a fixed-sized array.

Reviewed-by: Iago Toral Quiroga <[email protected]>
Reviewed-by: Alejandro PiƱeiro <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5953>

---

 src/compiler/nir/nir_schedule.c | 48 +++++++++++++++++++++++++++++++++++++++++
 src/compiler/nir/nir_schedule.h | 26 ++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/src/compiler/nir/nir_schedule.c b/src/compiler/nir/nir_schedule.c
index 1db808fc1cc..9082278d671 100644
--- a/src/compiler/nir/nir_schedule.c
+++ b/src/compiler/nir/nir_schedule.c
@@ -119,6 +119,12 @@ typedef struct {
  */
 enum direction { F, R };
 
+struct nir_schedule_class_dep {
+   int klass;
+   nir_schedule_node *node;
+   struct nir_schedule_class_dep *next;
+};
+
 typedef struct {
    nir_schedule_scoreboard *scoreboard;
 
@@ -133,6 +139,8 @@ typedef struct {
    nir_schedule_node *discard;
    nir_schedule_node *jump;
 
+   struct nir_schedule_class_dep *class_deps;
+
    enum direction dir;
 } nir_deps_state;
 
@@ -292,12 +300,52 @@ nir_schedule_ssa_deps(nir_ssa_def *def, void *in_state)
    return true;
 }
 
+static struct nir_schedule_class_dep *
+nir_schedule_get_class_dep(nir_deps_state *state,
+                           int klass)
+{
+   for (struct nir_schedule_class_dep *class_dep = state->class_deps;
+        class_dep != NULL;
+        class_dep = class_dep->next) {
+      if (class_dep->klass == klass)
+         return class_dep;
+   }
+
+   struct nir_schedule_class_dep *class_dep =
+      ralloc(state->reg_map, struct nir_schedule_class_dep);
+
+   class_dep->klass = klass;
+   class_dep->node = NULL;
+   class_dep->next = state->class_deps;
+
+   state->class_deps = class_dep;
+
+   return class_dep;
+}
+
 static void
 nir_schedule_intrinsic_deps(nir_deps_state *state,
                             nir_intrinsic_instr *instr)
 {
    nir_schedule_node *n = nir_schedule_get_node(state->scoreboard->instr_map,
                                                 &instr->instr);
+   const nir_schedule_options *options = state->scoreboard->options;
+   nir_schedule_dependency dep;
+
+   if (options->intrinsic_cb &&
+       options->intrinsic_cb(instr, &dep, options->intrinsic_cb_data)) {
+      struct nir_schedule_class_dep *class_dep =
+         nir_schedule_get_class_dep(state, dep.klass);
+
+      switch (dep.type) {
+      case NIR_SCHEDULE_READ_DEPENDENCY:
+         add_read_dep(state, class_dep->node, n);
+         break;
+      case NIR_SCHEDULE_WRITE_DEPENDENCY:
+         add_write_dep(state, &class_dep->node, n);
+         break;
+      }
+   }
 
    switch (instr->intrinsic) {
    case nir_intrinsic_load_uniform:
diff --git a/src/compiler/nir/nir_schedule.h b/src/compiler/nir/nir_schedule.h
index 030077a87c8..98c92a6b46c 100644
--- a/src/compiler/nir/nir_schedule.h
+++ b/src/compiler/nir/nir_schedule.h
@@ -30,6 +30,23 @@
 extern "C" {
 #endif
 
+/**
+ * Struct filled in by the intrinsic_cb callback of nir_schedule_options to
+ * specify a backend-specific dependency on an intrinsic.
+ */
+typedef struct nir_schedule_dependency {
+   /* Which class of dependency this is. The meanings of the classes are
+    * specific to the backend. This must be less than
+    * NIR_SCHEDULE_N_DEPENDENCY_CLASSES.
+    */
+   int klass;
+   /* The type of dependency */
+   enum {
+      NIR_SCHEDULE_READ_DEPENDENCY,
+      NIR_SCHEDULE_WRITE_DEPENDENCY,
+   } type;
+} nir_schedule_dependency;
+
 typedef struct nir_schedule_options {
    /* On some hardware with some stages the inputs and outputs to the shader
     * share the same memory. In that case the scheduler needs to ensure that
@@ -41,6 +58,15 @@ typedef struct nir_schedule_options {
     * will try to reduce register usage.
     */
    int threshold;
+   /* Callback used to add custom dependencies on intrinsics. If it returns
+    * true then a dependency should be added and dep is filled in to describe
+    * it.
+    */
+   bool (* intrinsic_cb)(nir_intrinsic_instr *intr,
+                         nir_schedule_dependency *dep,
+                         void *user_data);
+   /* Data to pass to the callback */
+   void *intrinsic_cb_data;
 } nir_schedule_options;
 
 void nir_schedule(nir_shader *shader, const nir_schedule_options *options);

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to