}
}
-static inline int64_t
+static inline uint64_t
nir_const_value_as_uint(nir_const_value value, unsigned bit_size)
{
switch (bit_size) {
}
}
+static inline bool
+nir_is_float_control_signed_zero_inf_nan_preserve(unsigned execution_mode, unsigned bit_size)
+{
+ return (16 == bit_size && execution_mode & FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP16) ||
+ (32 == bit_size && execution_mode & FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP32) ||
+ (64 == bit_size && execution_mode & FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP64);
+}
+
+static inline bool
+nir_is_denorm_flush_to_zero(unsigned execution_mode, unsigned bit_size)
+{
+ return (16 == bit_size && execution_mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP16) ||
+ (32 == bit_size && execution_mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32) ||
+ (64 == bit_size && execution_mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP64);
+}
+
+static inline bool
+nir_is_denorm_preserve(unsigned execution_mode, unsigned bit_size)
+{
+ return (16 == bit_size && execution_mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP16) ||
+ (32 == bit_size && execution_mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP32) ||
+ (64 == bit_size && execution_mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP64);
+}
+
+static inline bool
+nir_is_rounding_mode_rtne(unsigned execution_mode, unsigned bit_size)
+{
+ return (16 == bit_size && execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16) ||
+ (32 == bit_size && execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32) ||
+ (64 == bit_size && execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64);
+}
+
+static inline bool
+nir_is_rounding_mode_rtz(unsigned execution_mode, unsigned bit_size)
+{
+ return (16 == bit_size && execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP16) ||
+ (32 == bit_size && execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP32) ||
+ (64 == bit_size && execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP64);
+}
+
+static inline bool
+nir_has_any_rounding_mode_rtz(unsigned execution_mode)
+{
+ return (execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP16) ||
+ (execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP32) ||
+ (execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP64);
+}
+
+static inline bool
+nir_has_any_rounding_mode_rtne(unsigned execution_mode)
+{
+ return (execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16) ||
+ (execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32) ||
+ (execution_mode & FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64);
+}
+
+static inline nir_rounding_mode
+nir_get_rounding_mode_from_float_controls(unsigned execution_mode,
+ nir_alu_type type)
+{
+ if (nir_alu_type_get_base_type(type) != nir_type_float)
+ return nir_rounding_mode_undef;
+
+ unsigned bit_size = nir_alu_type_get_type_size(type);
+
+ if (nir_is_rounding_mode_rtz(execution_mode, bit_size))
+ return nir_rounding_mode_rtz;
+ if (nir_is_rounding_mode_rtne(execution_mode, bit_size))
+ return nir_rounding_mode_rtne;
+ return nir_rounding_mode_undef;
+}
+
+static inline bool
+nir_has_any_rounding_mode_enabled(unsigned execution_mode)
+{
+ bool result =
+ nir_has_any_rounding_mode_rtne(execution_mode) ||
+ nir_has_any_rounding_mode_rtz(execution_mode);
+ return result;
+}
+
typedef enum {
/**
* Operation where the first two sources are commutative.
NIR_INTRINSIC_SRC_ACCESS,
NIR_INTRINSIC_DST_ACCESS,
+ /* Driver location for nir_load_patch_location_ir3 */
+ NIR_INTRINSIC_DRIVER_LOCATION,
+
NIR_INTRINSIC_NUM_INDEX_FLAGS,
} nir_intrinsic_index_flag;
INTRINSIC_IDX_ACCESSORS(desc_type, DESC_TYPE, unsigned)
INTRINSIC_IDX_ACCESSORS(type, TYPE, nir_alu_type)
INTRINSIC_IDX_ACCESSORS(swizzle_mask, SWIZZLE_MASK, unsigned)
+INTRINSIC_IDX_ACCESSORS(driver_location, DRIVER_LOCATION, unsigned)
static inline void
nir_intrinsic_set_align(nir_intrinsic_instr *intrin,
nir_texop_samples_identical, /**< Query whether all samples are definitely
* identical.
*/
+ nir_texop_tex_prefetch, /**< Regular texture look-up, eligible for pre-dispatch */
} nir_texop;
typedef struct {
case nir_tex_src_projector:
case nir_tex_src_comparator:
case nir_tex_src_bias:
+ case nir_tex_src_min_lod:
case nir_tex_src_ddx:
case nir_tex_src_ddy:
return nir_type_float;
case nir_tex_src_offset:
case nir_tex_src_ms_index:
+ case nir_tex_src_plane:
+ return nir_type_int;
+
+ case nir_tex_src_ms_mcs:
+ case nir_tex_src_texture_deref:
+ case nir_tex_src_sampler_deref:
case nir_tex_src_texture_offset:
case nir_tex_src_sampler_offset:
- return nir_type_int;
+ case nir_tex_src_texture_handle:
+ case nir_tex_src_sampler_handle:
+ return nir_type_uint;
- default:
- unreachable("Invalid texture source type");
+ case nir_num_tex_src_types:
+ unreachable("nir_num_tex_src_types is not a valid source type");
}
+
+ unreachable("Invalid texture source type");
}
static inline unsigned
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_lower_fp64_full_software = (1 << 11),
} nir_lower_doubles_options;
+typedef enum {
+ nir_divergence_single_prim_per_subgroup = (1 << 0),
+ nir_divergence_single_patch_per_tcs_subgroup = (1 << 1),
+ nir_divergence_single_patch_per_tes_subgroup = (1 << 2),
+ nir_divergence_view_index_uniform = (1 << 3),
+} nir_divergence_options;
+
typedef struct nir_shader_compiler_options {
bool lower_fdiv;
bool lower_ffma;
* for IO purposes and would prefer loads/stores be vectorized.
*/
bool vectorize_io;
+ bool lower_to_scalar;
/**
* Should nir_lower_io() create load_interpolated_input intrinsics?
/* Lowers when rotate instruction is not supported */
bool lower_rotate;
+ /**
+ * Backend supports imul24, and would like to use it (when possible)
+ * for address/offset calculation. If true, driver should call
+ * nir_lower_amul(). (If not set, amul will automatically be lowered
+ * to imul.)
+ */
+ bool has_imul24;
+
/**
* Is this the Intel vec4 backend?
*
nir_block *nir_dominance_lca(nir_block *b1, nir_block *b2);
bool nir_block_dominates(nir_block *parent, nir_block *child);
+bool nir_block_is_unreachable(nir_block *block);
void nir_dump_dom_tree_impl(nir_function_impl *impl, FILE *fp);
void nir_dump_dom_tree(nir_shader *shader, FILE *fp);
void nir_link_xfb_varyings(nir_shader *producer, nir_shader *consumer);
bool nir_link_opt_varyings(nir_shader *producer, nir_shader *consumer);
+bool nir_lower_amul(nir_shader *shader,
+ int (*type_size)(const struct glsl_type *, bool));
void nir_assign_io_var_locations(struct exec_list *var_list,
unsigned *size,
gl_shader_stage stage);
typedef enum {
+ /* If set, this causes all 64-bit IO operations to be lowered on-the-fly
+ * to 32-bit operations. This is only valid for nir_var_shader_in/out
+ * modes.
+ */
+ nir_lower_io_lower_64bit_to_32 = (1 << 0),
+
/* If set, this forces all non-flat fragment shader inputs to be
* interpolated as if with the "sample" qualifier. This requires
* nir_shader_compiler_options::use_interpolated_input_intrinsics.
bool nir_io_add_const_offset_to_base(nir_shader *nir, nir_variable_mode mode);
+bool
+nir_lower_vars_to_explicit_types(nir_shader *shader,
+ nir_variable_mode modes,
+ glsl_type_size_align_func type_info);
+
typedef enum {
/**
* An address format which is a simple 32-bit global GPU address.
bool nir_lower_constant_initializers(nir_shader *shader,
nir_variable_mode modes);
-bool nir_move_load_const(nir_shader *shader);
bool nir_move_vec_src_uses_to_dest(nir_shader *shader);
bool nir_lower_vec_to_movs(nir_shader *shader);
void nir_lower_alpha_test(nir_shader *shader, enum compare_func func,
- bool alpha_to_one);
+ bool alpha_to_one,
+ const gl_state_index16 *alpha_ref_state_tokens);
bool nir_lower_alu(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_alu_to_scalar(nir_shader *shader, nir_instr_filter_cb cb, const void *data);
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_non_uniform_access(nir_shader *shader,
enum nir_lower_non_uniform_access_type);
-bool nir_lower_idiv(nir_shader *shader);
+enum nir_lower_idiv_path {
+ /* This path is based on NV50LegalizeSSA::handleDIV(). It is the faster of
+ * the two but it is not exact in some cases (for example, 1091317713u /
+ * 1034u gives 5209173 instead of 1055432) */
+ nir_lower_idiv_fast,
+ /* This path is based on AMDGPUTargetLowering::LowerUDIVREM() and
+ * AMDGPUTargetLowering::LowerSDIVREM(). It requires more instructions than
+ * the nv50 path and many of them are integer multiplications, so it is
+ * probably slower. It should always return the correct result, though. */
+ nir_lower_idiv_precise,
+};
+
+bool nir_lower_idiv(nir_shader *shader, enum nir_lower_idiv_path path);
bool nir_lower_input_attachments(nir_shader *shader, bool use_fragcoord_sysval);
-bool nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars);
-bool nir_lower_clip_gs(nir_shader *shader, unsigned ucp_enables);
-bool nir_lower_clip_fs(nir_shader *shader, unsigned ucp_enables);
+bool nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables,
+ bool use_vars,
+ bool use_clipdist_array,
+ const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]);
+bool nir_lower_clip_gs(nir_shader *shader, unsigned ucp_enables,
+ bool use_clipdist_array,
+ const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]);
+bool nir_lower_clip_fs(nir_shader *shader, unsigned ucp_enables,
+ bool use_clipdist_array);
bool nir_lower_clip_cull_distance_arrays(nir_shader *nir);
+void nir_lower_point_size_mov(nir_shader *shader,
+ const gl_state_index16 *pointsize_state_tokens);
+
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);
+bool nir_lower_flatshade(nir_shader *shader);
+
void nir_lower_passthrough_edgeflags(nir_shader *shader);
bool nir_lower_patch_vertices(nir_shader *nir, unsigned static_count,
const gl_state_index16 *uniform_state_tokens);
nir_lower_doubles_options options);
bool nir_lower_pack(nir_shader *shader);
+bool nir_lower_point_size(nir_shader *shader, float min, float max);
+
typedef enum {
nir_lower_interpolation_at_sample = (1 << 1),
nir_lower_interpolation_at_offset = (1 << 2),
bool nir_repair_ssa(nir_shader *shader);
void nir_convert_loop_to_lcssa(nir_loop *loop);
+bool nir_convert_to_lcssa(nir_shader *shader, bool skip_invariants, bool skip_bool_invariants);
+bool* nir_divergence_analysis(nir_shader *shader, nir_divergence_options options);
/* If phi_webs_only is true, only convert SSA values involved in phi nodes to
* registers. If false, convert all values (even those not involved in a phi
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_lower_samplers(nir_shader *shader);
+
/* This is here for unit tests. */
bool nir_opt_comparison_pre_impl(nir_function_impl *impl);
bool nir_opt_comparison_pre(nir_shader *shader);
+bool nir_opt_access(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_loop_unroll(nir_shader *shader, nir_variable_mode indirect_mask);
-bool nir_opt_move_comparisons(nir_shader *shader);
+typedef enum {
+ nir_move_const_undef = (1 << 0),
+ nir_move_load_ubo = (1 << 1),
+ nir_move_load_input = (1 << 2),
+ nir_move_comparisons = (1 << 3),
+} nir_move_options;
+
+bool nir_can_move_instr(nir_instr *instr, nir_move_options options);
+
+bool nir_opt_sink(nir_shader *shader, nir_move_options options);
-bool nir_opt_move_load_ubo(nir_shader *shader);
+bool nir_opt_move(nir_shader *shader, nir_move_options options);
bool nir_opt_peephole_select(nir_shader *shader, unsigned limit,
bool indirect_load_ok, bool expensive_alu_ok);