nir: use a single canonical list of intrinsic indices

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6587>
This commit is contained in:
Rhys Perry 2020-11-24 12:51:59 +00:00 committed by Marge Bot
parent f6407b9b7d
commit 898d7c1f49
12 changed files with 293 additions and 410 deletions

View file

@ -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)

View file

@ -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

View file

@ -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')

View file

@ -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('.'),
)

View file

@ -1774,196 +1774,6 @@ typedef enum {
NIR_INTRINSIC_CAN_REORDER = (1 << 1),
} 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).
*
@ -1971,7 +1781,7 @@ typedef enum {
*/
#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);

View file

@ -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')

View file

@ -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)
@ -73,81 +78,6 @@ class Intrinsic(object):
self.sysval = sysval
self.bit_sizes = 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"
# 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"
# Component offset
COMPONENT = "NIR_INTRINSIC_COMPONENT"
# Column index for matrix system values
COLUMN = "NIR_INTRINSIC_COLUMN"
# Interpolation mode (only meaningful for FS inputs)
INTERP_MODE = "NIR_INTRINSIC_INTERP_MODE"
# A binary nir_op to use when performing a reduction or scan operation
REDUCTION_OP = "NIR_INTRINSIC_REDUCTION_OP"
# Cluster size for reduction operations
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 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
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"
# The nir_alu_type of input data to a store or conversion
SRC_TYPE = "NIR_INTRINSIC_SRC_TYPE"
# The nir_alu_type of the data output from a load or conversion
DEST_TYPE = "NIR_INTRINSIC_DEST_TYPE"
# The swizzle mask for quad_swizzle_amd & masked_swizzle_amd
SWIZZLE_MASK = "NIR_INTRINSIC_SWIZZLE_MASK"
# Driver location of attribute
DRIVER_LOCATION = "NIR_INTRINSIC_DRIVER_LOCATION"
# Ordering and visibility of a memory operation
MEMORY_SEMANTICS = "NIR_INTRINSIC_MEMORY_SEMANTICS"
# Modes affected by a memory operation
MEMORY_MODES = "NIR_INTRINSIC_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"
#
# Possible flags:
#
@ -155,8 +85,14 @@ SATURATE = "NIR_INTRINSIC_SATURATE"
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.
#
@ -174,6 +110,126 @@ def intrinsic(name, src_comp=[], dest_comp=-1, indices=[],
INTR_OPCODES[name] = Intrinsic(name, src_comp, dest_comp,
indices, flags, sysval, bit_sizes)
#
# Possible indices:
#
# 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.
#
# 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
index("unsigned", "component")
# Column index for matrix system values
index("unsigned", "column")
# Interpolation mode (only meaningful for FS inputs)
index("unsigned", "interp_mode")
# A binary nir_op to use when performing a reduction or scan operation
index("unsigned", "reduction_op")
# Cluster size for reduction operations
index("unsigned", "cluster_size")
# Parameter index for a load_param intrinsic
index("unsigned", "param_idx")
# Image dimensionality for image intrinsics
index("enum glsl_sampler_dim", "image_dim")
# Non-zero if we are accessing an array image
index("bool", "image_array")
# Image format for image intrinsics
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
index("nir_alu_type", "src_type")
# The nir_alu_type of the data output from a load or conversion
index("nir_alu_type", "dest_type")
# The swizzle mask for quad_swizzle_amd & masked_swizzle_amd
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
index("unsigned", "driver_location")
# Ordering and visibility of a memory operation
index("nir_memory_semantics", "memory_semantics")
# Modes affected by a memory operation
index("nir_variable_mode", "memory_modes")
# Scope of a memory operation
index("nir_scope", "memory_scope")
# Scope of a control barrier
index("nir_scope", "execution_scope")
# Semantics of an IO instruction
index("struct nir_io_semantics", "io_semantics")
# Rounding mode for conversions
index("nir_rounding_mode", "rounding_mode")
# Whether or not to saturate in conversions
index("unsigned", "saturate")
intrinsic("nop", flags=[CAN_ELIMINATE])
intrinsic("convert_alu_types", dest_comp=0, src_comp=[0],
@ -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)

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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;
}
}

View file

@ -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;