From 0de003be0363df74a18f463d0291bc8000d4c1dd Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 16 Aug 2018 15:11:44 -0500 Subject: [PATCH] nir: Add handle/index-based image intrinsics Reviewed-by: Kenneth Graunke --- src/compiler/nir/nir.h | 30 ++++++++++++++++-- src/compiler/nir/nir_intrinsics.py | 50 +++++++++++++++++++----------- src/compiler/nir/nir_print.c | 22 +++++++++++++ 3 files changed, 82 insertions(+), 20 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 264b67c8d79..169fa1fa20d 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 170f954e375..d7184dadbbc 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: @@ -285,10 +293,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 @@ -297,20 +307,24 @@ 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_atomic_fadd", src_comp=[1, 4, 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("atomic_fadd", src_comp=[1, 4, 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.30.2