From: Rhys Perry Date: Tue, 24 Nov 2020 12:51:59 +0000 (+0000) Subject: nir: use a single canonical list of intrinsic indices X-Git-Tag: upstream/21.0.0~2090 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=898d7c1f493b8d06168c2256404d448888183bd9;p=platform%2Fupstream%2Fmesa.git nir: use a single canonical list of intrinsic indices Signed-off-by: Rhys Perry Reviewed-by: Jason Ekstrand Part-of: --- diff --git a/src/compiler/Android.nir.gen.mk b/src/compiler/Android.nir.gen.mk index 2d2f772..98a807a 100644 --- a/src/compiler/Android.nir.gen.mk +++ b/src/compiler/Android.nir.gen.mk @@ -117,3 +117,8 @@ nir_intrinsics_c_gen := $(LOCAL_PATH)/nir/nir_intrinsics_c.py $(intermediates)/nir/nir_intrinsics.c: $(LOCAL_PATH)/nir/nir_intrinsics.py $(nir_intrinsics_c_gen) @mkdir -p $(dir $@) $(hide) $(MESA_PYTHON2) $(nir_intrinsics_c_gen) --outdir $(dir $@) || ($(RM) $@; false) + +nir_intrinsics_indices_h_gen := $(LOCAL_PATH)/nir/nir_intrinsics_indices_h.py +$(intermediates)/nir/nir_intrinsics_indices.h: $(LOCAL_PATH)/nir/nir_intrinsics.py $(nir_intrinsics_indices_h_gen) + @mkdir -p $(dir $@) + $(hide) $(MESA_PYTHON2) $(nir_intrinsics_indices_h_gen) --outdir $(dir $@) || ($(RM) $@; false) diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources index 4822b0e..2f3d389 100644 --- a/src/compiler/Makefile.sources +++ b/src/compiler/Makefile.sources @@ -199,6 +199,7 @@ NIR_GENERATED_FILES = \ nir/nir_constant_expressions.c \ nir/nir_intrinsics.c \ nir/nir_intrinsics.h \ + nir/nir_intrinsics_indices.h \ nir/nir_opcodes.c \ nir/nir_opcodes.h \ nir/nir_opt_algebraic.c diff --git a/src/compiler/SConscript.nir b/src/compiler/SConscript.nir index 41c6794..be435e0 100644 --- a/src/compiler/SConscript.nir +++ b/src/compiler/SConscript.nir @@ -75,6 +75,13 @@ env.CodeGenerate( command = python_cmd + ' $SCRIPT --outdir ' + bldroot + '/nir' ) +env.CodeGenerate( + target = 'nir/nir_intrinsics_indices.h', + script = 'nir/nir_intrinsics_indices_h.py', + source = [], + command = python_cmd + ' $SCRIPT --outdir ' + bldroot + '/nir' +) + # parse Makefile.sources source_lists = env.ParseSourceList('Makefile.sources') diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build index 3741316..6895a0f 100644 --- a/src/compiler/nir/meson.build +++ b/src/compiler/nir/meson.build @@ -74,6 +74,15 @@ nir_intrinsics_h = custom_target( depend_files : files('nir_intrinsics.py'), ) +nir_intrinsics_indices_h = custom_target( + 'nir_intrinsics_indices.h', + input : 'nir_intrinsics_indices_h.py', + output : 'nir_intrinsics_indices.h', + command : [prog_python, '@INPUT@', '--outdir', meson.current_build_dir()], + capture : false, + depend_files : files('nir_intrinsics.py'), +) + nir_intrinsics_c = custom_target( 'nir_intrinsic.c', input : 'nir_intrinsics_c.py', @@ -323,7 +332,7 @@ _libnir = static_library( 'nir', [files_libnir, spirv_info_c, nir_opt_algebraic_c, nir_opcodes_c, nir_opcodes_h, nir_constant_expressions_c, nir_builder_opcodes_h, - vtn_gather_types_c, nir_intrinsics_c, nir_intrinsics_h, vtn_generator_ids_h], + vtn_gather_types_c, nir_intrinsics_c, nir_intrinsics_h, nir_intrinsics_indices_h, vtn_generator_ids_h], include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_compiler, include_directories('../spirv')], c_args : [c_msvc_compat_args, no_override_init_args, _libnir_args], gnu_symbol_visibility : 'hidden', @@ -334,7 +343,7 @@ _libnir = static_library( # Headers-only dependency idep_nir_headers = declare_dependency( - sources : [nir_opcodes_h, nir_builder_opcodes_h, nir_intrinsics_h], + sources : [nir_opcodes_h, nir_builder_opcodes_h, nir_intrinsics_h, nir_intrinsics_indices_h], include_directories : include_directories('.'), ) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 9e7420f..314ae34 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1775,203 +1775,13 @@ typedef enum { } nir_intrinsic_semantic_flag; /** - * \name NIR intrinsics const-index flag - * - * Indicates the usage of a const_index slot. - * - * \sa nir_intrinsic_info::index_map - */ -typedef enum { - /** - * Generally instructions that take a offset src argument, can encode - * a constant 'base' value which is added to the offset. - */ - NIR_INTRINSIC_BASE = 1, - - /** - * For store instructions, a writemask for the store. - */ - NIR_INTRINSIC_WRMASK, - - /** - * The stream-id for GS emit_vertex/end_primitive intrinsics. - */ - NIR_INTRINSIC_STREAM_ID, - - /** - * The clip-plane id for load_user_clip_plane intrinsic. - */ - NIR_INTRINSIC_UCP_ID, - - /** - * The start of NIR_INTRINSIC_RANGE. Only present on instructions that - * don't have NIR_INTRINSIC_BASE. - * - * If the [range_base, range] is [0, ~0], then we don't know the possible - * range of the access. - */ - NIR_INTRINSIC_RANGE_BASE, - - /** - * The amount of data, starting from BASE or RANGE_BASE, that this - * instruction may access. This is used to provide bounds if the offset is - * not constant. - */ - NIR_INTRINSIC_RANGE, - - /** - * The Vulkan descriptor set for vulkan_resource_index intrinsic. - */ - NIR_INTRINSIC_DESC_SET, - - /** - * The Vulkan descriptor set binding for vulkan_resource_index intrinsic. - */ - NIR_INTRINSIC_BINDING, - - /** - * Component offset. - */ - NIR_INTRINSIC_COMPONENT, - - /** - * Column index for matrix intrinsics. - */ - NIR_INTRINSIC_COLUMN, - - /** - * Interpolation mode (only meaningful for FS inputs). - */ - NIR_INTRINSIC_INTERP_MODE, - - /** - * A binary nir_op to use when performing a reduction or scan operation - */ - NIR_INTRINSIC_REDUCTION_OP, - - /** - * Cluster size for reduction operations - */ - NIR_INTRINSIC_CLUSTER_SIZE, - - /** - * Parameter index for a load_param intrinsic - */ - NIR_INTRINSIC_PARAM_IDX, - - /** - * Image dimensionality for image intrinsics - * - * One of GLSL_SAMPLER_DIM_* - */ - NIR_INTRINSIC_IMAGE_DIM, - - /** - * Non-zero if we are accessing an array image - */ - NIR_INTRINSIC_IMAGE_ARRAY, - - /** - * Image format for image intrinsics - */ - NIR_INTRINSIC_FORMAT, - - /** - * Access qualifiers for image and memory access intrinsics - */ - NIR_INTRINSIC_ACCESS, - - /** - * Alignment for offsets and addresses - * - * These two parameters, specify an alignment in terms of a multiplier and - * an offset. The multiplier is always a power of two. The offset or - * address parameter X of the intrinsic is guaranteed to satisfy the - * following: - * - * (X - align_offset) % align_mul == 0 - * - * For constant offset values, align_mul will be NIR_ALIGN_MUL_MAX and the - * align_offset will be modulo that. - */ - NIR_INTRINSIC_ALIGN_MUL, - NIR_INTRINSIC_ALIGN_OFFSET, - - /** - * The Vulkan descriptor type for a vulkan_resource_[re]index intrinsic. - */ - NIR_INTRINSIC_DESC_TYPE, - - /** - * The nir_alu_type of input data to a store or conversion - */ - NIR_INTRINSIC_SRC_TYPE, - - /** - * The nir_alu_type of the data output from a load or conversion - */ - NIR_INTRINSIC_DEST_TYPE, - - /** - * The swizzle mask for the instructions - * SwizzleInvocationsAMD and SwizzleInvocationsMaskedAMD - */ - NIR_INTRINSIC_SWIZZLE_MASK, - - /* Separate source/dest access flags for copies */ - NIR_INTRINSIC_SRC_ACCESS, - NIR_INTRINSIC_DST_ACCESS, - - /* Driver location for nir_load_patch_location_ir3 */ - NIR_INTRINSIC_DRIVER_LOCATION, - - /** - * Mask of nir_memory_semantics, includes ordering and visibility. - */ - NIR_INTRINSIC_MEMORY_SEMANTICS, - - /** - * Mask of nir_variable_modes affected by the memory operation. - */ - NIR_INTRINSIC_MEMORY_MODES, - - /** - * Value of nir_scope. - */ - NIR_INTRINSIC_MEMORY_SCOPE, - - /** - * Value of nir_scope. - */ - NIR_INTRINSIC_EXECUTION_SCOPE, - - /** - * Value of nir_io_semantics. - */ - NIR_INTRINSIC_IO_SEMANTICS, - - /** - * The rounding mode of a conversion - */ - NIR_INTRINSIC_ROUNDING_MODE, - - /** - * Whether or not to saturate in conversions - */ - NIR_INTRINSIC_SATURATE, - - NIR_INTRINSIC_NUM_INDEX_FLAGS, - -} nir_intrinsic_index_flag; - -/** * Maximum valid value for a nir align_mul value (in intrinsics or derefs). * * Offsets can be signed, so this is the largest power of two in int32_t. */ #define NIR_ALIGN_MUL_MAX 0x40000000 -typedef struct { +typedef struct nir_io_semantics { unsigned location:7; /* gl_vert_attrib, gl_varying_slot, or gl_frag_result */ unsigned num_slots:6; /* max 32, may be pessimistic with const indexing */ unsigned dual_source_blend_index:1; @@ -2074,61 +1884,7 @@ nir_intrinsic_copy_const_indices(nir_intrinsic_instr *dst, nir_intrinsic_instr * } } -#define INTRINSIC_IDX_ACCESSORS(name, flag, type) \ -static inline type \ -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 (type)instr->const_index[info->index_map[NIR_INTRINSIC_##flag] - 1]; \ -} \ -static inline void \ -nir_intrinsic_set_##name(nir_intrinsic_instr *instr, type val) \ -{ \ - const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; \ - assert(info->index_map[NIR_INTRINSIC_##flag] > 0); \ - instr->const_index[info->index_map[NIR_INTRINSIC_##flag] - 1] = val; \ -} \ -static inline bool \ -nir_intrinsic_has_##name(const nir_intrinsic_instr *instr) \ -{ \ - const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; \ - return info->index_map[NIR_INTRINSIC_##flag] > 0; \ -} - -INTRINSIC_IDX_ACCESSORS(write_mask, WRMASK, unsigned) -INTRINSIC_IDX_ACCESSORS(base, BASE, int) -INTRINSIC_IDX_ACCESSORS(stream_id, STREAM_ID, unsigned) -INTRINSIC_IDX_ACCESSORS(ucp_id, UCP_ID, unsigned) -INTRINSIC_IDX_ACCESSORS(range, RANGE, unsigned) -INTRINSIC_IDX_ACCESSORS(range_base, RANGE_BASE, unsigned) -INTRINSIC_IDX_ACCESSORS(desc_set, DESC_SET, unsigned) -INTRINSIC_IDX_ACCESSORS(binding, BINDING, unsigned) -INTRINSIC_IDX_ACCESSORS(component, COMPONENT, unsigned) -INTRINSIC_IDX_ACCESSORS(column, COLUMN, unsigned) -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(src_access, SRC_ACCESS, enum gl_access_qualifier) -INTRINSIC_IDX_ACCESSORS(dst_access, DST_ACCESS, enum gl_access_qualifier) -INTRINSIC_IDX_ACCESSORS(format, FORMAT, enum pipe_format) -INTRINSIC_IDX_ACCESSORS(align_mul, ALIGN_MUL, unsigned) -INTRINSIC_IDX_ACCESSORS(align_offset, ALIGN_OFFSET, unsigned) -INTRINSIC_IDX_ACCESSORS(desc_type, DESC_TYPE, unsigned) -INTRINSIC_IDX_ACCESSORS(src_type, SRC_TYPE, nir_alu_type) -INTRINSIC_IDX_ACCESSORS(dest_type, DEST_TYPE, nir_alu_type) -INTRINSIC_IDX_ACCESSORS(swizzle_mask, SWIZZLE_MASK, unsigned) -INTRINSIC_IDX_ACCESSORS(driver_location, DRIVER_LOCATION, unsigned) -INTRINSIC_IDX_ACCESSORS(memory_semantics, MEMORY_SEMANTICS, nir_memory_semantics) -INTRINSIC_IDX_ACCESSORS(memory_modes, MEMORY_MODES, nir_variable_mode) -INTRINSIC_IDX_ACCESSORS(memory_scope, MEMORY_SCOPE, nir_scope) -INTRINSIC_IDX_ACCESSORS(execution_scope, EXECUTION_SCOPE, nir_scope) -INTRINSIC_IDX_ACCESSORS(rounding_mode, ROUNDING_MODE, nir_rounding_mode) -INTRINSIC_IDX_ACCESSORS(saturate, SATURATE, bool) +#include "nir_intrinsics_indices.h" static inline void nir_intrinsic_set_align(nir_intrinsic_instr *intrin, @@ -2163,30 +1919,6 @@ nir_intrinsic_has_align(const nir_intrinsic_instr *intrin) nir_intrinsic_has_align_offset(intrin); } -static inline void -nir_intrinsic_set_io_semantics(nir_intrinsic_instr *intrin, - nir_io_semantics semantics) -{ - const nir_intrinsic_info *info = &nir_intrinsic_infos[intrin->intrinsic]; - assert(info->index_map[NIR_INTRINSIC_IO_SEMANTICS] > 0); - STATIC_ASSERT(sizeof(nir_io_semantics) == sizeof(intrin->const_index[0])); - semantics._pad = 0; /* clear padding bits */ - memcpy(&intrin->const_index[info->index_map[NIR_INTRINSIC_IO_SEMANTICS] - 1], - &semantics, sizeof(semantics)); -} - -static inline nir_io_semantics -nir_intrinsic_io_semantics(const nir_intrinsic_instr *intrin) -{ - const nir_intrinsic_info *info = &nir_intrinsic_infos[intrin->intrinsic]; - assert(info->index_map[NIR_INTRINSIC_IO_SEMANTICS] > 0); - nir_io_semantics semantics; - memcpy(&semantics, - &intrin->const_index[info->index_map[NIR_INTRINSIC_IO_SEMANTICS] - 1], - sizeof(semantics)); - return semantics; -} - unsigned nir_image_intrinsic_coord_components(const nir_intrinsic_instr *instr); diff --git a/src/compiler/nir/nir_builder_opcodes_h.py b/src/compiler/nir/nir_builder_opcodes_h.py index 2c37be7..4113c76 100644 --- a/src/compiler/nir/nir_builder_opcodes_h.py +++ b/src/compiler/nir/nir_builder_opcodes_h.py @@ -72,7 +72,7 @@ nir_load_system_value(nir_builder *build, nir_intrinsic_op op, int index, def sysval_decl_list(opcode): res = '' if opcode.indices: - res += ', unsigned ' + opcode.indices[0].lower() + res += ', unsigned ' + opcode.indices[0].name.lower() if opcode.dest_components == 0: res += ', unsigned num_components' if len(opcode.bit_sizes) != 1: @@ -82,7 +82,7 @@ def sysval_decl_list(opcode): def sysval_arg_list(opcode): args = [] if opcode.indices: - args.append(opcode.indices[0].lower()) + args.append(opcode.indices[0].name.lower()) else: args.append('0') diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 7157d7d..e29fb28 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -27,6 +27,11 @@ # The Intrinsic class corresponds one-to-one with nir_intrinsic_info # structure. +class Index(object): + def __init__(self, c_data_type, name): + self.c_data_type = c_data_type + self.name = name + class Intrinsic(object): """Class that represents all the information about an intrinsic opcode. NOTE: this must be kept in sync with nir_intrinsic_info. @@ -54,7 +59,7 @@ class Intrinsic(object): assert isinstance(dest_components, int) assert isinstance(indices, list) if indices: - assert isinstance(indices[0], str) + assert isinstance(indices[0], Index) assert isinstance(flags, list) if flags: assert isinstance(flags[0], str) @@ -74,105 +79,156 @@ class Intrinsic(object): self.bit_sizes = bit_sizes # +# Possible flags: +# + +CAN_ELIMINATE = "NIR_INTRINSIC_CAN_ELIMINATE" +CAN_REORDER = "NIR_INTRINSIC_CAN_REORDER" + +INTR_INDICES = [] +INTR_OPCODES = {} + +def index(c_data_type, name): + idx = Index(c_data_type, name) + INTR_INDICES.append(idx) + globals()[name.upper()] = idx + +# Defines a new NIR intrinsic. By default, the intrinsic will have no sources +# and no destination. +# +# You can set dest_comp=n to enable a destination for the intrinsic, in which +# case it will have that many components, or =0 for "as many components as the +# NIR destination value." +# +# Set src_comp=n to enable sources for the intruction. It can be an array of +# component counts, or (for convenience) a scalar component count if there's +# only one source. If a component count is 0, it will be as many components as +# the intrinsic has based on the dest_comp. +def intrinsic(name, src_comp=[], dest_comp=-1, indices=[], + flags=[], sysval=False, bit_sizes=[]): + assert name not in INTR_OPCODES + INTR_OPCODES[name] = Intrinsic(name, src_comp, dest_comp, + indices, flags, sysval, bit_sizes) + +# # Possible indices: # -# A constant 'base' value that is added to an offset src: -BASE = "NIR_INTRINSIC_BASE" -# For store instructions, a writemask: -WRMASK = "NIR_INTRINSIC_WRMASK" -# The stream-id for GS emit_vertex/end_primitive intrinsics: -STREAM_ID = "NIR_INTRINSIC_STREAM_ID" -# The clip-plane id for load_user_clip_plane intrinsics: -UCP_ID = "NIR_INTRINSIC_UCP_ID" -# The amount of data, starting from BASE, that this instruction -# may access. This is used to provide bounds if the offset is -# not constant. -RANGE = "NIR_INTRINSIC_RANGE" +# Generally instructions that take a offset src argument, can encode +# a constant 'base' value which is added to the offset. +index("int", "base") + +# For store instructions, a writemask for the store. +index("unsigned", "write_mask") + +# The stream-id for GS emit_vertex/end_primitive intrinsics. +index("unsigned", "stream_id") + +# The clip-plane id for load_user_clip_plane intrinsic. +index("unsigned", "ucp_id") + # The offset to the start of the NIR_INTRINSIC_RANGE. This is an alternative # to NIR_INTRINSIC_BASE for describing the valid range in intrinsics that don't # have the implicit addition of a base to the offset. -RANGE_BASE = "NIR_INTRINSIC_RANGE_BASE" -# The vulkan descriptor set binding for vulkan_resource_index -# intrinsic -DESC_SET = "NIR_INTRINSIC_DESC_SET" -# The vulkan descriptor set binding for vulkan_resource_index -# intrinsic -BINDING = "NIR_INTRINSIC_BINDING" +# +# If the [range_base, range] is [0, ~0], then we don't know the possible +# range of the access. +index("unsigned", "range_base") + +# The amount of data, starting from BASE or RANGE_BASE, that this +# instruction may access. This is used to provide bounds if the offset is +# not constant. +index("unsigned", "range") + +# The Vulkan descriptor set for vulkan_resource_index intrinsic. +index("unsigned", "desc_set") + +# The Vulkan descriptor set binding for vulkan_resource_index intrinsic. +index("unsigned", "binding") + # Component offset -COMPONENT = "NIR_INTRINSIC_COMPONENT" +index("unsigned", "component") + # Column index for matrix system values -COLUMN = "NIR_INTRINSIC_COLUMN" +index("unsigned", "column") + # Interpolation mode (only meaningful for FS inputs) -INTERP_MODE = "NIR_INTRINSIC_INTERP_MODE" +index("unsigned", "interp_mode") + # A binary nir_op to use when performing a reduction or scan operation -REDUCTION_OP = "NIR_INTRINSIC_REDUCTION_OP" +index("unsigned", "reduction_op") + # Cluster size for reduction operations -CLUSTER_SIZE = "NIR_INTRINSIC_CLUSTER_SIZE" +index("unsigned", "cluster_size") + # Parameter index for a load_param intrinsic -PARAM_IDX = "NIR_INTRINSIC_PARAM_IDX" +index("unsigned", "param_idx") + # Image dimensionality for image intrinsics -IMAGE_DIM = "NIR_INTRINSIC_IMAGE_DIM" +index("enum glsl_sampler_dim", "image_dim") + # Non-zero if we are accessing an array image -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" +index("bool", "image_array") + # Image format for image intrinsics -FORMAT = "NIR_INTRINSIC_FORMAT" -# Offset or address alignment -ALIGN_MUL = "NIR_INTRINSIC_ALIGN_MUL" -ALIGN_OFFSET = "NIR_INTRINSIC_ALIGN_OFFSET" -# The vulkan descriptor type for vulkan_resource_index -DESC_TYPE = "NIR_INTRINSIC_DESC_TYPE" +index("enum pipe_format", "format") + +# Access qualifiers for image and memory access intrinsics +index("enum gl_access_qualifier", "access") + +# Alignment for offsets and addresses +# +# These two parameters, specify an alignment in terms of a multiplier and +# an offset. The multiplier is always a power of two. The offset or +# address parameter X of the intrinsic is guaranteed to satisfy the +# following: +# +# (X - align_offset) % align_mul == 0 +# +# For constant offset values, align_mul will be NIR_ALIGN_MUL_MAX and the +# align_offset will be modulo that. +index("unsigned", "align_mul") +index("unsigned", "align_offset") + +# The Vulkan descriptor type for a vulkan_resource_[re]index intrinsic. +index("unsigned", "desc_type") + # The nir_alu_type of input data to a store or conversion -SRC_TYPE = "NIR_INTRINSIC_SRC_TYPE" +index("nir_alu_type", "src_type") + # The nir_alu_type of the data output from a load or conversion -DEST_TYPE = "NIR_INTRINSIC_DEST_TYPE" +index("nir_alu_type", "dest_type") + # The swizzle mask for quad_swizzle_amd & masked_swizzle_amd -SWIZZLE_MASK = "NIR_INTRINSIC_SWIZZLE_MASK" +index("unsigned", "swizzle_mask") + +# Separate source/dest access flags for copies +index("enum gl_access_qualifier", "dst_access") +index("enum gl_access_qualifier", "src_access") + # Driver location of attribute -DRIVER_LOCATION = "NIR_INTRINSIC_DRIVER_LOCATION" +index("unsigned", "driver_location") + # Ordering and visibility of a memory operation -MEMORY_SEMANTICS = "NIR_INTRINSIC_MEMORY_SEMANTICS" +index("nir_memory_semantics", "memory_semantics") + # Modes affected by a memory operation -MEMORY_MODES = "NIR_INTRINSIC_MEMORY_MODES" +index("nir_variable_mode", "memory_modes") + # Scope of a memory operation -MEMORY_SCOPE = "NIR_INTRINSIC_MEMORY_SCOPE" -# Scope of a control barrier -EXECUTION_SCOPE = "NIR_INTRINSIC_EXECUTION_SCOPE" -IO_SEMANTICS = "NIR_INTRINSIC_IO_SEMANTICS" -# Rounding mode for conversions -ROUNDING_MODE = "NIR_INTRINSIC_ROUNDING_MODE" -# Whether or not to saturate in conversions -SATURATE = "NIR_INTRINSIC_SATURATE" +index("nir_scope", "memory_scope") -# -# Possible flags: -# +# Scope of a control barrier +index("nir_scope", "execution_scope") -CAN_ELIMINATE = "NIR_INTRINSIC_CAN_ELIMINATE" -CAN_REORDER = "NIR_INTRINSIC_CAN_REORDER" +# Semantics of an IO instruction +index("struct nir_io_semantics", "io_semantics") -INTR_OPCODES = {} +# Rounding mode for conversions +index("nir_rounding_mode", "rounding_mode") -# Defines a new NIR intrinsic. By default, the intrinsic will have no sources -# and no destination. -# -# You can set dest_comp=n to enable a destination for the intrinsic, in which -# case it will have that many components, or =0 for "as many components as the -# NIR destination value." -# -# Set src_comp=n to enable sources for the intruction. It can be an array of -# component counts, or (for convenience) a scalar component count if there's -# only one source. If a component count is 0, it will be as many components as -# the intrinsic has based on the dest_comp. -def intrinsic(name, src_comp=[], dest_comp=-1, indices=[], - flags=[], sysval=False, bit_sizes=[]): - assert name not in INTR_OPCODES - INTR_OPCODES[name] = Intrinsic(name, src_comp, dest_comp, - indices, flags, sysval, bit_sizes) +# Whether or not to saturate in conversions +index("unsigned", "saturate") intrinsic("nop", flags=[CAN_ELIMINATE]) @@ -184,7 +240,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("store_deref", src_comp=[-1, 0], indices=[WRITE_MASK, ACCESS]) intrinsic("copy_deref", src_comp=[-1, -1], indices=[DST_ACCESS, SRC_ACCESS]) intrinsic("memcpy_deref", src_comp=[-1, -1, 1], indices=[DST_ACCESS, SRC_ACCESS]) @@ -863,17 +919,17 @@ def store(name, srcs, indices=[], flags=[]): intrinsic("store_" + name, [0] + srcs, indices=indices, flags=flags) # src[] = { value, offset }. -store("output", [1], [BASE, WRMASK, COMPONENT, SRC_TYPE, IO_SEMANTICS]) +store("output", [1], [BASE, WRITE_MASK, COMPONENT, SRC_TYPE, IO_SEMANTICS]) # src[] = { value, vertex, offset }. -store("per_vertex_output", [1, 1], [BASE, WRMASK, COMPONENT, IO_SEMANTICS]) +store("per_vertex_output", [1, 1], [BASE, WRITE_MASK, COMPONENT, IO_SEMANTICS]) # src[] = { value, block_index, offset } -store("ssbo", [-1, 1], [WRMASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) +store("ssbo", [-1, 1], [WRITE_MASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) # src[] = { value, offset }. -store("shared", [1], [BASE, WRMASK, ALIGN_MUL, ALIGN_OFFSET]) +store("shared", [1], [BASE, WRITE_MASK, ALIGN_MUL, ALIGN_OFFSET]) # src[] = { value, address }. -store("global", [1], [WRMASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) +store("global", [1], [WRITE_MASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) # src[] = { value, offset }. -store("scratch", [1], [ALIGN_MUL, ALIGN_OFFSET, WRMASK]) +store("scratch", [1], [ALIGN_MUL, ALIGN_OFFSET, WRITE_MASK]) # IR3-specific version of most SSBO intrinsics. The only different # compare to the originals is that they add an extra source to hold @@ -887,7 +943,7 @@ store("scratch", [1], [ALIGN_MUL, ALIGN_OFFSET, WRMASK]) # The float versions are not handled because those are not supported # by the backend. store("ssbo_ir3", [1, 1, 1], - indices=[WRMASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) + indices=[WRITE_MASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) load("ssbo_ir3", [1, 1, 1], indices=[ACCESS, ALIGN_MUL, ALIGN_OFFSET], flags=[CAN_ELIMINATE]) intrinsic("ssbo_atomic_add_ir3", src_comp=[1, 1, 1, 1], dest_comp=1, indices=[ACCESS]) @@ -1018,7 +1074,7 @@ system_value("tcs_tess_factor_base_r600", 1) # load as many components as needed giving per-component addresses intrinsic("load_local_shared_r600", src_comp=[0], dest_comp=0, indices = [COMPONENT], flags = [CAN_ELIMINATE, CAN_REORDER]) -store("local_shared_r600", [1], [WRMASK]) +store("local_shared_r600", [1], [WRITE_MASK]) store("tf_r600", []) # V3D-specific instrinc for tile buffer color reads. @@ -1068,7 +1124,7 @@ intrinsic("load_reloc_const_intel", dest_comp=1, bit_sizes=[32], # OpSubgroupBlockReadINTEL and OpSubgroupBlockWriteINTEL from SPV_INTEL_subgroups. intrinsic("load_deref_block_intel", dest_comp=0, src_comp=[-1], indices=[ACCESS], flags=[CAN_ELIMINATE]) -intrinsic("store_deref_block_intel", src_comp=[-1, 0], indices=[WRMASK, ACCESS]) +intrinsic("store_deref_block_intel", src_comp=[-1, 0], indices=[WRITE_MASK, ACCESS]) # src[] = { address }. load("global_block_intel", [1], [ACCESS, ALIGN_MUL, ALIGN_OFFSET], [CAN_ELIMINATE]) @@ -1080,13 +1136,13 @@ load("ssbo_block_intel", [-1, 1], [ACCESS, ALIGN_MUL, ALIGN_OFFSET], [CAN_ELIMIN load("shared_block_intel", [1], [BASE, ALIGN_MUL, ALIGN_OFFSET], [CAN_ELIMINATE]) # src[] = { value, address }. -store("global_block_intel", [1], [WRMASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) +store("global_block_intel", [1], [WRITE_MASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) # src[] = { value, block_index, offset } -store("ssbo_block_intel", [-1, 1], [WRMASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) +store("ssbo_block_intel", [-1, 1], [WRITE_MASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) # src[] = { value, offset }. -store("shared_block_intel", [1], [BASE, WRMASK, ALIGN_MUL, ALIGN_OFFSET]) +store("shared_block_intel", [1], [BASE, WRITE_MASK, ALIGN_MUL, ALIGN_OFFSET]) # Intrinsics for Intel bindless thread dispatch system_value("btd_dss_id_intel", 1) diff --git a/src/compiler/nir/nir_intrinsics_c.py b/src/compiler/nir/nir_intrinsics_c.py index 3043ffe..c2dce43 100644 --- a/src/compiler/nir/nir_intrinsics_c.py +++ b/src/compiler/nir/nir_intrinsics_c.py @@ -43,7 +43,7 @@ const nir_intrinsic_info nir_intrinsic_infos[nir_num_intrinsics] = { % if opcode.indices: .index_map = { % for i in range(len(opcode.indices)): - [${opcode.indices[i]}] = ${i + 1}, + [NIR_INTRINSIC_${opcode.indices[i].name.upper()}] = ${i + 1}, % endfor }, % endif @@ -51,9 +51,15 @@ const nir_intrinsic_info nir_intrinsic_infos[nir_num_intrinsics] = { }, % endfor }; + +const char *nir_intrinsic_index_names[NIR_INTRINSIC_NUM_INDEX_FLAGS] = { +% for index in INTR_INDICES: + "${index.name}", +% endfor +}; """ -from nir_intrinsics import INTR_OPCODES +from nir_intrinsics import INTR_OPCODES, INTR_INDICES from mako.template import Template import argparse import os @@ -67,7 +73,9 @@ def main(): path = os.path.join(args.outdir, 'nir_intrinsics.c') with open(path, 'wb') as f: - f.write(Template(template, output_encoding='utf-8').render(INTR_OPCODES=INTR_OPCODES, reduce=reduce, operator=operator)) + f.write(Template(template, output_encoding='utf-8').render( + INTR_OPCODES=INTR_OPCODES, INTR_INDICES=INTR_INDICES, + reduce=reduce, operator=operator)) if __name__ == '__main__': main() diff --git a/src/compiler/nir/nir_intrinsics_h.py b/src/compiler/nir/nir_intrinsics_h.py index 8abc6a8..6941f23 100644 --- a/src/compiler/nir/nir_intrinsics_h.py +++ b/src/compiler/nir/nir_intrinsics_h.py @@ -36,9 +36,18 @@ typedef enum { nir_num_intrinsics = nir_last_intrinsic + 1 } nir_intrinsic_op; +typedef enum { +% for index in INTR_INDICES: + NIR_INTRINSIC_${index.name.upper()}, +% endfor + NIR_INTRINSIC_NUM_INDEX_FLAGS, +} nir_intrinsic_index_flag; + +extern const char *nir_intrinsic_index_names[NIR_INTRINSIC_NUM_INDEX_FLAGS]; + #endif /* _NIR_INTRINSICS_ */""" -from nir_intrinsics import INTR_OPCODES +from nir_intrinsics import INTR_OPCODES, INTR_INDICES from mako.template import Template import argparse import os @@ -53,7 +62,7 @@ def main(): path = os.path.join(args.outdir, 'nir_intrinsics.h') with open(path, 'wb') as f: - f.write(Template(template, output_encoding='utf-8').render(INTR_OPCODES=INTR_OPCODES)) + f.write(Template(template, output_encoding='utf-8').render(INTR_OPCODES=INTR_OPCODES, INTR_INDICES=INTR_INDICES)) if __name__ == '__main__': main() diff --git a/src/compiler/nir/nir_intrinsics_indices_h.py b/src/compiler/nir/nir_intrinsics_indices_h.py new file mode 100644 index 0000000..fd39e41 --- /dev/null +++ b/src/compiler/nir/nir_intrinsics_indices_h.py @@ -0,0 +1,94 @@ + +template = """\ +/* Copyright (C) 2018 Red Hat + * Copyright (C) 2020 Valve Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _NIR_INTRINSICS_INDICES_ +#define _NIR_INTRINSICS_INDICES_ + +% for index in INTR_INDICES: +<% +data_type = index.c_data_type +name = index.name +enum = "NIR_INTRINSIC_" + name.upper() +%> + +static inline ${data_type} +nir_intrinsic_${name}(const nir_intrinsic_instr *instr) +{ + const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; + assert(info->index_map[${enum}] > 0); +% if "struct" in data_type: + ${data_type} res; + STATIC_ASSERT(sizeof(instr->const_index[0]) == sizeof(res)); + memcpy(&res, &instr->const_index[info->index_map[${enum}] - 1], sizeof(res)); + return res; +% else: + return (${data_type})instr->const_index[info->index_map[${enum}] - 1]; +% endif +} + +static inline void +nir_intrinsic_set_${name}(nir_intrinsic_instr *instr, ${data_type} val) +{ + const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; + assert(info->index_map[${enum}] > 0); +% if "struct" in data_type: + val._pad = 0; /* clear padding bits */ + STATIC_ASSERT(sizeof(instr->const_index[0]) == sizeof(val)); + memcpy(&instr->const_index[info->index_map[${enum}] - 1], &val, sizeof(val)); +% else: + instr->const_index[info->index_map[${enum}] - 1] = val; +% endif +} + +static inline bool +nir_intrinsic_has_${name}(const nir_intrinsic_instr *instr) +{ + const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; + return info->index_map[${enum}] > 0; +} +% endfor + +#endif /* _NIR_INTRINSICS_INDICES_ */""" + +from nir_intrinsics import INTR_INDICES +from mako.template import Template +import argparse +import os + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--outdir', required=True, + help='Directory to put the generated files in') + + args = parser.parse_args() + + path = os.path.join(args.outdir, 'nir_intrinsics_indices.h') + with open(path, 'wb') as f: + f.write(Template(template, output_encoding='utf-8').render(INTR_INDICES=INTR_INDICES)) + +if __name__ == '__main__': + main() + diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index b03e703..43463cc 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -824,49 +824,12 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) fprintf(fp, ")"); - static const char *index_name[NIR_INTRINSIC_NUM_INDEX_FLAGS] = { - [NIR_INTRINSIC_BASE] = "base", - [NIR_INTRINSIC_WRMASK] = "wrmask", - [NIR_INTRINSIC_STREAM_ID] = "stream-id", - [NIR_INTRINSIC_UCP_ID] = "ucp-id", - [NIR_INTRINSIC_RANGE] = "range", - [NIR_INTRINSIC_RANGE_BASE] = "range_base", - [NIR_INTRINSIC_DESC_SET] = "desc-set", - [NIR_INTRINSIC_BINDING] = "binding", - [NIR_INTRINSIC_COMPONENT] = "component", - [NIR_INTRINSIC_COLUMN] = "column", - [NIR_INTRINSIC_INTERP_MODE] = "interp_mode", - [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_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", - [NIR_INTRINSIC_DESC_TYPE] = "desc_type", - [NIR_INTRINSIC_SRC_TYPE] = "src_type", - [NIR_INTRINSIC_DEST_TYPE] = "dest_type", - [NIR_INTRINSIC_SWIZZLE_MASK] = "swizzle_mask", - [NIR_INTRINSIC_DRIVER_LOCATION] = "driver_location", - [NIR_INTRINSIC_MEMORY_SEMANTICS] = "mem_semantics", - [NIR_INTRINSIC_MEMORY_MODES] = "mem_modes", - [NIR_INTRINSIC_MEMORY_SCOPE] = "mem_scope", - [NIR_INTRINSIC_EXECUTION_SCOPE] = "exec_scope", - [NIR_INTRINSIC_IO_SEMANTICS] = "io_semantics", - [NIR_INTRINSIC_ROUNDING_MODE] = "src_type", - [NIR_INTRINSIC_SATURATE] = "src_type", - }; - for (unsigned idx = 1; idx < NIR_INTRINSIC_NUM_INDEX_FLAGS; idx++) { if (!info->index_map[idx]) continue; fprintf(fp, " /*"); switch (idx) { - case NIR_INTRINSIC_WRMASK: { + case NIR_INTRINSIC_WRITE_MASK: { /* special case wrmask to show it as a writemask.. */ unsigned wrmask = nir_intrinsic_write_mask(instr); fprintf(fp, " wrmask="); @@ -972,7 +935,7 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) case NIR_INTRINSIC_EXECUTION_SCOPE: case NIR_INTRINSIC_MEMORY_SCOPE: { - fprintf(fp, " %s=", index_name[idx]); + fprintf(fp, " %s=", nir_intrinsic_index_names[idx]); nir_scope scope = idx == NIR_INTRINSIC_MEMORY_SCOPE ? nir_intrinsic_memory_scope(instr) : nir_intrinsic_execution_scope(instr); @@ -1039,8 +1002,7 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) default: { unsigned off = info->index_map[idx] - 1; - assert(index_name[idx]); /* forgot to update index_name table? */ - fprintf(fp, " %s=%d", index_name[idx], instr->const_index[off]); + fprintf(fp, " %s=%d", nir_intrinsic_index_names[idx], instr->const_index[off]); break; } } diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index 3e15d4f..0a2367a 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -66,7 +66,7 @@ static void scan_io_usage(struct si_shader_info *info, nir_intrinsic_instr *intr unsigned mask, bit_size; bool is_output_load; - if (nir_intrinsic_infos[intr->intrinsic].index_map[NIR_INTRINSIC_WRMASK] > 0) { + if (nir_intrinsic_has_write_mask(intr)) { mask = nir_intrinsic_write_mask(intr); /* store */ bit_size = nir_src_bit_size(intr->src[0]); is_output_load = false;