#define NIR_FALSE 0u
#define NIR_TRUE (~0u)
#define NIR_MAX_VEC_COMPONENTS 4
+#define NIR_MAX_MATRIX_COLUMNS 4
typedef uint8_t nir_component_mask_t;
/** Defines a cast function
} 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];
- uint8_t u8[NIR_MAX_VEC_COMPONENTS];
- int16_t i16[NIR_MAX_VEC_COMPONENTS];
- uint16_t u16[NIR_MAX_VEC_COMPONENTS];
- int32_t i32[NIR_MAX_VEC_COMPONENTS];
- uint32_t u32[NIR_MAX_VEC_COMPONENTS];
- int64_t i64[NIR_MAX_VEC_COMPONENTS];
- uint64_t u64[NIR_MAX_VEC_COMPONENTS];
+ bool b;
+ float f32;
+ double f64;
+ int8_t i8;
+ uint8_t u8;
+ int16_t i16;
+ uint16_t u16;
+ int32_t i32;
+ uint32_t u32;
+ int64_t i64;
+ uint64_t u64;
} nir_const_value;
+#define nir_const_value_to_array(arr, c, components, m) \
+{ \
+ for (unsigned i = 0; i < components; ++i) \
+ arr[i] = c[i].m; \
+} while (false)
+
typedef struct nir_constant {
/**
* Value of the constant.
* by the type associated with the \c nir_variable. Constants may be
* scalars, vectors, or matrices.
*/
- nir_const_value values[NIR_MAX_VEC_COMPONENTS];
+ nir_const_value values[NIR_MAX_MATRIX_COLUMNS][NIR_MAX_VEC_COMPONENTS];
/* we could get this from the var->type but makes clone *much* easier to
* not have to care about the type.
/** only for debug purposes, can be NULL */
const char *name;
- /** whether this register is local (per-function) or global (per-shader) */
- bool is_global;
-
- /**
- * If this flag is set to true, then accessing channels >= num_components
- * is well-defined, and simply spills over to the next array element. This
- * is useful for backends that can do per-component accessing, in
- * particular scalar backends. By setting this flag and making
- * num_components equal to 1, structures can be packed tightly into
- * registers and then registers can be accessed per-component to get to
- * each structure member, even if it crosses vec4 boundaries.
- */
- bool is_packed;
-
/** set of nir_srcs where this register is used (read from) */
struct list_head uses;
case GLSL_TYPE_DOUBLE:
return nir_type_float64;
break;
- default:
- unreachable("unknown type");
+
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_STRUCT:
+ case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_ARRAY:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_SUBROUTINE:
+ case GLSL_TYPE_FUNCTION:
+ case GLSL_TYPE_ERROR:
+ return nir_type_invalid;
}
+
+ unreachable("unknown type");
}
static inline nir_alu_type
nir_op nir_type_conversion_op(nir_alu_type src, nir_alu_type dst,
nir_rounding_mode rnd);
+static inline nir_op
+nir_op_vec(unsigned components)
+{
+ switch (components) {
+ case 1: return nir_op_mov;
+ case 2: return nir_op_vec2;
+ case 3: return nir_op_vec3;
+ case 4: return nir_op_vec4;
+ default: unreachable("bad component count");
+ }
+}
+
typedef enum {
- NIR_OP_IS_COMMUTATIVE = (1 << 0),
+ /**
+ * Operation where the first two sources are commutative.
+ *
+ * For 2-source operations, this just mathematical commutativity. Some
+ * 3-source operations, like ffma, are only commutative in the first two
+ * sources.
+ */
+ NIR_OP_IS_2SRC_COMMUTATIVE = (1 << 0),
NIR_OP_IS_ASSOCIATIVE = (1 << 1),
} nir_op_algebraic_property;
return instr->dest.dest.ssa.num_components;
}
+bool nir_const_value_negative_equal(const nir_const_value *c1,
+ const nir_const_value *c2,
+ unsigned components,
+ nir_alu_type base_type,
+ unsigned bits);
+
bool nir_alu_srcs_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2,
unsigned src1, unsigned src2);
+bool nir_alu_srcs_negative_equal(const nir_alu_instr *alu1,
+ const nir_alu_instr *alu2,
+ unsigned src1, unsigned src2);
+
typedef enum {
nir_deref_type_var,
nir_deref_type_array,
nir_dest dest;
} nir_deref_instr;
-NIR_DEFINE_CAST(nir_instr_as_deref, nir_instr, nir_deref_instr, instr,
- type, nir_instr_type_deref)
-
-static inline nir_deref_instr *
-nir_src_as_deref(nir_src src)
-{
- if (!src.is_ssa)
- return NULL;
-
- if (src.ssa->parent_instr->type != nir_instr_type_deref)
- return NULL;
-
- return nir_instr_as_deref(src.ssa->parent_instr);
-}
+static inline nir_deref_instr *nir_src_as_deref(nir_src src);
static inline nir_deref_instr *
nir_deref_instr_parent(const nir_deref_instr *instr)
}
bool nir_deref_instr_has_indirect(nir_deref_instr *instr);
+bool nir_deref_instr_has_complex_use(nir_deref_instr *instr);
bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr);
*/
NIR_INTRINSIC_DESC_TYPE = 19,
+ /**
+ * The nir_alu_type of a uniform/input/output
+ */
+ NIR_INTRINSIC_TYPE = 20,
+
NIR_INTRINSIC_NUM_INDEX_FLAGS,
} nir_intrinsic_index_flag;
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(type, TYPE, nir_alu_type)
static inline void
nir_intrinsic_set_align(nir_intrinsic_instr *intrin,
return align_offset ? 1 << (ffs(align_offset) - 1) : align_mul;
}
+/* Converts a image_deref_* intrinsic into a image_* one */
+void nir_rewrite_image_intrinsic(nir_intrinsic_instr *instr,
+ nir_ssa_def *handle, bool bindless);
+
/**
* \group texture information
*
nir_tex_src_sampler_deref, /* < deref pointing to the sampler */
nir_tex_src_texture_offset, /* < dynamically uniform indirect offset */
nir_tex_src_sampler_offset, /* < dynamically uniform indirect offset */
+ nir_tex_src_texture_handle, /* < bindless texture handle */
+ nir_tex_src_sampler_handle, /* < bindless sampler handle */
nir_tex_src_plane, /* < selects plane for planar textures */
nir_num_tex_src_types
} nir_tex_src_type;
nir_texop_txl, /**< Texture look-up with explicit LOD */
nir_texop_txd, /**< Texture look-up with partial derivatives */
nir_texop_txf, /**< Texel fetch with explicit LOD */
- nir_texop_txf_ms, /**< Multisample texture fetch */
+ nir_texop_txf_ms, /**< Multisample texture fetch */
+ nir_texop_txf_ms_fb, /**< Multisample texture fetch from framebuffer */
nir_texop_txf_ms_mcs, /**< Multisample compression value fetch */
nir_texop_txs, /**< Texture size */
nir_texop_lod, /**< Texture lod query */
/* gather component selector */
unsigned component : 2;
+ /* gather offsets */
+ int8_t tg4_offsets[4][2];
+
+ /* True if the texture index or handle is not dynamically uniform */
+ bool texture_non_uniform;
+
+ /* True if the sampler index or handle is not dynamically uniform */
+ bool sampler_non_uniform;
+
/** The texture index
*
* If this texture instruction has a nir_tex_src_texture_offset source,
case nir_texop_txd:
case nir_texop_txf:
case nir_texop_txf_ms:
+ case nir_texop_txf_ms_fb:
case nir_texop_tg4:
return false;
default:
switch (instr->op) {
case nir_texop_txf:
case nir_texop_txf_ms:
+ case nir_texop_txf_ms_fb:
case nir_texop_txf_ms_mcs:
case nir_texop_samples_identical:
return nir_type_int;
void nir_tex_instr_remove_src(nir_tex_instr *tex, unsigned src_idx);
+bool nir_tex_instr_has_explicit_tg4_offsets(nir_tex_instr *tex);
+
typedef struct {
nir_instr instr;
- nir_const_value value;
-
nir_ssa_def def;
+
+ nir_const_value value[];
} nir_load_const_instr;
+#define nir_const_load_to_arr(arr, l, m) \
+{ \
+ nir_const_value_to_array(arr, l->value, l->def.num_components, m); \
+} while (false);
+
typedef enum {
nir_jump_return,
nir_jump_break,
NIR_DEFINE_CAST(nir_instr_as_alu, nir_instr, nir_alu_instr, instr,
type, nir_instr_type_alu)
+NIR_DEFINE_CAST(nir_instr_as_deref, nir_instr, nir_deref_instr, instr,
+ type, nir_instr_type_deref)
NIR_DEFINE_CAST(nir_instr_as_call, nir_instr, nir_call_instr, instr,
type, nir_instr_type_call)
NIR_DEFINE_CAST(nir_instr_as_jump, nir_instr, nir_jump_instr, instr,
#define nir_foreach_instr_reverse_safe(instr, block) \
foreach_list_typed_reverse_safe(nir_instr, instr, node, &(block)->instr_list)
+typedef enum {
+ nir_selection_control_none = 0x0,
+ nir_selection_control_flatten = 0x1,
+ nir_selection_control_dont_flatten = 0x2,
+} nir_selection_control;
+
typedef struct nir_if {
nir_cf_node cf_node;
nir_src condition;
+ nir_selection_control control;
struct exec_list then_list; /** < list of nir_cf_node */
struct exec_list else_list; /** < list of nir_cf_node */
/** True when ::break_block is in the else-path of ::nif. */
bool continue_from_then;
+ bool induction_rhs;
+
+ /* This is true if the terminators exact trip count is unknown. For
+ * example:
+ *
+ * for (int i = 0; i < imin(x, 4); i++)
+ * ...
+ *
+ * Here loop analysis would have set a max_trip_count of 4 however we dont
+ * know for sure that this is the exact trip count.
+ */
+ bool exact_trip_count_unknown;
struct list_head loop_terminator_link;
} nir_loop_terminator;
typedef struct {
- /* Number of instructions in the loop */
- unsigned num_instructions;
+ /* Estimated cost (in number of instructions) of the loop */
+ unsigned instr_cost;
+
+ /* Guessed trip count based on array indexing */
+ unsigned guessed_trip_count;
/* Maximum number of times the loop is run (if known) */
unsigned max_trip_count;
struct list_head loop_terminator_list;
} nir_loop_info;
+typedef enum {
+ nir_loop_control_none = 0x0,
+ nir_loop_control_unroll = 0x1,
+ nir_loop_control_dont_unroll = 0x2,
+} nir_loop_control;
+
typedef struct {
nir_cf_node cf_node;
struct exec_list body; /** < list of nir_cf_node */
nir_loop_info *info;
+ nir_loop_control control;
+ bool partially_unrolled;
} nir_loop;
/**
return nir_cf_node_as_block(exec_node_data(nir_cf_node, tail, node));
}
+/**
+ * Return true if this list of cf_nodes contains a single empty block.
+ */
+static inline bool
+nir_cf_list_is_empty_block(struct exec_list *cf_list)
+{
+ if (exec_list_is_singular(cf_list)) {
+ struct exec_node *head = exec_list_get_head(cf_list);
+ nir_block *block =
+ nir_cf_node_as_block(exec_node_data(nir_cf_node, head, node));
+ return exec_list_is_empty(&block->instr_list);
+ }
+ return false;
+}
+
typedef struct {
uint8_t num_components;
uint8_t bit_size;
bool lower_fdiv;
bool lower_ffma;
bool fuse_ffma;
+ bool lower_flrp16;
bool lower_flrp32;
/** Lowers flrp when it does not support doubles */
bool lower_flrp64;
bool lower_fpow;
bool lower_fsat;
bool lower_fsqrt;
- bool lower_fmod32;
- bool lower_fmod64;
+ bool lower_fmod;
/** Lowers ibitfield_extract/ubitfield_extract to ibfe/ubfe. */
bool lower_bitfield_extract;
/** Lowers ibitfield_extract/ubitfield_extract to bfm, compares, shifts. */
/** enables rules to lower idiv by power-of-two: */
bool lower_idiv;
+ /** enable rules to avoid bit shifts */
+ bool lower_bitshift;
+
/** enables rules to lower isign to imin+imax */
bool lower_isign;
+ /** enables rules to lower fsign to fsub and flt */
+ bool lower_fsign;
+
/* 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.
/** lowers fceil to fneg+ffloor+fneg: */
bool lower_fceil;
+ bool lower_ftrunc;
+
bool lower_ldexp;
bool lower_pack_half_2x16;
bool lower_extract_word;
bool lower_all_io_to_temps;
-
- /**
- * Does the driver support real 32-bit integers? (Otherwise, integers
- * are simulated by floats.)
- */
- bool native_integers;
+ bool lower_all_io_to_elements;
/* Indicates that the driver only has zero-based vertex id */
bool vertex_id_zero_based;
*/
bool lower_helper_invocation;
+ /**
+ * Convert gl_SampleMaskIn to gl_HelperInvocation as follows:
+ *
+ * gl_SampleMaskIn == 0 ---> gl_HelperInvocation
+ * gl_SampleMaskIn != 0 ---> !gl_HelperInvocation
+ */
+ bool optimize_sample_mask_in;
+
bool lower_cs_local_index_from_id;
bool lower_cs_local_id_from_index;
bool lower_hadd;
bool lower_add_sat;
+ /**
+ * Should IO be re-vectorized? Some scalar ISAs still operate on vec4's
+ * for IO purposes and would prefer loads/stores be vectorized.
+ */
+ bool vectorize_io;
+
/**
* Should nir_lower_io() create load_interpolated_input intrinsics?
*
struct exec_list functions; /** < list of nir_function */
- /** list of global register in the shader */
- struct exec_list registers;
-
- /** next available global register index */
- unsigned reg_alloc;
-
/**
* the highest index a load_input_*, load_uniform_*, etc. intrinsic can
* access plus one
*/
unsigned num_inputs, num_uniforms, num_outputs, num_shared;
+ /** Size in bytes of required scratch space */
+ unsigned scratch_size;
+
/** Constant data associated with this shader.
*
* Constant data is loaded through load_constant intrinsics. See also
const nir_shader_compiler_options *options,
shader_info *si);
-/** creates a register, including assigning it an index and adding it to the list */
-nir_register *nir_global_reg_create(nir_shader *shader);
-
nir_register *nir_local_reg_create(nir_function_impl *impl);
void nir_reg_remove(nir_register *reg);
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) \
+nir_src_as_ ## name (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; \
+ 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)
+NIR_SRC_AS_(intrinsic, nir_intrinsic_instr,
+ nir_instr_type_intrinsic, nir_instr_as_intrinsic)
+NIR_SRC_AS_(deref, nir_deref_instr, nir_instr_type_deref, nir_instr_as_deref)
bool nir_src_is_dynamically_uniform(nir_src src);
bool nir_srcs_equal(nir_src src1, nir_src src2);
nir_loop *nir_block_get_following_loop(nir_block *block);
void nir_index_local_regs(nir_function_impl *impl);
-void nir_index_global_regs(nir_shader *shader);
void nir_index_ssa_defs(nir_function_impl *impl);
unsigned nir_index_instrs(nir_function_impl *impl);
void nir_print_instr(const nir_instr *instr, FILE *fp);
void nir_print_deref(const nir_deref_instr *deref, FILE *fp);
+/** Shallow clone of a single ALU instruction. */
+nir_alu_instr *nir_alu_instr_clone(nir_shader *s, const nir_alu_instr *orig);
+
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_function_impl *nir_function_impl_clone(nir_shader *shader,
+ const nir_function_impl *fi);
nir_constant *nir_constant_clone(const nir_constant *c, nir_variable *var);
nir_variable *nir_variable_clone(const nir_variable *c, nir_shader *shader);
-nir_shader *nir_shader_serialize_deserialize(void *mem_ctx, nir_shader *s);
+void nir_shader_replace(nir_shader *dest, nir_shader *src);
+
+void nir_shader_serialize_deserialize(nir_shader *s);
#ifndef NDEBUG
void nir_validate_shader(nir_shader *shader, const char *when);
nir_validate_shader(nir, "after " #pass); \
if (should_clone_nir()) { \
nir_shader *clone = nir_shader_clone(ralloc_parent(nir), nir); \
- ralloc_free(nir); \
- nir = clone; \
+ nir_shader_replace(nir, clone); \
} \
if (should_serialize_deserialize_nir()) { \
- void *mem_ctx = ralloc_parent(nir); \
- nir = nir_shader_serialize_deserialize(mem_ctx, nir); \
+ nir_shader_serialize_deserialize(nir); \
} \
} while (0)
bool nir_lower_returns_impl(nir_function_impl *impl);
bool nir_lower_returns(nir_shader *shader);
+void nir_inline_function_impl(struct nir_builder *b,
+ const nir_function_impl *impl,
+ nir_ssa_def **params);
bool nir_inline_functions(nir_shader *shader);
bool nir_propagate_invariant(nir_shader *shader);
bool nir_lower_global_vars_to_local(nir_shader *shader);
+typedef enum {
+ nir_lower_direct_array_deref_of_vec_load = (1 << 0),
+ nir_lower_indirect_array_deref_of_vec_load = (1 << 1),
+ nir_lower_direct_array_deref_of_vec_store = (1 << 2),
+ nir_lower_indirect_array_deref_of_vec_store = (1 << 3),
+} nir_lower_array_deref_of_vec_options;
+
+bool nir_lower_array_deref_of_vec(nir_shader *shader, nir_variable_mode modes,
+ nir_lower_array_deref_of_vec_options options);
+
bool nir_lower_indirect_derefs(nir_shader *shader, nir_variable_mode modes);
bool nir_lower_locals_to_regs(nir_shader *shader);
nir_function_impl *entrypoint,
bool outputs, bool inputs);
+bool nir_lower_vars_to_scratch(nir_shader *shader,
+ nir_variable_mode modes,
+ int size_threshold,
+ glsl_type_size_align_func size_align);
+
void nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint);
+void nir_gather_ssa_types(nir_function_impl *impl,
+ BITSET_WORD *float_types,
+ BITSET_WORD *int_types);
+
void nir_assign_var_locations(struct exec_list *var_list, unsigned *size,
- int (*type_size)(const struct glsl_type *));
+ int (*type_size)(const struct glsl_type *, bool));
/* Some helpers to do very simple linking */
bool nir_remove_unused_varyings(nir_shader *producer, nir_shader *consumer);
} nir_lower_io_options;
bool nir_lower_io(nir_shader *shader,
nir_variable_mode modes,
- int (*type_size)(const struct glsl_type *),
+ int (*type_size)(const struct glsl_type *, bool),
nir_lower_io_options);
typedef enum {
*/
nir_address_format_64bit_global,
+ /**
+ * An address format which is a bounds-checked 64-bit global GPU address.
+ *
+ * The address is comprised as a 32-bit vec4 where .xy are a uint64_t base
+ * address stored with the low bits in .x and high bits in .y, .z is a
+ * size, and .w is an offset. When the final I/O operation is lowered, .w
+ * is checked against .z and the operation is predicated on the result.
+ */
+ nir_address_format_64bit_bounded_global,
+
/**
* An address format which is comprised of a vec2 where the first
- * component is a vulkan descriptor index and the second is an offset.
+ * component is a buffer index and the second is an offset.
+ */
+ nir_address_format_32bit_index_offset,
+
+ /**
+ * An address format which is a simple 32-bit offset.
+ */
+ nir_address_format_32bit_offset,
+
+ /**
+ * An address format representing a purely logical addressing model. In
+ * this model, all deref chains must be complete from the dereference
+ * operation to the variable. Cast derefs are not allowed. These
+ * addresses will be 32-bit scalars but the format is immaterial because
+ * you can always chase the chain.
*/
- nir_address_format_vk_index_offset,
+ nir_address_format_logical,
} nir_address_format;
+
+static inline unsigned
+nir_address_format_bit_size(nir_address_format addr_format)
+{
+ switch (addr_format) {
+ case nir_address_format_32bit_global: return 32;
+ case nir_address_format_64bit_global: return 64;
+ case nir_address_format_64bit_bounded_global: return 32;
+ case nir_address_format_32bit_index_offset: return 32;
+ case nir_address_format_32bit_offset: return 32;
+ case nir_address_format_logical: return 32;
+ }
+ unreachable("Invalid address format");
+}
+
+static inline unsigned
+nir_address_format_num_components(nir_address_format addr_format)
+{
+ switch (addr_format) {
+ case nir_address_format_32bit_global: return 1;
+ case nir_address_format_64bit_global: return 1;
+ case nir_address_format_64bit_bounded_global: return 4;
+ case nir_address_format_32bit_index_offset: return 2;
+ case nir_address_format_32bit_offset: return 1;
+ case nir_address_format_logical: return 1;
+ }
+ unreachable("Invalid address format");
+}
+
+static inline const struct glsl_type *
+nir_address_format_to_glsl_type(nir_address_format addr_format)
+{
+ unsigned bit_size = nir_address_format_bit_size(addr_format);
+ assert(bit_size == 32 || bit_size == 64);
+ return glsl_vector_type(bit_size == 32 ? GLSL_TYPE_UINT : GLSL_TYPE_UINT64,
+ nir_address_format_num_components(addr_format));
+}
+
+const nir_const_value *nir_address_format_null_value(nir_address_format addr_format);
+
+nir_ssa_def *nir_build_addr_ieq(struct nir_builder *b, nir_ssa_def *addr0, nir_ssa_def *addr1,
+ nir_address_format addr_format);
+
+nir_ssa_def *nir_build_addr_isub(struct nir_builder *b, nir_ssa_def *addr0, nir_ssa_def *addr1,
+ nir_address_format addr_format);
+
+nir_ssa_def * nir_explicit_io_address_from_deref(struct nir_builder *b,
+ nir_deref_instr *deref,
+ nir_ssa_def *base_addr,
+ nir_address_format addr_format);
+void nir_lower_explicit_io_instr(struct nir_builder *b,
+ nir_intrinsic_instr *io_instr,
+ nir_ssa_def *addr,
+ nir_address_format addr_format);
+
bool nir_lower_explicit_io(nir_shader *shader,
nir_variable_mode modes,
nir_address_format);
void nir_lower_alpha_test(nir_shader *shader, enum compare_func func,
bool alpha_to_one);
bool nir_lower_alu(nir_shader *shader);
-bool nir_lower_alu_to_scalar(nir_shader *shader);
+
+bool nir_lower_flrp(nir_shader *shader, unsigned lowering_mask,
+ bool always_precise, bool have_ffma);
+
+bool nir_lower_alu_to_scalar(nir_shader *shader, BITSET_WORD *lower_set);
bool nir_lower_bool_to_float(nir_shader *shader);
bool nir_lower_bool_to_int32(nir_shader *shader);
+bool nir_lower_int_to_float(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 outputs_only);
void nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask);
void nir_lower_io_to_scalar_early(nir_shader *shader, nir_variable_mode mask);
+bool nir_lower_io_to_vector(nir_shader *shader, nir_variable_mode mask);
+void nir_lower_fragcoord_wtrans(nir_shader *shader);
+void nir_lower_viewport_transform(nir_shader *shader);
bool nir_lower_uniforms_to_ubo(nir_shader *shader, int multiplier);
typedef struct nir_lower_subgroups_options {
*/
unsigned lower_srgb;
+ /**
+ * If true, lower nir_texop_tex on shaders that doesn't support implicit
+ * LODs to nir_texop_txl.
+ */
+ bool lower_tex_without_implicit_lod;
+
/**
* If true, lower nir_texop_txd on cube maps with nir_texop_txl.
*/
*/
bool lower_txd_offset_clamp;
+ /**
+ * If true, lower nir_texop_txd with min_lod to a nir_texop_txl if the
+ * sampler is bindless.
+ */
+ bool lower_txd_clamp_bindless_sampler;
+
/**
* If true, lower nir_texop_txd with min_lod to a nir_texop_txl if the
* sampler index is not statically determinable to be less than 16.
*/
bool lower_tg4_broadcom_swizzle;
+ /**
+ * If true, lowers tg4 with 4 constant offsets to 4 tg4 calls
+ */
+ bool lower_tg4_offsets;
+
enum nir_lower_tex_packing lower_tex_packing[32];
} nir_lower_tex_options;
bool nir_lower_tex(nir_shader *shader,
const nir_lower_tex_options *options);
+enum nir_lower_non_uniform_access_type {
+ nir_lower_non_uniform_ubo_access = (1 << 0),
+ nir_lower_non_uniform_ssbo_access = (1 << 1),
+ nir_lower_non_uniform_texture_access = (1 << 2),
+ nir_lower_non_uniform_image_access = (1 << 3),
+};
+
+bool nir_lower_non_uniform_access(nir_shader *shader,
+ enum nir_lower_non_uniform_access_type);
+
bool nir_lower_idiv(nir_shader *shader);
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);
+bool nir_lower_frexp(nir_shader *nir);
+
void nir_lower_two_sided_color(nir_shader *shader);
bool nir_lower_clamp_color_outputs(nir_shader *shader);
const nir_lower_wpos_ytransform_options *options);
bool nir_lower_wpos_center(nir_shader *shader, const bool for_sample_shading);
+bool nir_lower_fb_read(nir_shader *shader);
+
typedef struct nir_lower_drawpixels_options {
gl_state_index16 texcoord_state_tokens[STATE_LENGTH];
gl_state_index16 scale_state_tokens[STATE_LENGTH];
nir_lower_bit_size_callback callback,
void *callback_data);
+nir_lower_int64_options nir_lower_int64_op_to_options_mask(nir_op opcode);
bool nir_lower_int64(nir_shader *shader, nir_lower_int64_options options);
-bool nir_lower_doubles(nir_shader *shader, nir_lower_doubles_options options);
+nir_lower_doubles_options nir_lower_doubles_op_to_options_mask(nir_op opcode);
+bool nir_lower_doubles(nir_shader *shader, const nir_shader *softfp64,
+ nir_lower_doubles_options options);
bool nir_lower_pack(nir_shader *shader);
bool nir_normalize_cubemap_coords(nir_shader *shader);
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_comparison_pre(nir_shader *shader);
+
bool nir_opt_algebraic(nir_shader *shader);
bool nir_opt_algebraic_before_ffma(nir_shader *shader);
bool nir_opt_algebraic_late(nir_shader *shader);
bool nir_opt_constant_folding(nir_shader *shader);
-bool nir_opt_global_to_local(nir_shader *shader);
+bool nir_opt_combine_stores(nir_shader *shader, nir_variable_mode modes);
bool nir_copy_prop(nir_shader *shader);
bool nir_opt_dead_write_vars(nir_shader *shader);
+bool nir_opt_deref_impl(nir_function_impl *impl);
bool nir_opt_deref(nir_shader *shader);
bool nir_opt_find_array_copies(nir_shader *shader);
bool nir_opt_idiv_const(nir_shader *shader, unsigned min_bit_size);
-bool nir_opt_if(nir_shader *shader);
+bool nir_opt_if(nir_shader *shader, bool aggressive_last_continue);
bool nir_opt_intrinsics(nir_shader *shader);
bool nir_opt_peephole_select(nir_shader *shader, unsigned limit,
bool indirect_load_ok, bool expensive_alu_ok);
+bool nir_opt_rematerialize_compares(nir_shader *shader);
+
bool nir_opt_remove_phis(nir_shader *shader);
bool nir_opt_shrink_load(nir_shader *shader);
bool nir_opt_conditional_discard(nir_shader *shader);
+void nir_strip(nir_shader *shader);
+
void nir_sweep(nir_shader *shader);
void nir_remap_dual_slot_attributes(nir_shader *shader,
nir_intrinsic_op nir_intrinsic_from_system_value(gl_system_value val);
gl_system_value nir_system_value_from_intrinsic(nir_intrinsic_op intrin);
+bool nir_lower_sincos(nir_shader *shader);
+
#ifdef __cplusplus
} /* extern "C" */
#endif