[Mesa-dev] [PATCH 09/61] nir: Add _deref versions of all of the _var intrinsics

Jason Ekstrand jason at jlekstrand.net
Fri Mar 23 21:42:15 UTC 2018


---
 src/compiler/nir/nir.h            |  2 +-
 src/compiler/nir/nir_builder.h    | 37 +++++++++++++++++
 src/compiler/nir/nir_intrinsics.h | 84 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index b02c241..591d53e 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1164,7 +1164,7 @@ typedef enum {
 
 } nir_intrinsic_index_flag;
 
-#define NIR_INTRINSIC_MAX_INPUTS 4
+#define NIR_INTRINSIC_MAX_INPUTS 5
 
 typedef struct {
    const char *name;
diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
index 66f705b..0513e31 100644
--- a/src/compiler/nir/nir_builder.h
+++ b/src/compiler/nir/nir_builder.h
@@ -632,6 +632,43 @@ nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent,
 }
 
 static inline nir_ssa_def *
+nir_load_deref(nir_builder *build, nir_deref_instr *deref)
+{
+   nir_intrinsic_instr *load =
+      nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_deref);
+   load->num_components = glsl_get_vector_elements(deref->type);
+   load->src[0] = nir_src_for_ssa(&deref->dest.ssa);
+   nir_ssa_dest_init(&load->instr, &load->dest, load->num_components,
+                     glsl_get_bit_size(deref->type), NULL);
+   nir_builder_instr_insert(build, &load->instr);
+   return &load->dest.ssa;
+}
+
+static inline void
+nir_store_deref(nir_builder *build, nir_deref_instr *deref,
+                nir_ssa_def *value, unsigned writemask)
+{
+   nir_intrinsic_instr *store =
+      nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_deref);
+   store->num_components = glsl_get_vector_elements(deref->type);
+   store->src[0] = nir_src_for_ssa(&deref->dest.ssa);
+   store->src[1] = nir_src_for_ssa(value);
+   nir_intrinsic_set_write_mask(store,
+                                writemask & ((1 << store->num_components) - 1));
+   nir_builder_instr_insert(build, &store->instr);
+}
+
+static inline void
+nir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src)
+{
+   nir_intrinsic_instr *copy =
+      nir_intrinsic_instr_create(build->shader, nir_intrinsic_copy_deref);
+   copy->src[0] = nir_src_for_ssa(&dest->dest.ssa);
+   copy->src[1] = nir_src_for_ssa(&src->dest.ssa);
+   nir_builder_instr_insert(build, &copy->instr);
+}
+
+static inline nir_ssa_def *
 nir_load_var(nir_builder *build, nir_variable *var)
 {
    const unsigned num_components = glsl_get_vector_elements(var->type);
diff --git a/src/compiler/nir/nir_intrinsics.h b/src/compiler/nir/nir_intrinsics.h
index 8f3d3bc..c14a9ef 100644
--- a/src/compiler/nir/nir_intrinsics.h
+++ b/src/compiler/nir/nir_intrinsics.h
@@ -49,6 +49,14 @@ INTRINSIC(store_var, 1, ARR(0), false, 0, 1, 1, WRMASK, xx, xx, 0)
 INTRINSIC(copy_var, 0, ARR(0), false, 0, 2, 0, xx, xx, xx, 0)
 
 /*
+ * Pointer versions of the _var intrinsics which take a deref as the first (or
+ * second, in the case of copy) source.
+ */
+INTRINSIC(load_deref, 1, ARR(1), true, 0, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE)
+INTRINSIC(store_deref, 2, ARR(1, 0), false, 0, 0, 1, WRMASK, xx, xx, 0)
+INTRINSIC(copy_deref, 2, ARR(1, 1), false, 0, 0, 0, xx, xx, xx, 0)
+
+/*
  * Interpolation of input.  The interp_var_at* intrinsics are similar to the
  * load_var intrinsic acting on a shader input except that they interpolate
  * the input differently.  The at_sample and at_offset intrinsics take an
@@ -64,6 +72,21 @@ INTRINSIC(interp_var_at_offset, 1, ARR(2), true, 0, 1, 0, xx, xx, xx,
           NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 
 /*
+ * Interpolation of input.  The interp_deref_at* intrinsics are similar to the
+ * load_deref intrinsic acting on a shader input except that they interpolate
+ * the input differently.  The at_sample and at_offset intrinsics take an
+ * additional source that is an integer sample id or a vec2 position offset
+ * respectively.
+ */
+
+INTRINSIC(interp_deref_at_centroid, 1, ARR(1, 0), true, 0, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+INTRINSIC(interp_deref_at_sample, 2, ARR(1, 1), true, 0, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+INTRINSIC(interp_deref_at_offset, 2, ARR(1, 2), true, 0, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+
+/*
  * Ask the driver for the size of a given buffer. It takes the buffer index
  * as source.
  */
@@ -217,12 +240,15 @@ INTRINSIC(set_vertex_count, 1, ARR(1), false, 0, 0, 0, xx, xx, xx, 0)
 
 #define ATOMIC(name, flags) \
    INTRINSIC(name##_var, 0, ARR(0), true, 1, 1, 0, xx, xx, xx, flags) \
+   INTRINSIC(name##_deref, 1, ARR(1), true, 1, 0, 0, xx, xx, xx, flags) \
    INTRINSIC(name, 1, ARR(1), true, 1, 0, 1, BASE, xx, xx, flags)
 #define ATOMIC2(name) \
    INTRINSIC(name##_var, 1, ARR(1), true, 1, 1, 0, xx, xx, xx, 0) \
+   INTRINSIC(name##_deref, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0) \
    INTRINSIC(name, 2, ARR(1, 1), true, 1, 0, 1, BASE, xx, xx, 0)
 #define ATOMIC3(name) \
    INTRINSIC(name##_var, 2, ARR(1, 1), true, 1, 1, 0, xx, xx, xx, 0) \
+   INTRINSIC(name##_deref, 3, ARR(1, 1, 1), true, 1, 0, 0, xx, xx, xx, 0) \
    INTRINSIC(name, 3, ARR(1, 1, 1), true, 1, 0, 1, BASE, xx, xx, 0)
 
 ATOMIC(atomic_counter_inc, 0)
@@ -269,6 +295,38 @@ INTRINSIC(image_var_samples, 0, ARR(0), true, 1, 1, 0, xx, xx, xx,
           NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 
 /*
+ * Image load, store and atomic intrinsics.
+ *
+ * All image intrinsics take an image target passed as a nir_variable.  The
+ * variable is passed in using a chain of nir_deref_instr with as the first
+ * source of the image intrinsic.  Image variables contain a number of memory
+ * and layout qualifiers that influence the semantics of the intrinsic.
+ *
+ * All image intrinsics take a four-coordinate vector and a sample index as
+ * first two sources, determining the location within the image that will be
+ * accessed by the intrinsic.  Components not applicable to the image target
+ * in use are undefined.  Image store takes an additional four-component
+ * argument with the value to be written, and image atomic operations take
+ * either one or two additional scalar arguments with the same meaning as in
+ * the ARB_shader_image_load_store specification.
+ */
+INTRINSIC(image_deref_load, 3, ARR(1, 4, 1), true, 4, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE)
+INTRINSIC(image_deref_store, 4, ARR(1, 4, 1, 4), false, 0, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_add, 4, ARR(1, 4, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_min, 4, ARR(1, 4, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_max, 4, ARR(1, 4, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_and, 4, ARR(1, 4, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_or, 4, ARR(1, 4, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_xor, 4, ARR(1, 4, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_exchange, 4, ARR(1, 4, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_atomic_comp_swap, 5, ARR(1, 4, 1, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(image_deref_size, 1, ARR(1), true, 0, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+INTRINSIC(image_deref_samples, 1, ARR(1), true, 1, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+
+/*
  * Vulkan descriptor set intrinsics
  *
  * The Vulkan API uses a different binding model from GL.  In the Vulkan
@@ -323,6 +381,32 @@ INTRINSIC(var_atomic_exchange, 1, ARR(1), true, 1, 1, 0, xx, xx, xx, 0)
 INTRINSIC(var_atomic_comp_swap, 2, ARR(1, 1), true, 1, 1, 0, xx, xx, xx, 0)
 
 /*
+ * deref atomic intrinsics
+ *
+ * All of these deref atomic memory operations read a value from memory,
+ * compute a new value using one of the operations below, write the new value
+ * to memory, and return the original value read.
+ *
+ * All operations take 2 sources except CompSwap that takes 3. These sources
+ * represent:
+ *
+ * 0: A deref to the memory on which to perform the atomic
+ * 1: The data parameter to the atomic function (i.e. the value to add
+ *    in shared_atomic_add, etc).
+ * 2: For CompSwap only: the second data parameter.
+ */
+INTRINSIC(deref_atomic_add, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_imin, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_umin, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_imax, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_umax, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_and, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_or, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_xor, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_exchange, 2, ARR(1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+INTRINSIC(deref_atomic_comp_swap, 3, ARR(1, 1, 1), true, 1, 0, 0, xx, xx, xx, 0)
+
+/*
  * SSBO atomic intrinsics
  *
  * All of the SSBO atomic memory operations read a value from memory,
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list