nir: Allow qualifiers on copy_deref and image instructions
authorConnor Abbott <cwabbott0@gmail.com>
Tue, 4 Jun 2019 09:40:14 +0000 (11:40 +0200)
committerConnor Abbott <cwabbott0@gmail.com>
Wed, 19 Jun 2019 12:08:27 +0000 (14:08 +0200)
In the next commit, we'll properly handle access qualifiers on struct
members by propagating them to load/store instructions, but these
instructions had no way to specify the qualifier.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/compiler/nir/nir.h
src/compiler/nir/nir_builder.h
src/compiler/nir/nir_intrinsics.py
src/compiler/nir/nir_lower_var_copies.c
src/compiler/nir/nir_print.c
src/compiler/nir/nir_split_var_copies.c

index 6b2ebcab6fb7bdd281e4b61944405fc4e82a3eb0..3977e75dc4b2ce6c893804566ee2611d807ef48a 100644 (file)
@@ -1312,6 +1312,10 @@ typedef enum {
     */
    NIR_INTRINSIC_SWIZZLE_MASK,
 
+   /* Separate source/dest access flags for copies */
+   NIR_INTRINSIC_SRC_ACCESS = 21,
+   NIR_INTRINSIC_DST_ACCESS = 22,
+
    NIR_INTRINSIC_NUM_INDEX_FLAGS,
 
 } nir_intrinsic_index_flag;
@@ -1412,6 +1416,8 @@ 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(src_access, SRC_ACCESS, enum gl_access_qualifier)
+INTRINSIC_IDX_ACCESSORS(dst_access, DST_ACCESS, enum gl_access_qualifier)
 INTRINSIC_IDX_ACCESSORS(format, FORMAT, unsigned)
 INTRINSIC_IDX_ACCESSORS(align_mul, ALIGN_MUL, unsigned)
 INTRINSIC_IDX_ACCESSORS(align_offset, ALIGN_OFFSET, unsigned)
index 8ca776f733efacdbc6ac38568909ea0e2dc2e21e..cef84a8914ece1bff33ddeb5c4fda2b7aa755702 100644 (file)
@@ -1120,15 +1120,28 @@ nir_store_deref(nir_builder *build, nir_deref_instr *deref,
 }
 
 static inline void
-nir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src)
+nir_copy_deref_with_access(nir_builder *build, nir_deref_instr *dest,
+                           nir_deref_instr *src,
+                           enum gl_access_qualifier dest_access,
+                           enum gl_access_qualifier src_access)
 {
    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_intrinsic_set_dst_access(copy, dest_access);
+   nir_intrinsic_set_src_access(copy, src_access);
    nir_builder_instr_insert(build, &copy->instr);
 }
 
+static inline void
+nir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src)
+{
+   nir_copy_deref_with_access(build, dest, src,
+                              (enum gl_access_qualifier) 0,
+                              (enum gl_access_qualifier) 0);
+}
+
 static inline nir_ssa_def *
 nir_load_var(nir_builder *build, nir_variable *var)
 {
index 155a548d1b881a45e1bfe2c62572a331042a9092..c9d0a236c5a72c169d4932a25ab62c16f5507c3d 100644 (file)
@@ -111,6 +111,8 @@ IMAGE_DIM = "NIR_INTRINSIC_IMAGE_DIM"
 IMAGE_ARRAY = "NIR_INTRINSIC_IMAGE_ARRAY"
 # Access qualifiers for image and memory access intrinsics
 ACCESS = "NIR_INTRINSIC_ACCESS"
+DST_ACCESS = "NIR_INTRINSIC_DST_ACCESS"
+SRC_ACCESS = "NIR_INTRINSIC_SRC_ACCESS"
 # Image format for image intrinsics
 FORMAT = "NIR_INTRINSIC_FORMAT"
 # Offset or address alignment
@@ -156,7 +158,7 @@ intrinsic("load_param", dest_comp=0, indices=[PARAM_IDX], flags=[CAN_ELIMINATE])
 intrinsic("load_deref", dest_comp=0, src_comp=[-1],
           indices=[ACCESS], flags=[CAN_ELIMINATE])
 intrinsic("store_deref", src_comp=[-1, 0], indices=[WRMASK, ACCESS])
-intrinsic("copy_deref", src_comp=[-1, -1])
+intrinsic("copy_deref", src_comp=[-1, -1], indices=[DST_ACCESS, SRC_ACCESS])
 
 # Interpolation of input.  The interp_deref_at* intrinsics are similar to the
 # load_var intrinsic acting on a shader input except that they interpolate the
@@ -345,7 +347,8 @@ atomic3("atomic_counter_comp_swap")
 # either one or two additional scalar arguments with the same meaning as in
 # the ARB_shader_image_load_store specification.
 def image(name, src_comp=[], **kwargs):
-    intrinsic("image_deref_" + name, src_comp=[1] + src_comp, **kwargs)
+    intrinsic("image_deref_" + name, src_comp=[1] + src_comp,
+              indices=[ACCESS], **kwargs)
     intrinsic("image_" + name, src_comp=[1] + src_comp,
               indices=[IMAGE_DIM, IMAGE_ARRAY, FORMAT, ACCESS], **kwargs)
     intrinsic("bindless_image_" + name, src_comp=[1] + src_comp,
index 0ba398698f0dd9d0fa24f962bd4156a632fb6e96..e6ade733ebace512711c207443016cd133aba7c7 100644 (file)
@@ -56,7 +56,9 @@ emit_deref_copy_load_store(nir_builder *b,
                            nir_deref_instr *dst_deref,
                            nir_deref_instr **dst_deref_arr,
                            nir_deref_instr *src_deref,
-                           nir_deref_instr **src_deref_arr)
+                           nir_deref_instr **src_deref_arr,
+                           enum gl_access_qualifier dst_access,
+                           enum gl_access_qualifier src_access)
 {
    if (dst_deref_arr || src_deref_arr) {
       assert(dst_deref_arr && src_deref_arr);
@@ -79,14 +81,16 @@ emit_deref_copy_load_store(nir_builder *b,
                                     nir_build_deref_array_imm(b, dst_deref, i),
                                     dst_deref_arr + 1,
                                     nir_build_deref_array_imm(b, src_deref, i),
-                                    src_deref_arr + 1);
+                                    src_deref_arr + 1, dst_access, src_access);
       }
    } else {
       assert(glsl_get_bare_type(dst_deref->type) ==
              glsl_get_bare_type(src_deref->type));
       assert(glsl_type_is_vector_or_scalar(dst_deref->type));
 
-      nir_store_deref(b, dst_deref, nir_load_deref(b, src_deref), ~0);
+      nir_store_deref_with_access(b, dst_deref,
+                                  nir_load_deref_with_access(b, src_deref, src_access),
+                                  ~0, src_access);
    }
 }
 
@@ -106,7 +110,9 @@ nir_lower_deref_copy_instr(nir_builder *b, nir_intrinsic_instr *copy)
 
    b->cursor = nir_before_instr(&copy->instr);
    emit_deref_copy_load_store(b, dst_path.path[0], &dst_path.path[1],
-                                 src_path.path[0], &src_path.path[1]);
+                                 src_path.path[0], &src_path.path[1],
+                                 nir_intrinsic_dst_access(copy),
+                                 nir_intrinsic_src_access(copy));
 
    nir_deref_path_finish(&dst_path);
    nir_deref_path_finish(&src_path);
index d67c6c79c17ea69625da80a328a590f632a11a85..6dac4eb5f5cf67bbe050237cedacc07cc1046249 100644 (file)
@@ -771,6 +771,8 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
       [NIR_INTRINSIC_IMAGE_DIM] = "image_dim",
       [NIR_INTRINSIC_IMAGE_ARRAY] = "image_array",
       [NIR_INTRINSIC_ACCESS] = "access",
+      [NIR_INTRINSIC_SRC_ACCESS] = "src-access",
+      [NIR_INTRINSIC_DST_ACCESS] = "dst-access",
       [NIR_INTRINSIC_FORMAT] = "format",
       [NIR_INTRINSIC_ALIGN_MUL] = "align_mul",
       [NIR_INTRINSIC_ALIGN_OFFSET] = "align_offset",
index 355a4e56d0136bdb08e71a16e34b38cd2b9f01a0..10b71c16c1799e6ea6aaf805f2496140785beb29 100644 (file)
 
 static void
 split_deref_copy_instr(nir_builder *b,
-                       nir_deref_instr *dst, nir_deref_instr *src)
+                       nir_deref_instr *dst, nir_deref_instr *src,
+                       enum gl_access_qualifier dst_access,
+                       enum gl_access_qualifier src_access)
 {
    assert(glsl_get_bare_type(dst->type) ==
           glsl_get_bare_type(src->type));
    if (glsl_type_is_vector_or_scalar(src->type)) {
-      nir_copy_deref(b, dst, src);
+      nir_copy_deref_with_access(b, dst, src, dst_access, src_access);
    } else if (glsl_type_is_struct_or_ifc(src->type)) {
       for (unsigned i = 0; i < glsl_get_length(src->type); i++) {
          split_deref_copy_instr(b, nir_build_deref_struct(b, dst, i),
-                                   nir_build_deref_struct(b, src, i));
+                                   nir_build_deref_struct(b, src, i),
+                                   dst_access, src_access);
       }
    } else {
       assert(glsl_type_is_matrix(src->type) || glsl_type_is_array(src->type));
       split_deref_copy_instr(b, nir_build_deref_array_wildcard(b, dst),
-                                nir_build_deref_array_wildcard(b, src));
+                                nir_build_deref_array_wildcard(b, src),
+                                dst_access, src_access);
    }
 }
 
@@ -105,7 +109,9 @@ split_var_copies_impl(nir_function_impl *impl)
             nir_instr_as_deref(copy->src[0].ssa->parent_instr);
          nir_deref_instr *src =
             nir_instr_as_deref(copy->src[1].ssa->parent_instr);
-         split_deref_copy_instr(&b, dst, src);
+         split_deref_copy_instr(&b, dst, src,
+                                nir_intrinsic_dst_access(copy),
+                                nir_intrinsic_src_access(copy));
 
          progress = true;
       }