#include "util/list.h"
#include "util/ralloc.h"
#include "util/set.h"
+#include "util/bitscan.h"
#include "util/bitset.h"
#include "util/macros.h"
#include "compiler/nir_types.h"
typedef enum {
nir_var_shader_in = (1 << 0),
nir_var_shader_out = (1 << 1),
- nir_var_global = (1 << 2),
- nir_var_local = (1 << 3),
+ nir_var_shader_temp = (1 << 2),
+ nir_var_function = (1 << 3),
nir_var_uniform = (1 << 4),
- nir_var_shader_storage = (1 << 5),
+ nir_var_ubo = (1 << 5),
nir_var_system_value = (1 << 6),
+ nir_var_ssbo = (1 << 7),
nir_var_shared = (1 << 8),
nir_var_all = ~0,
} nir_variable_mode;
} nir_rounding_mode;
typedef union {
+ bool b[NIR_MAX_VEC_COMPONENTS];
float f32[NIR_MAX_VEC_COMPONENTS];
double f64[NIR_MAX_VEC_COMPONENTS];
int8_t i8[NIR_MAX_VEC_COMPONENTS];
* ARB_shader_image_load_store qualifiers.
*/
struct {
- bool read_only; /**< "readonly" qualifier. */
- bool write_only; /**< "writeonly" qualifier. */
- bool coherent;
- bool _volatile;
- bool restrict_flag;
+ enum gl_access_qualifier access;
/** Image internal format if specified explicitly, otherwise GL_NONE. */
GLenum format;
static inline bool
nir_variable_is_global(const nir_variable *var)
{
- return var->data.mode != nir_var_local;
+ return var->data.mode != nir_var_function;
}
typedef struct nir_register {
#define nir_foreach_register_safe(reg, reg_list) \
foreach_list_typed_safe(nir_register, reg, node, reg_list)
-typedef enum {
+typedef enum PACKED {
nir_instr_type_alu,
nir_instr_type_deref,
nir_instr_type_call,
typedef struct nir_instr {
struct exec_node node;
- nir_instr_type type;
struct nir_block *block;
-
- /** generic instruction index. */
- unsigned index;
+ nir_instr_type type;
/* A temporary for optimization and analysis passes to use for storing
* flags. For instance, DCE uses this to store the "dead/live" info.
*/
uint8_t pass_flags;
+
+ /** generic instruction index. */
+ unsigned index;
} nir_instr;
static inline nir_instr *
return src.is_ssa ? src.ssa->num_components : src.reg.reg->num_components;
}
+static inline bool
+nir_src_is_const(nir_src src)
+{
+ return src.is_ssa &&
+ src.ssa->parent_instr->type == nir_instr_type_load_const;
+}
+
+int64_t nir_src_as_int(nir_src src);
+uint64_t nir_src_as_uint(nir_src src);
+bool nir_src_as_bool(nir_src src);
+double nir_src_as_float(nir_src src);
+int64_t nir_src_comp_as_int(nir_src src, unsigned component);
+uint64_t nir_src_comp_as_uint(nir_src src, unsigned component);
+bool nir_src_comp_as_bool(nir_src src, unsigned component);
+double nir_src_comp_as_float(nir_src src, unsigned component);
+
static inline unsigned
nir_dest_bit_size(nir_dest dest)
{
unsigned write_mask : NIR_MAX_VEC_COMPONENTS; /* ignored if dest.is_ssa is true */
} nir_alu_dest;
+/** NIR sized and unsized types
+ *
+ * The values in this enum are carefully chosen so that the sized type is
+ * just the unsized type OR the number of bits.
+ */
typedef enum {
nir_type_invalid = 0, /* Not a valid type */
- nir_type_float,
- nir_type_int,
- nir_type_uint,
- nir_type_bool,
+ nir_type_int = 2,
+ nir_type_uint = 4,
+ nir_type_bool = 6,
+ nir_type_float = 128,
+ nir_type_bool1 = 1 | nir_type_bool,
nir_type_bool32 = 32 | nir_type_bool,
+ nir_type_int1 = 1 | nir_type_int,
nir_type_int8 = 8 | nir_type_int,
nir_type_int16 = 16 | nir_type_int,
nir_type_int32 = 32 | nir_type_int,
nir_type_int64 = 64 | nir_type_int,
+ nir_type_uint1 = 1 | nir_type_uint,
nir_type_uint8 = 8 | nir_type_uint,
nir_type_uint16 = 16 | nir_type_uint,
nir_type_uint32 = 32 | nir_type_uint,
nir_type_float64 = 64 | nir_type_float,
} nir_alu_type;
-#define NIR_ALU_TYPE_SIZE_MASK 0xfffffff8
-#define NIR_ALU_TYPE_BASE_TYPE_MASK 0x00000007
+#define NIR_ALU_TYPE_SIZE_MASK 0x79
+#define NIR_ALU_TYPE_BASE_TYPE_MASK 0x86
static inline unsigned
nir_alu_type_get_type_size(nir_alu_type type)
{
switch (base_type) {
case GLSL_TYPE_BOOL:
- return nir_type_bool32;
+ return nir_type_bool1;
break;
case GLSL_TYPE_UINT:
return nir_type_uint32;
return (instr->dest.write_mask >> channel) & 1;
}
+static inline nir_component_mask_t
+nir_alu_instr_src_read_mask(const nir_alu_instr *instr, unsigned src)
+{
+ nir_component_mask_t read_mask = 0;
+ for (unsigned c = 0; c < NIR_MAX_VEC_COMPONENTS; c++) {
+ if (!nir_alu_instr_channel_used(instr, src, c))
+ continue;
+
+ read_mask |= (1 << instr->src[src].swizzle[c]);
+ }
+ return read_mask;
+}
+
/*
* For instructions whose destinations are SSA, get the number of channels
* used for a source
nir_deref_type_var,
nir_deref_type_array,
nir_deref_type_array_wildcard,
+ nir_deref_type_ptr_as_array,
nir_deref_type_struct,
nir_deref_type_cast,
} nir_deref_type;
struct {
unsigned index;
} strct;
+
+ struct {
+ unsigned ptr_stride;
+ } cast;
};
/** Destination to store the resulting "pointer" */
bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr);
+unsigned nir_deref_instr_ptr_as_array_stride(nir_deref_instr *instr);
+
typedef struct {
nir_instr instr;
#include "nir_intrinsics.h"
-#define NIR_INTRINSIC_MAX_CONST_INDEX 3
+#define NIR_INTRINSIC_MAX_CONST_INDEX 4
/** Represents an intrinsic
*
*/
NIR_INTRINSIC_PARAM_IDX = 12,
+ /**
+ * Image dimensionality for image intrinsics
+ *
+ * One of GLSL_SAMPLER_DIM_*
+ */
+ NIR_INTRINSIC_IMAGE_DIM = 13,
+
+ /**
+ * Non-zero if we are accessing an array image
+ */
+ NIR_INTRINSIC_IMAGE_ARRAY = 14,
+
+ /**
+ * Image format for image intrinsics
+ */
+ NIR_INTRINSIC_FORMAT = 15,
+
+ /**
+ * Access qualifiers for image and memory access intrinsics
+ */
+ NIR_INTRINSIC_ACCESS = 16,
+
+ /**
+ * Alignment for offsets and addresses
+ *
+ * These two parameters, specify an alignment in terms of a multiplier and
+ * an offset. The offset or address parameter X of the intrinsic is
+ * guaranteed to satisfy the following:
+ *
+ * (X - align_offset) % align_mul == 0
+ */
+ NIR_INTRINSIC_ALIGN_MUL = 17,
+ NIR_INTRINSIC_ALIGN_OFFSET = 18,
+
+ /**
+ * The Vulkan descriptor type for a vulkan_resource_[re]index intrinsic.
+ */
+ NIR_INTRINSIC_DESC_TYPE = 19,
+
NIR_INTRINSIC_NUM_INDEX_FLAGS,
} nir_intrinsic_index_flag;
/** number of components of each input register
*
* If this value is 0, the number of components is given by the
- * num_components field of nir_intrinsic_instr.
+ * num_components field of nir_intrinsic_instr. If this value is -1, the
+ * intrinsic consumes however many components are provided and it is not
+ * validated at all.
*/
- unsigned src_components[NIR_INTRINSIC_MAX_INPUTS];
+ int src_components[NIR_INTRINSIC_MAX_INPUTS];
bool has_dest;
{
const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic];
assert(srcn < info->num_srcs);
- if (info->src_components[srcn])
+ if (info->src_components[srcn] > 0)
return info->src_components[srcn];
- else
+ else if (info->src_components[srcn] == 0)
return intr->num_components;
+ else
+ return nir_src_num_components(intr->src[srcn]);
}
static inline unsigned
{ \
const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; \
assert(info->index_map[NIR_INTRINSIC_##flag] > 0); \
- return instr->const_index[info->index_map[NIR_INTRINSIC_##flag] - 1]; \
+ return (type)instr->const_index[info->index_map[NIR_INTRINSIC_##flag] - 1]; \
} \
static inline void \
nir_intrinsic_set_##name(nir_intrinsic_instr *instr, type val) \
INTRINSIC_IDX_ACCESSORS(reduction_op, REDUCTION_OP, unsigned)
INTRINSIC_IDX_ACCESSORS(cluster_size, CLUSTER_SIZE, unsigned)
INTRINSIC_IDX_ACCESSORS(param_idx, PARAM_IDX, unsigned)
+INTRINSIC_IDX_ACCESSORS(image_dim, IMAGE_DIM, enum glsl_sampler_dim)
+INTRINSIC_IDX_ACCESSORS(image_array, IMAGE_ARRAY, bool)
+INTRINSIC_IDX_ACCESSORS(access, ACCESS, enum gl_access_qualifier)
+INTRINSIC_IDX_ACCESSORS(format, FORMAT, unsigned)
+INTRINSIC_IDX_ACCESSORS(align_mul, ALIGN_MUL, unsigned)
+INTRINSIC_IDX_ACCESSORS(align_offset, ALIGN_OFFSET, unsigned)
+INTRINSIC_IDX_ACCESSORS(desc_type, DESC_TYPE, unsigned)
+
+static inline void
+nir_intrinsic_set_align(nir_intrinsic_instr *intrin,
+ unsigned align_mul, unsigned align_offset)
+{
+ assert(util_is_power_of_two_nonzero(align_mul));
+ assert(align_offset < align_mul);
+ nir_intrinsic_set_align_mul(intrin, align_mul);
+ nir_intrinsic_set_align_offset(intrin, align_offset);
+}
+
+/** Returns a simple alignment for a load/store intrinsic offset
+ *
+ * Instead of the full mul+offset alignment scheme provided by the ALIGN_MUL
+ * and ALIGN_OFFSET parameters, this helper takes both into account and
+ * provides a single simple alignment parameter. The offset X is guaranteed
+ * to satisfy X % align == 0.
+ */
+static inline unsigned
+nir_intrinsic_align(const nir_intrinsic_instr *intrin)
+{
+ const unsigned align_mul = nir_intrinsic_align_mul(intrin);
+ const unsigned align_offset = nir_intrinsic_align_offset(intrin);
+ assert(align_offset < align_mul);
+ return align_offset ? 1 << (ffs(align_offset) - 1) : align_mul;
+}
/**
* \group texture information
nir_tex_src_offset,
nir_tex_src_bias,
nir_tex_src_lod,
+ nir_tex_src_min_lod,
nir_tex_src_ms_index, /* MSAA sample index */
nir_tex_src_ms_mcs, /* MSAA compression value */
nir_tex_src_ddx,
case nir_op_uge:
case nir_op_ieq:
case nir_op_ine:
- case nir_op_i2b:
- case nir_op_f2b:
+ case nir_op_i2b1:
+ case nir_op_f2b1:
case nir_op_inot:
case nir_op_fnot:
return true;
return exec_node_data(nir_instr, tail, node);
}
+static inline bool
+nir_block_ends_in_jump(nir_block *block)
+{
+ return !exec_list_is_empty(&block->instr_list) &&
+ nir_block_last_instr(block)->type == nir_instr_type_jump;
+}
+
#define nir_foreach_instr(instr, block) \
foreach_list_typed(nir_instr, instr, node, &(block)->instr_list)
#define nir_foreach_instr_reverse(instr, block) \
/* Number of instructions in the loop */
unsigned num_instructions;
- /* How many times the loop is run (if known) */
- unsigned trip_count;
- bool is_trip_count_known;
+ /* Maximum number of times the loop is run (if known) */
+ unsigned max_trip_count;
+
+ /* Do we know the exact number of times the loop will be run */
+ bool exact_trip_count_known;
/* Unroll the loop regardless of its size */
bool force_unroll;
+ /* Does the loop contain complex loop terminators, continues or other
+ * complex behaviours? If this is true we can't rely on
+ * loop_terminator_list to be complete or accurate.
+ */
+ bool complex_loop;
+
nir_loop_terminator *limiting_terminator;
/* A list of loop_terminators terminating this loop. */
* If the function is only declared and not implemented, this is NULL.
*/
nir_function_impl *impl;
+
+ bool is_entrypoint;
} nir_function;
typedef struct nir_shader_compiler_options {
/** enables rules to lower idiv by power-of-two: */
bool lower_idiv;
- /* lower b2f to iand */
- bool lower_b2f;
-
/* Does the native fdot instruction replicate its result for four
* components? If so, then opt_algebraic_late will turn all fdotN
* instructions into fdot_replicatedN instructions.
*/
bool fdot_replicates;
+ /** lowers ffloor to fsub+ffract: */
+ bool lower_ffloor;
+
/** lowers ffract to fsub+ffloor: */
bool lower_ffract;
+ /** lowers fceil to fneg+ffloor+fneg: */
+ bool lower_fceil;
+
bool lower_ldexp;
bool lower_pack_half_2x16;
bool lower_helper_invocation;
bool lower_cs_local_index_from_id;
+ bool lower_cs_local_id_from_index;
bool lower_device_index_to_zero;
*/
bool use_interpolated_input_intrinsics;
- /**
- * Do vertex shader double inputs use two locations? The Vulkan spec
- * requires two locations to be used, OpenGL allows a single location.
- */
- bool vs_inputs_dual_locations;
-
unsigned max_unroll_iterations;
} nir_shader_compiler_options;
unsigned constant_data_size;
} nir_shader;
+#define nir_foreach_function(func, shader) \
+ foreach_list_typed(nir_function, func, node, &(shader)->functions)
+
static inline nir_function_impl *
nir_shader_get_entrypoint(nir_shader *shader)
{
- assert(exec_list_length(&shader->functions) == 1);
- struct exec_node *func_node = exec_list_get_head(&shader->functions);
- nir_function *func = exec_node_data(nir_function, func_node, node);
+ nir_function *func = NULL;
+
+ nir_foreach_function(function, shader) {
+ assert(func == NULL);
+ if (function->is_entrypoint) {
+ func = function;
+#ifndef NDEBUG
+ break;
+#endif
+ }
+ }
+
+ if (!func)
+ return NULL;
+
assert(func->num_params == 0);
assert(func->impl);
return func->impl;
}
-#define nir_foreach_function(func, shader) \
- foreach_list_typed(nir_function, func, node, &(shader)->functions)
-
nir_shader *nir_shader_create(void *mem_ctx,
gl_shader_stage stage,
const nir_shader_compiler_options *options,
static inline void
nir_function_impl_add_variable(nir_function_impl *impl, nir_variable *var)
{
- assert(var->data.mode == nir_var_local);
+ assert(var->data.mode == nir_var_function);
exec_list_push_tail(&impl->locals, &var->node);
}
}
}
+static inline nir_cursor
+nir_before_src(nir_src *src, bool is_if_condition)
+{
+ if (is_if_condition) {
+ nir_block *prev_block =
+ nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node));
+ assert(!nir_block_ends_in_jump(prev_block));
+ return nir_after_block(prev_block);
+ } else if (src->parent_instr->type == nir_instr_type_phi) {
+#ifndef NDEBUG
+ nir_phi_instr *cond_phi = nir_instr_as_phi(src->parent_instr);
+ bool found = false;
+ nir_foreach_phi_src(phi_src, cond_phi) {
+ if (phi_src->src.ssa == src->ssa) {
+ found = true;
+ break;
+ }
+ }
+ assert(found);
+#endif
+ /* The LIST_ENTRY macro is a generic container-of macro, it just happens
+ * to have a more specific name.
+ */
+ nir_phi_src *phi_src = LIST_ENTRY(nir_phi_src, src, src);
+ return nir_after_block_before_jump(phi_src->pred);
+ } else {
+ return nir_before_instr(src->parent_instr);
+ }
+}
+
static inline nir_cursor
nir_before_cf_node(nir_cf_node *node)
{
bool nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state);
nir_const_value *nir_src_as_const_value(nir_src src);
+
+static inline struct nir_instr *
+nir_src_instr(const struct nir_src *src)
+{
+ return src->is_ssa ? src->ssa->parent_instr : NULL;
+}
+
+#define NIR_SRC_AS_(name, c_type, type_enum, cast_macro) \
+static inline c_type * \
+nir_src_as_ ## name (struct nir_src *src) \
+{ \
+ return src->is_ssa && src->ssa->parent_instr->type == type_enum \
+ ? cast_macro(src->ssa->parent_instr) : NULL; \
+} \
+static inline const c_type * \
+nir_src_as_ ## name ## _const(const struct nir_src *src) \
+{ \
+ return src->is_ssa && src->ssa->parent_instr->type == type_enum \
+ ? cast_macro(src->ssa->parent_instr) : NULL; \
+}
+
+NIR_SRC_AS_(alu_instr, nir_alu_instr, nir_instr_type_alu, nir_instr_as_alu)
+
bool nir_src_is_dynamically_uniform(nir_src src);
bool nir_srcs_equal(nir_src src1, nir_src src2);
void nir_instr_rewrite_src(nir_instr *instr, nir_src *src, nir_src new_src);
void nir_print_shader(nir_shader *shader, FILE *fp);
void nir_print_shader_annotated(nir_shader *shader, FILE *fp, struct hash_table *errors);
void nir_print_instr(const nir_instr *instr, FILE *fp);
+void nir_print_deref(const nir_deref_instr *deref, FILE *fp);
nir_shader *nir_shader_clone(void *mem_ctx, const nir_shader *s);
nir_function_impl *nir_function_impl_clone(const nir_function_impl *fi);
nir_shader *nir_shader_serialize_deserialize(void *mem_ctx, nir_shader *s);
#ifndef NDEBUG
-void nir_validate_shader(nir_shader *shader);
+void nir_validate_shader(nir_shader *shader, const char *when);
void nir_metadata_set_validation_flag(nir_shader *shader);
void nir_metadata_check_validation_flag(nir_shader *shader);
+static inline bool
+should_skip_nir(const char *name)
+{
+ static const char *list = NULL;
+ if (!list) {
+ /* Comma separated list of names to skip. */
+ list = getenv("NIR_SKIP");
+ if (!list)
+ list = "";
+ }
+
+ if (!list[0])
+ return false;
+
+ return comma_separated_list_contains(list, name);
+}
+
static inline bool
should_clone_nir(void)
{
return should_print;
}
#else
-static inline void nir_validate_shader(nir_shader *shader) { (void) shader; }
+static inline void nir_validate_shader(nir_shader *shader, const char *when) { (void) shader; (void)when; }
static inline void nir_metadata_set_validation_flag(nir_shader *shader) { (void) shader; }
static inline void nir_metadata_check_validation_flag(nir_shader *shader) { (void) shader; }
+static inline bool should_skip_nir(const char *pass_name) { return false; }
static inline bool should_clone_nir(void) { return false; }
static inline bool should_serialize_deserialize_nir(void) { return false; }
static inline bool should_print_nir(void) { return false; }
#endif /* NDEBUG */
-#define _PASS(nir, do_pass) do { \
+#define _PASS(pass, nir, do_pass) do { \
+ if (should_skip_nir(#pass)) { \
+ printf("skipping %s\n", #pass); \
+ break; \
+ } \
do_pass \
- nir_validate_shader(nir); \
+ nir_validate_shader(nir, "after " #pass); \
if (should_clone_nir()) { \
nir_shader *clone = nir_shader_clone(ralloc_parent(nir), nir); \
ralloc_free(nir); \
} \
} while (0)
-#define NIR_PASS(progress, nir, pass, ...) _PASS(nir, \
+#define NIR_PASS(progress, nir, pass, ...) _PASS(pass, nir, \
nir_metadata_set_validation_flag(nir); \
if (should_print_nir()) \
printf("%s\n", #pass); \
} \
)
-#define NIR_PASS_V(nir, pass, ...) _PASS(nir, \
+#define NIR_PASS_V(nir, pass, ...) _PASS(pass, nir, \
if (should_print_nir()) \
printf("%s\n", #pass); \
pass(nir, ##__VA_ARGS__); \
nir_print_shader(nir, stdout); \
)
+#define NIR_SKIP(name) should_skip_nir(#name)
+
void nir_calc_dominance_impl(nir_function_impl *impl);
void nir_calc_dominance(nir_shader *shader);
int nir_gs_count_vertices(const nir_shader *shader);
+bool nir_shrink_vec_array_vars(nir_shader *shader, nir_variable_mode modes);
+bool nir_split_array_vars(nir_shader *shader, nir_variable_mode modes);
bool nir_split_var_copies(nir_shader *shader);
bool nir_split_per_member_structs(nir_shader *shader);
+bool nir_split_struct_vars(nir_shader *shader, nir_variable_mode modes);
bool nir_lower_returns_impl(nir_function_impl *impl);
bool nir_lower_returns(nir_shader *shader);
/* Some helpers to do very simple linking */
bool nir_remove_unused_varyings(nir_shader *producer, nir_shader *consumer);
+bool nir_remove_unused_io_vars(nir_shader *shader, struct exec_list *var_list,
+ uint64_t *used_by_other_stage,
+ uint64_t *used_by_other_stage_patches);
void nir_compact_varyings(nir_shader *producer, nir_shader *consumer,
bool default_to_smooth_interp);
+void nir_link_xfb_varyings(nir_shader *producer, nir_shader *consumer);
+bool nir_link_opt_varyings(nir_shader *producer, nir_shader *consumer);
typedef enum {
/* If set, this forces all non-flat fragment shader inputs to be
nir_variable_mode modes,
int (*type_size)(const struct glsl_type *),
nir_lower_io_options);
+
+typedef enum {
+ /**
+ * An address format which is comprised of a vec2 where the first
+ * component is a vulkan descriptor index and the second is an offset.
+ */
+ nir_address_format_vk_index_offset,
+} nir_address_format;
+bool nir_lower_explicit_io(nir_shader *shader,
+ nir_variable_mode modes,
+ nir_address_format);
+
nir_src *nir_get_io_offset_src(nir_intrinsic_instr *instr);
nir_src *nir_get_io_vertex_index_src(nir_intrinsic_instr *instr);
bool alpha_to_one);
bool nir_lower_alu(nir_shader *shader);
bool nir_lower_alu_to_scalar(nir_shader *shader);
+bool nir_lower_bool_to_float(nir_shader *shader);
+bool nir_lower_bool_to_int32(nir_shader *shader);
bool nir_lower_load_const_to_scalar(nir_shader *shader);
bool nir_lower_read_invocation_to_scalar(nir_shader *shader);
bool nir_lower_phis_to_scalar(nir_shader *shader);
bool nir_lower_system_values(nir_shader *shader);
+enum PACKED nir_lower_tex_packing {
+ nir_lower_tex_packing_none = 0,
+ /* The sampler returns up to 2 32-bit words of half floats or 16-bit signed
+ * or unsigned ints based on the sampler type
+ */
+ nir_lower_tex_packing_16,
+ /* The sampler returns 1 32-bit word of 4x8 unorm */
+ nir_lower_tex_packing_8,
+};
+
typedef struct nir_lower_tex_options {
/**
* bitmask of (1 << GLSL_SAMPLER_DIM_x) to control for which
unsigned lower_y_u_v_external;
unsigned lower_yx_xuxv_external;
unsigned lower_xy_uxvx_external;
+ unsigned lower_ayuv_external;
/**
* To emulate certain texture wrap modes, this can be used
*/
bool lower_txd_cube_map;
+ /**
+ * If true, lower nir_texop_txd on 3D surfaces with nir_texop_txl.
+ */
+ bool lower_txd_3d;
+
/**
* If true, lower nir_texop_txd on shadow samplers (except cube maps)
* with nir_texop_txl. Notice that cube map shadow samplers are lowered
* Implies lower_txd_cube_map and lower_txd_shadow.
*/
bool lower_txd;
+
+ /**
+ * If true, lower nir_texop_txb that try to use shadow compare and min_lod
+ * at the same time to a nir_texop_lod, some math, and nir_texop_tex.
+ */
+ bool lower_txb_shadow_clamp;
+
+ /**
+ * If true, lower nir_texop_txd on shadow samplers when it uses min_lod
+ * with nir_texop_txl. This includes cube maps.
+ */
+ bool lower_txd_shadow_clamp;
+
+ /**
+ * If true, lower nir_texop_txd on when it uses both offset and min_lod
+ * with nir_texop_txl. This includes cube maps.
+ */
+ bool lower_txd_offset_clamp;
+
+ /**
+ * If true, apply a .bagr swizzle on tg4 results to handle Broadcom's
+ * mixed-up tg4 locations.
+ */
+ bool lower_tg4_broadcom_swizzle;
+
+ enum nir_lower_tex_packing lower_tex_packing[32];
} nir_lower_tex_options;
bool nir_lower_tex(nir_shader *shader,
bool nir_lower_idiv(nir_shader *shader);
-bool nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables);
+bool nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars);
bool nir_lower_clip_fs(nir_shader *shader, unsigned ucp_enables);
bool nir_lower_clip_cull_distance_arrays(nir_shader *nir);
void nir_lower_bitmap(nir_shader *shader, const nir_lower_bitmap_options *options);
bool nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset);
-bool nir_lower_to_source_mods(nir_shader *shader);
+
+typedef enum {
+ nir_lower_int_source_mods = 1 << 0,
+ nir_lower_float_source_mods = 1 << 1,
+ nir_lower_all_source_mods = (1 << 2) - 1
+} nir_lower_to_source_mods_flags;
+
+
+bool nir_lower_to_source_mods(nir_shader *shader, nir_lower_to_source_mods_flags options);
bool nir_lower_gs_intrinsics(nir_shader *shader);
nir_lower_isign64 = (1 << 1),
/** Lower all int64 modulus and division opcodes */
nir_lower_divmod64 = (1 << 2),
+ /** Lower all 64-bit umul_high and imul_high opcodes */
+ nir_lower_imul_high64 = (1 << 3),
+ nir_lower_mov64 = (1 << 4),
+ nir_lower_icmp64 = (1 << 5),
+ nir_lower_iadd64 = (1 << 6),
+ nir_lower_iabs64 = (1 << 7),
+ nir_lower_ineg64 = (1 << 8),
+ nir_lower_logic64 = (1 << 9),
+ nir_lower_minmax64 = (1 << 10),
+ nir_lower_shift64 = (1 << 11),
} nir_lower_int64_options;
bool nir_lower_int64(nir_shader *shader, nir_lower_int64_options options);
nir_lower_dceil = (1 << 5),
nir_lower_dfract = (1 << 6),
nir_lower_dround_even = (1 << 7),
- nir_lower_dmod = (1 << 8)
+ nir_lower_dmod = (1 << 8),
+ nir_lower_fp64_full_software = (1 << 9),
} nir_lower_doubles_options;
bool nir_lower_doubles(nir_shader *shader, nir_lower_doubles_options options);
bool nir_lower_phis_to_regs_block(nir_block *block);
bool nir_lower_ssa_defs_to_regs_block(nir_block *block);
+bool nir_rematerialize_derefs_in_use_blocks_impl(nir_function_impl *impl);
bool nir_opt_algebraic(nir_shader *shader);
bool nir_opt_algebraic_before_ffma(nir_shader *shader);
bool nir_opt_dead_cf(nir_shader *shader);
+bool nir_opt_dead_write_vars(nir_shader *shader);
+
+bool nir_opt_deref(nir_shader *shader);
+
+bool nir_opt_find_array_copies(nir_shader *shader);
+
bool nir_opt_gcm(nir_shader *shader, bool value_number);
+bool nir_opt_idiv_const(nir_shader *shader, unsigned min_bit_size);
+
bool nir_opt_if(nir_shader *shader);
bool nir_opt_intrinsics(nir_shader *shader);
bool nir_opt_move_load_ubo(nir_shader *shader);
-bool nir_opt_peephole_select(nir_shader *shader, unsigned limit);
+bool nir_opt_peephole_select(nir_shader *shader, unsigned limit,
+ bool indirect_load_ok, bool expensive_alu_ok);
-bool nir_opt_remove_phis_impl(nir_function_impl *impl);
bool nir_opt_remove_phis(nir_shader *shader);
bool nir_opt_shrink_load(nir_shader *shader);
void nir_sweep(nir_shader *shader);
-void nir_remap_attributes(nir_shader *shader,
- const nir_shader_compiler_options *options);
+void nir_remap_dual_slot_attributes(nir_shader *shader,
+ uint64_t *dual_slot_inputs);
+uint64_t nir_get_single_slot_attribs_mask(uint64_t attribs, uint64_t dual_slot);
nir_intrinsic_op nir_intrinsic_from_system_value(gl_system_value val);
gl_system_value nir_system_value_from_intrinsic(nir_intrinsic_op intrin);