$(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)
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
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')
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',
'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',
# 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('.'),
)
} 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;
}
}
-#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,
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);
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:
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')
# 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.
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)
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])
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])
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
# 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])
# 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.
# 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])
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)
% 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
},
% 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
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()
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
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()
--- /dev/null
+
+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()
+
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=");
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);
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;
}
}
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;