[Mesa-dev] [PATCH v3 004/104] nir: Add _deref versions of all of the _var intrinsics

Rob Clark robdclark at gmail.com
Sun Apr 8 11:44:37 UTC 2018


On Tue, Apr 3, 2018 at 2:32 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> ---
>  src/compiler/nir/nir.h             |  2 +-
>  src/compiler/nir/nir_builder.h     | 37 ++++++++++++++++++++
>  src/compiler/nir/nir_intrinsics.py | 72 ++++++++++++++++++++++++++++++++++++++
>  src/compiler/nir/nir_validate.c    | 34 ++++++++++++++++++
>  4 files changed, 144 insertions(+), 1 deletion(-)
>
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> index db7dc91..fb75c96 100644
> --- a/src/compiler/nir/nir.h
> +++ b/src/compiler/nir/nir.h
> @@ -1161,7 +1161,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 69c7261..62c3f38 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.py b/src/compiler/nir/nir_intrinsics.py
> index 1bc9955..5bd2a43 100644
> --- a/src/compiler/nir/nir_intrinsics.py
> +++ b/src/compiler/nir/nir_intrinsics.py
> @@ -124,6 +124,10 @@ intrinsic("load_var", dest_comp=0, num_vars=1, flags=[CAN_ELIMINATE])
>  intrinsic("store_var", src_comp=[0], num_vars=1, indices=[WRMASK])
>  intrinsic("copy_var", num_vars=2)
>
> +intrinsic("load_deref", dest_comp=0, src_comp=[1], flags=[CAN_ELIMINATE])
> +intrinsic("store_deref", src_comp=[1, 0], indices=[WRMASK])
> +intrinsic("copy_deref", src_comp=[1, 1])
> +
>  # 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
> @@ -137,6 +141,19 @@ intrinsic("interp_var_at_sample", src_comp=[1], dest_comp=0, num_vars=1,
>  intrinsic("interp_var_at_offset", src_comp=[2], dest_comp=0, num_vars=1,
>            flags=[CAN_ELIMINATE, CAN_REORDER])
>
> +# 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
> +# 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", dest_comp=0, src_comp=[1],
> +          flags=[ CAN_ELIMINATE, CAN_REORDER])

minor nit:          ^ whitespace

BR,
-R

> +intrinsic("interp_deref_at_sample", src_comp=[1, 1], dest_comp=0,
> +          flags=[CAN_ELIMINATE, CAN_REORDER])
> +intrinsic("interp_deref_at_offset", src_comp=[1, 2], dest_comp=0,
> +          flags=[CAN_ELIMINATE, CAN_REORDER])
> +
>  # Ask the driver for the size of a given buffer. It takes the buffer index
>  # as source.
>  intrinsic("get_buffer_size", src_comp=[1], dest_comp=1,
> @@ -256,14 +273,17 @@ intrinsic("set_vertex_count", src_comp=[1])
>
>  def atomic(name, flags=[]):
>      intrinsic(name + "_var", dest_comp=1, num_vars=1, flags=flags)
> +    intrinsic(name + "_deref", src_comp=[1], dest_comp=1, flags=flags)
>      intrinsic(name, src_comp=[1], dest_comp=1, indices=[BASE], flags=flags)
>
>  def atomic2(name):
>      intrinsic(name + "_var", src_comp=[1], dest_comp=1, num_vars=1)
> +    intrinsic(name + "_deref", src_comp=[1, 1], dest_comp=1)
>      intrinsic(name, src_comp=[1, 1], dest_comp=1, indices=[BASE])
>
>  def atomic3(name):
>      intrinsic(name + "_var", src_comp=[1, 1], dest_comp=1, num_vars=1)
> +    intrinsic(name + "_deref", src_comp=[1, 1, 1], dest_comp=1)
>      intrinsic(name, src_comp=[1, 1, 1], dest_comp=1, indices=[BASE])
>
>  atomic("atomic_counter_inc")
> @@ -305,6 +325,34 @@ intrinsic("image_var_atomic_comp_swap", src_comp=[4, 1, 1, 1], dest_comp=1, num_
>  intrinsic("image_var_size",    dest_comp=0, num_vars=1, flags=[CAN_ELIMINATE, CAN_REORDER])
>  intrinsic("image_var_samples", dest_comp=1, num_vars=1, flags=[CAN_ELIMINATE, 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", src_comp=[1, 4, 1], dest_comp=4,
> +          flags=[CAN_ELIMINATE])
> +intrinsic("image_deref_store", src_comp=[1, 4, 1, 4])
> +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])
> +
>  # Vulkan descriptor set intrinsics
>  #
>  # The Vulkan API uses a different binding model from GL.  In the Vulkan
> @@ -354,6 +402,30 @@ intrinsic("var_atomic_xor",  src_comp=[1], dest_comp=1, num_vars=1)
>  intrinsic("var_atomic_exchange", src_comp=[1], dest_comp=1, num_vars=1)
>  intrinsic("var_atomic_comp_swap", src_comp=[1, 1], dest_comp=1, num_vars=1)
>
> +# variable atomic intrinsics
> +#
> +# All of these variable 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",  src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_imin", src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_umin", src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_imax", src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_umax", src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_and",  src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_or",   src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_xor",  src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_exchange", src_comp=[1, 1], dest_comp=1)
> +intrinsic("deref_atomic_comp_swap", src_comp=[1, 1, 1], dest_comp=1)
> +
>  # SSBO atomic intrinsics
>  #
>  # All of the SSBO atomic memory operations read a value from memory,
> diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
> index 527abde..655d430 100644
> --- a/src/compiler/nir/nir_validate.c
> +++ b/src/compiler/nir/nir_validate.c
> @@ -555,6 +555,40 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
>     unsigned dest_bit_size = 0;
>     unsigned src_bit_sizes[NIR_INTRINSIC_MAX_INPUTS] = { 0, };
>     switch (instr->intrinsic) {
> +   case nir_intrinsic_load_deref: {
> +      nir_deref_instr *src = nir_src_as_deref(instr->src[0]);
> +      validate_assert(state, glsl_type_is_vector_or_scalar(src->type) ||
> +                      (src->mode == nir_var_uniform &&
> +                       glsl_get_base_type(src->type) == GLSL_TYPE_SUBROUTINE));
> +      validate_assert(state, instr->num_components ==
> +                             glsl_get_vector_elements(src->type));
> +      dest_bit_size = glsl_get_bit_size(src->type);
> +      break;
> +   }
> +
> +   case nir_intrinsic_store_deref: {
> +      nir_deref_instr *dst = nir_src_as_deref(instr->src[0]);
> +      validate_assert(state, glsl_type_is_vector_or_scalar(dst->type));
> +      validate_assert(state, instr->num_components ==
> +                             glsl_get_vector_elements(dst->type));
> +      src_bit_sizes[1] = glsl_get_bit_size(dst->type);
> +      validate_assert(state, (dst->mode & (nir_var_shader_in |
> +                                           nir_var_uniform |
> +                                           nir_var_shader_storage)) == 0);
> +      validate_assert(state, (nir_intrinsic_write_mask(instr) & ~((1 << instr->num_components) - 1)) == 0);
> +      break;
> +   }
> +
> +   case nir_intrinsic_copy_deref: {
> +      nir_deref_instr *dst = nir_src_as_deref(instr->src[0]);
> +      nir_deref_instr *src = nir_src_as_deref(instr->src[1]);
> +      validate_assert(state, dst->type == src->type);
> +      validate_assert(state, (dst->mode & (nir_var_shader_in |
> +                                           nir_var_uniform |
> +                                           nir_var_shader_storage)) == 0);
> +      break;
> +   }
> +
>     case nir_intrinsic_load_var: {
>        const struct glsl_type *type =
>           nir_deref_tail(&instr->variables[0]->deref)->type;
> --
> 2.5.0.400.gff86faf
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list