[Mesa-dev] [PATCH 20/22] nir: Add handle/index-based image intrinsics

Jason Ekstrand jason at jlekstrand.net
Fri Aug 17 20:06:26 UTC 2018


---
 src/compiler/nir/nir.h             | 30 +++++++++++++++++--
 src/compiler/nir/nir_intrinsics.py | 48 +++++++++++++++++++-----------
 src/compiler/nir/nir_print.c       | 22 ++++++++++++++
 3 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 55e48bbb693..b88e6fc5834 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1049,7 +1049,7 @@ typedef struct {
 
 #include "nir_intrinsics.h"
 
-#define NIR_INTRINSIC_MAX_CONST_INDEX 3
+#define NIR_INTRINSIC_MAX_CONST_INDEX 4
 
 /** Represents an intrinsic
  *
@@ -1197,6 +1197,28 @@ typedef enum {
     */
    NIR_INTRINSIC_PARAM_IDX = 12,
 
+   /**
+    * Image dimensionality for image intrinsics
+    *
+    * One of GLSL_SAMPLER_DIM_*
+    */
+   NIR_INTRINSIC_IMAGE_DIM = 13,
+
+   /**
+    * Non-zero if we are accessing an array image
+    */
+   NIR_INTRINSIC_IMAGE_ARRAY = 14,
+
+   /**
+    * Image format for image intrinsics
+    */
+   NIR_INTRINSIC_FORMAT = 15,
+
+   /**
+    * Access qualifiers for image intrinsics
+    */
+   NIR_INTRINSIC_ACCESS = 16,
+
    NIR_INTRINSIC_NUM_INDEX_FLAGS,
 
 } nir_intrinsic_index_flag;
@@ -1265,7 +1287,7 @@ nir_intrinsic_##name(const nir_intrinsic_instr *instr)                        \
 {                                                                             \
    const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];   \
    assert(info->index_map[NIR_INTRINSIC_##flag] > 0);                         \
-   return instr->const_index[info->index_map[NIR_INTRINSIC_##flag] - 1];      \
+   return (type)instr->const_index[info->index_map[NIR_INTRINSIC_##flag] - 1]; \
 }                                                                             \
 static inline void                                                            \
 nir_intrinsic_set_##name(nir_intrinsic_instr *instr, type val)                \
@@ -1287,6 +1309,10 @@ INTRINSIC_IDX_ACCESSORS(interp_mode, INTERP_MODE, unsigned)
 INTRINSIC_IDX_ACCESSORS(reduction_op, REDUCTION_OP, unsigned)
 INTRINSIC_IDX_ACCESSORS(cluster_size, CLUSTER_SIZE, unsigned)
 INTRINSIC_IDX_ACCESSORS(param_idx, PARAM_IDX, unsigned)
+INTRINSIC_IDX_ACCESSORS(image_dim, IMAGE_DIM, enum glsl_sampler_dim)
+INTRINSIC_IDX_ACCESSORS(image_array, IMAGE_ARRAY, bool)
+INTRINSIC_IDX_ACCESSORS(access, ACCESS, enum gl_access_qualifier)
+INTRINSIC_IDX_ACCESSORS(format, FORMAT, unsigned)
 
 /**
  * \group texture information
diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py
index 45872e00c55..0dae37ae886 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -101,6 +101,14 @@ REDUCTION_OP = "NIR_INTRINSIC_REDUCTION_OP"
 CLUSTER_SIZE = "NIR_INTRINSIC_CLUSTER_SIZE"
 # Parameter index for a load_param intrinsic
 PARAM_IDX = "NIR_INTRINSIC_PARAM_IDX"
+# Image dimensionality for image intrinsics
+IMAGE_DIM = "NIR_INTRINSIC_IMAGE_DIM"
+# Non-zero if we are accessing an array image
+IMAGE_ARRAY = "NIR_INTRINSIC_IMAGE_ARRAY"
+# Access qualifiers for image intrinsics
+ACCESS = "NIR_INTRINSIC_ACCESS"
+# Image format for image intrinsics
+FORMAT = "NIR_INTRINSIC_FORMAT"
 
 #
 # Possible flags:
@@ -284,10 +292,12 @@ atomic3("atomic_counter_comp_swap")
 
 # 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 come in two versions.  One which take an image target
+# passed as a deref chain as the first source and one which takes an index or
+# handle as the first source.  In the first version, the image variable
+# contains the memory and layout qualifiers that influence the semantics of
+# the intrinsic.  In the second, the image format and access qualifiers are
+# provided as constant indices.
 #
 # All image intrinsics take a four-coordinate vector and a sample index as
 # 2nd and 3rd sources, determining the location within the image that will be
@@ -296,19 +306,23 @@ atomic3("atomic_counter_comp_swap")
 # 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", src_comp=[1, 4, 1], dest_comp=0,
-          flags=[CAN_ELIMINATE])
-intrinsic("image_deref_store", src_comp=[1, 4, 1, 0])
-intrinsic("image_deref_atomic_add",  src_comp=[1, 4, 1, 1], dest_comp=1)
-intrinsic("image_deref_atomic_min",  src_comp=[1, 4, 1, 1], dest_comp=1)
-intrinsic("image_deref_atomic_max",  src_comp=[1, 4, 1, 1], dest_comp=1)
-intrinsic("image_deref_atomic_and",  src_comp=[1, 4, 1, 1], dest_comp=1)
-intrinsic("image_deref_atomic_or",   src_comp=[1, 4, 1, 1], dest_comp=1)
-intrinsic("image_deref_atomic_xor",  src_comp=[1, 4, 1, 1], dest_comp=1)
-intrinsic("image_deref_atomic_exchange",  src_comp=[1, 4, 1, 1], dest_comp=1)
-intrinsic("image_deref_atomic_comp_swap", src_comp=[1, 4, 1, 1, 1], dest_comp=1)
-intrinsic("image_deref_size",    src_comp=[1], dest_comp=0, flags=[CAN_ELIMINATE, CAN_REORDER])
-intrinsic("image_deref_samples", src_comp=[1], dest_comp=1, flags=[CAN_ELIMINATE, CAN_REORDER])
+def image(name, src_comp=[], **kwargs):
+    intrinsic("image_deref_" + name, src_comp=[1] + src_comp, **kwargs)
+    intrinsic("image_" + name, src_comp=[1] + src_comp,
+              indices=[IMAGE_DIM, IMAGE_ARRAY, FORMAT, ACCESS], **kwargs)
+
+image("load", src_comp=[4, 1], dest_comp=0, flags=[CAN_ELIMINATE])
+image("store", src_comp=[4, 1, 0])
+image("atomic_add",  src_comp=[4, 1, 1], dest_comp=1)
+image("atomic_min",  src_comp=[4, 1, 1], dest_comp=1)
+image("atomic_max",  src_comp=[4, 1, 1], dest_comp=1)
+image("atomic_and",  src_comp=[4, 1, 1], dest_comp=1)
+image("atomic_or",   src_comp=[4, 1, 1], dest_comp=1)
+image("atomic_xor",  src_comp=[4, 1, 1], dest_comp=1)
+image("atomic_exchange",  src_comp=[4, 1, 1], dest_comp=1)
+image("atomic_comp_swap", src_comp=[4, 1, 1, 1], dest_comp=1)
+image("size",    dest_comp=0, flags=[CAN_ELIMINATE, CAN_REORDER])
+image("samples", dest_comp=1, flags=[CAN_ELIMINATE, CAN_REORDER])
 
 # Intel-specific query for loading from the brw_image_param struct passed
 # into the shader as a uniform.  The variable is a deref to the image
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index 9175560383f..19f26f46405 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -687,6 +687,10 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
       [NIR_INTRINSIC_REDUCTION_OP] = "reduction_op",
       [NIR_INTRINSIC_CLUSTER_SIZE] = "cluster_size",
       [NIR_INTRINSIC_PARAM_IDX] = "param_idx",
+      [NIR_INTRINSIC_IMAGE_DIM] = "image_dim",
+      [NIR_INTRINSIC_IMAGE_ARRAY] = "image_array",
+      [NIR_INTRINSIC_ACCESS] = "access",
+      [NIR_INTRINSIC_FORMAT] = "format",
    };
    for (unsigned idx = 1; idx < NIR_INTRINSIC_NUM_INDEX_FLAGS; idx++) {
       if (!info->index_map[idx])
@@ -702,6 +706,24 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
       } else if (idx == NIR_INTRINSIC_REDUCTION_OP) {
          nir_op reduction_op = nir_intrinsic_reduction_op(instr);
          fprintf(fp, " reduction_op=%s", nir_op_infos[reduction_op].name);
+      } else if (idx == NIR_INTRINSIC_IMAGE_DIM) {
+         static const char *dim_name[] = {
+            [GLSL_SAMPLER_DIM_1D] = "1D",
+            [GLSL_SAMPLER_DIM_2D] = "2D",
+            [GLSL_SAMPLER_DIM_3D] = "3D",
+            [GLSL_SAMPLER_DIM_CUBE] = "Cube",
+            [GLSL_SAMPLER_DIM_RECT] = "Rect",
+            [GLSL_SAMPLER_DIM_BUF] = "Buf",
+            [GLSL_SAMPLER_DIM_MS] = "2D-MSAA",
+            [GLSL_SAMPLER_DIM_SUBPASS] = "Subpass",
+            [GLSL_SAMPLER_DIM_SUBPASS_MS] = "Subpass-MSAA",
+         };
+         enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
+         assert(dim < ARRAY_SIZE(dim_name) && dim_name[idx]);
+         fprintf(fp, " image_dim=%s", dim_name[dim]);
+      } else if (idx == NIR_INTRINSIC_IMAGE_ARRAY) {
+         bool array = nir_intrinsic_image_dim(instr);
+         fprintf(fp, " image_dim=%s", array ? "true" : "false");
       } else {
          unsigned off = info->index_map[idx] - 1;
          assert(index_name[idx]);  /* forgot to update index_name table? */
-- 
2.17.1



More information about the mesa-dev mailing list