ReactOS 0.4.17-dev-934-g091855f
ir.c File Reference
#include "vkd3d_shader_private.h"
#include "vkd3d_types.h"
Include dependency graph for ir.c:

Go to the source code of this file.

Classes

struct  vsir_transformation_context
 
struct  hull_flattener
 
struct  shader_phase_location
 
struct  shader_phase_location_array
 
struct  control_point_normaliser
 
struct  io_normaliser
 
struct  flat_constant_def
 
struct  flat_constants_normaliser
 
struct  cf_flattener_if_info
 
struct  cf_flattener_loop_info
 
struct  cf_flattener_switch_case
 
struct  cf_flattener_switch_info
 
struct  cf_flattener_info
 
struct  cf_flattener
 
struct  lower_switch_to_if_ladder_block_mapping
 
struct  ssas_to_temps_alloc
 
struct  ssas_to_temps_block_info
 
struct  ssas_to_temps_block_info::phi_incoming_to_temp
 
struct  vsir_block_list
 
struct  vsir_block
 
struct  vsir_cfg_structure_list
 
struct  vsir_cfg_structure
 
struct  vsir_cfg_emit_target
 
struct  vsir_cfg
 
struct  vsir_cfg::cfg_loop_interval
 
struct  vsir_cfg_node_sorter
 
struct  vsir_cfg_node_sorter::vsir_cfg_node_sorter_stack_item
 
struct  vsir_cfg_edge_action
 
struct  validation_context
 
struct  validation_context::validation_context_temp_data
 
struct  validation_context::validation_context_ssa_data
 
struct  sysval_validation_data_element
 
struct  vsir_validator_instruction_desc
 

Macros

#define VKD3D_SHADER_SWIZZLE__   VKD3D_SHADER_SWIZZLE_X
 
#define PS_BIT   (1u << VKD3D_SHADER_TYPE_PIXEL)
 
#define VS_BIT   (1u << VKD3D_SHADER_TYPE_VERTEX)
 
#define GS_BIT   (1u << VKD3D_SHADER_TYPE_GEOMETRY)
 
#define HS_BIT   (1u << VKD3D_SHADER_TYPE_HULL)
 
#define DS_BIT   (1u << VKD3D_SHADER_TYPE_DOMAIN)
 
#define CS_BIT   (1u << VKD3D_SHADER_TYPE_COMPUTE)
 
#define vsir_transform(ctx, step)   vsir_transform_(ctx, #step, step)
 

Enumerations

enum  vsir_signature_type { SIGNATURE_TYPE_INPUT , SIGNATURE_TYPE_OUTPUT , SIGNATURE_TYPE_PATCH_CONSTANT }
 

Functions

static int convert_parameter_info (const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters)
 
bool vsir_program_init (struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type, enum vsir_normalisation_level normalisation_level)
 
void vsir_program_cleanup (struct vsir_program *program)
 
const struct vkd3d_shader_parameter1 * vsir_program_get_parameter (const struct vsir_program *program, enum vkd3d_shader_parameter_name name)
 
static struct signature_element * vsir_signature_find_element_by_name (const struct shader_signature *signature, const char *semantic_name, unsigned int semantic_index)
 
bool vsir_signature_find_sysval (const struct shader_signature *signature, enum vkd3d_shader_sysval_semantic sysval, unsigned int semantic_index, unsigned int *element_index)
 
void vsir_register_init (struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
 
static bool shader_register_is_phase_instance_id (const struct vkd3d_shader_register *reg)
 
void vsir_src_param_init (struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
 
static void src_param_init_const_uint (struct vkd3d_shader_src_param *src, uint32_t value)
 
void vsir_src_param_init_label (struct vkd3d_shader_src_param *param, unsigned int label_id)
 
static void src_param_init_parameter (struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
 
static void vsir_src_param_init_resource (struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
 
static void vsir_src_param_init_sampler (struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
 
static void src_param_init_ssa_bool (struct vkd3d_shader_src_param *src, unsigned int idx)
 
static void src_param_init_ssa_float (struct vkd3d_shader_src_param *src, unsigned int idx)
 
static void src_param_init_temp_bool (struct vkd3d_shader_src_param *src, unsigned int idx)
 
static void src_param_init_temp_float (struct vkd3d_shader_src_param *src, unsigned int idx)
 
static void src_param_init_temp_float4 (struct vkd3d_shader_src_param *src, unsigned int idx)
 
static void src_param_init_temp_uint (struct vkd3d_shader_src_param *src, unsigned int idx)
 
void vsir_dst_param_init (struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
 
static void dst_param_init_ssa_bool (struct vkd3d_shader_dst_param *dst, unsigned int idx)
 
static void dst_param_init_ssa_float (struct vkd3d_shader_dst_param *dst, unsigned int idx)
 
static void dst_param_init_temp_bool (struct vkd3d_shader_dst_param *dst, unsigned int idx)
 
static void dst_param_init_temp_float4 (struct vkd3d_shader_dst_param *dst, unsigned int idx)
 
static void dst_param_init_temp_uint (struct vkd3d_shader_dst_param *dst, unsigned int idx)
 
static void dst_param_init_output (struct vkd3d_shader_dst_param *dst, enum vkd3d_data_type data_type, uint32_t idx, uint32_t write_mask)
 
void vsir_instruction_init (struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode)
 
bool vsir_instruction_init_with_params (struct vsir_program *program, struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count)
 
static bool vsir_instruction_init_label (struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, unsigned int label_id, struct vsir_program *program)
 
static bool vsir_instruction_is_dcl (const struct vkd3d_shader_instruction *instruction)
 
static void vkd3d_shader_instruction_make_nop (struct vkd3d_shader_instruction *ins)
 
static bool get_opcode_from_rel_op (enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap)
 
static enum vkd3d_result vsir_program_lower_ifc (struct vsir_program *program, struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx, struct vkd3d_shader_message_context *message_context)
 
static enum vkd3d_result vsir_program_lower_texkill (struct vsir_program *program, struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx)
 
static enum vkd3d_result vsir_program_lower_precise_mad (struct vsir_program *program, struct vkd3d_shader_instruction *mad, unsigned int *tmp_idx)
 
static enum vkd3d_result vsir_program_lower_sm1_sincos (struct vsir_program *program, struct vkd3d_shader_instruction *sincos)
 
static enum vkd3d_result vsir_program_lower_tex (struct vsir_program *program, struct vkd3d_shader_instruction *tex)
 
static enum vkd3d_result vsir_program_lower_texldd (struct vsir_program *program, struct vkd3d_shader_instruction *texldd)
 
static enum vkd3d_result vsir_program_lower_instructions (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static void shader_register_eliminate_phase_addressing (struct vkd3d_shader_register *reg, unsigned int instance_id)
 
static void shader_instruction_eliminate_phase_instance_id (struct vkd3d_shader_instruction *ins, unsigned int instance_id)
 
static enum vkd3d_result vsir_program_ensure_ret (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static enum vkd3d_result vsir_program_add_diffuse_output (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static enum vkd3d_result vsir_program_ensure_diffuse (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static const struct vkd3d_shader_varying_map * find_varying_map (const struct vkd3d_shader_varying_map_info *varying_map, unsigned int signature_idx)
 
static bool target_allows_subset_masks (const struct vkd3d_shader_compile_info *info)
 
static void remove_unread_output_components (const struct shader_signature *signature, struct vkd3d_shader_instruction *ins, struct vkd3d_shader_dst_param *dst)
 
static enum vkd3d_result vsir_program_remap_output_signature (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool flattener_is_in_fork_or_join_phase (const struct hull_flattener *flattener)
 
static void flattener_eliminate_phase_related_dcls (struct hull_flattener *normaliser, unsigned int index, struct shader_phase_location_array *locations)
 
static enum vkd3d_result flattener_flatten_phases (struct hull_flattener *normaliser, struct shader_phase_location_array *locations)
 
static enum vkd3d_result vsir_program_flatten_hull_shader_phases (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool control_point_normaliser_is_in_control_point_phase (const struct control_point_normaliser *normaliser)
 
struct vkd3d_shader_src_param * vsir_program_create_outpointid_param (struct vsir_program *program)
 
static void shader_dst_param_normalise_outpointid (struct vkd3d_shader_dst_param *dst_param, struct control_point_normaliser *normaliser)
 
static void shader_dst_param_io_init (struct vkd3d_shader_dst_param *param, const struct signature_element *e, enum vkd3d_shader_register_type reg_type, unsigned int idx_count)
 
static enum vkd3d_result control_point_normaliser_emit_hs_input (struct control_point_normaliser *normaliser, const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst, const struct vkd3d_shader_location *location)
 
static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool io_normaliser_is_in_fork_or_join_phase (const struct io_normaliser *normaliser)
 
static bool io_normaliser_is_in_control_point_phase (const struct io_normaliser *normaliser)
 
static bool shader_signature_find_element_for_reg (const struct shader_signature *signature, unsigned int reg_idx, unsigned int write_mask, unsigned int *element_idx)
 
struct signature_element * vsir_signature_find_element_for_reg (const struct shader_signature *signature, unsigned int reg_idx, unsigned int write_mask)
 
static unsigned int range_map_get_register_count (uint8_t range_map[][VKD3D_VEC4_SIZE], unsigned int register_idx, uint32_t write_mask)
 
static void range_map_set_register_range (uint8_t range_map[][VKD3D_VEC4_SIZE], unsigned int register_idx, unsigned int register_count, uint32_t write_mask, bool is_dcl_indexrange)
 
static void io_normaliser_add_index_range (struct io_normaliser *normaliser, const struct vkd3d_shader_instruction *ins)
 
static int signature_element_mask_compare (const void *a, const void *b)
 
static bool sysval_semantics_should_merge (const struct signature_element *e, const struct signature_element *f)
 
static void shader_signature_map_patch_constant_index_ranges (struct shader_signature *s, uint8_t range_map[][VKD3D_VEC4_SIZE])
 
static int signature_element_register_compare (const void *a, const void *b)
 
static int signature_element_index_compare (const void *a, const void *b)
 
static unsigned int signature_element_range_expand_mask (struct signature_element *e, unsigned int register_count, uint8_t range_map[][VKD3D_VEC4_SIZE])
 
static bool shader_signature_merge (struct shader_signature *s, uint8_t range_map[][VKD3D_VEC4_SIZE], bool is_patch_constant)
 
static unsigned int shader_register_normalise_arrayed_addressing (struct vkd3d_shader_register *reg, unsigned int id_idx, unsigned int register_index)
 
static bool shader_dst_param_io_normalise (struct vkd3d_shader_dst_param *dst_param, bool is_io_dcl, struct io_normaliser *normaliser)
 
static void shader_src_param_io_normalise (struct vkd3d_shader_src_param *src_param, struct io_normaliser *normaliser)
 
static void shader_instruction_normalise_io_params (struct vkd3d_shader_instruction *ins, struct io_normaliser *normaliser)
 
static enum vkd3d_result vsir_program_normalise_io_registers (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool get_flat_constant_register_type (const struct vkd3d_shader_register *reg, enum vkd3d_shader_d3dbc_constant_register *set, uint32_t *index)
 
static void shader_register_normalise_flat_constants (struct vkd3d_shader_src_param *param, const struct flat_constants_normaliser *normaliser)
 
static enum vkd3d_result vsir_program_normalise_flat_constants (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static enum vkd3d_result vsir_program_remove_dead_code (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static void cf_flattener_set_error (struct cf_flattener *flattener, enum vkd3d_result error)
 
static struct vkd3d_shader_instruction * cf_flattener_require_space (struct cf_flattener *flattener, size_t count)
 
static bool cf_flattener_copy_instruction (struct cf_flattener *flattener, const struct vkd3d_shader_instruction *instruction)
 
static unsigned int cf_flattener_alloc_block_id (struct cf_flattener *flattener)
 
static struct vkd3d_shader_src_param * instruction_src_params_alloc (struct vkd3d_shader_instruction *ins, unsigned int count, struct cf_flattener *flattener)
 
static void cf_flattener_emit_label (struct cf_flattener *flattener, unsigned int label_id)
 
static struct vkd3d_shader_src_param * cf_flattener_emit_branch (struct cf_flattener *flattener, unsigned int merge_block_id, unsigned int continue_block_id, const struct vkd3d_shader_src_param *condition, unsigned int true_id, unsigned int false_id, unsigned int flags)
 
static void cf_flattener_emit_conditional_branch_and_merge (struct cf_flattener *flattener, const struct vkd3d_shader_src_param *condition, unsigned int true_id, unsigned int flags)
 
static void cf_flattener_emit_unconditional_branch (struct cf_flattener *flattener, unsigned int target_block_id)
 
static struct cf_flattener_info * cf_flattener_push_control_flow_level (struct cf_flattener *flattener)
 
static void cf_flattener_pop_control_flow_level (struct cf_flattener *flattener)
 
static struct cf_flattener_info * cf_flattener_find_innermost_loop (struct cf_flattener *flattener)
 
static struct cf_flattener_info * cf_flattener_find_innermost_breakable_cf_construct (struct cf_flattener *flattener)
 
static void VKD3D_PRINTF_FUNC (3, 4)
 
static enum vkd3d_result cf_flattener_iterate_instruction_array (struct cf_flattener *flattener, struct vkd3d_shader_message_context *message_context)
 
static enum vkd3d_result vsir_program_flatten_control_flow_constructs (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static unsigned int label_from_src_param (const struct vkd3d_shader_src_param *param)
 
static bool reserve_instructions (struct vkd3d_shader_instruction **instructions, size_t *capacity, size_t count)
 
static bool lower_switch_to_if_ladder_add_block_mapping (struct lower_switch_to_if_ladder_block_mapping **block_map, size_t *map_capacity, size_t *map_count, unsigned int switch_label, unsigned int if_label, unsigned int target_label)
 
static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool ssas_to_temps_alloc_init (struct ssas_to_temps_alloc *alloc, unsigned int ssa_count, unsigned int temp_count)
 
static void materialize_ssas_to_temps_process_reg (struct vsir_program *program, struct ssas_to_temps_alloc *alloc, struct vkd3d_shader_register *reg)
 
static void ssas_to_temps_block_info_cleanup (struct ssas_to_temps_block_info *block_info, size_t count)
 
static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static void vsir_block_list_init (struct vsir_block_list *list)
 
static void vsir_block_list_cleanup (struct vsir_block_list *list)
 
static enum vkd3d_result vsir_block_list_add_checked (struct vsir_block_list *list, struct vsir_block *block)
 
static enum vkd3d_result vsir_block_list_add (struct vsir_block_list *list, struct vsir_block *block)
 
static void vsir_block_list_remove_index (struct vsir_block_list *list, size_t idx)
 
static enum vkd3d_result vsir_block_init (struct vsir_block *block, unsigned int label, size_t block_count)
 
static void vsir_block_cleanup (struct vsir_block *block)
 
static int block_compare (const void *ptr1, const void *ptr2)
 
static void vsir_block_list_sort (struct vsir_block_list *list)
 
static bool vsir_block_list_search (struct vsir_block_list *list, struct vsir_block *block)
 
static void vsir_cfg_structure_init (struct vsir_cfg_structure *structure, enum vsir_cfg_structure_type type)
 
static void vsir_cfg_structure_cleanup (struct vsir_cfg_structure *structure)
 
static void vsir_cfg_structure_list_cleanup (struct vsir_cfg_structure_list *list)
 
static struct vsir_cfg_structure * vsir_cfg_structure_list_append (struct vsir_cfg_structure_list *list, enum vsir_cfg_structure_type type)
 
static enum vkd3d_result vsir_cfg_structure_list_append_from_region (struct vsir_cfg_structure_list *list, struct vsir_cfg_structure *begin, size_t size)
 
static void vsir_cfg_cleanup (struct vsir_cfg *cfg)
 
static enum vkd3d_result vsir_cfg_add_loop_interval (struct vsir_cfg *cfg, unsigned int begin, unsigned int end, bool synthetic)
 
static bool vsir_block_dominates (struct vsir_block *b1, struct vsir_block *b2)
 
static enum vkd3d_result vsir_cfg_add_edge (struct vsir_cfg *cfg, struct vsir_block *block, struct vkd3d_shader_src_param *successor_param)
 
static void vsir_cfg_dump_dot (struct vsir_cfg *cfg)
 
static void vsir_cfg_structure_list_dump (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
 
static void vsir_cfg_structure_dump (struct vsir_cfg *cfg, struct vsir_cfg_structure *structure)
 
static void vsir_cfg_dump_structured_program (struct vsir_cfg *cfg)
 
static enum vkd3d_result vsir_cfg_init (struct vsir_cfg *cfg, struct vsir_program *program, struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, size_t *pos)
 
static void vsir_cfg_compute_dominators_recurse (struct vsir_block *current, struct vsir_block *reference)
 
static void vsir_cfg_compute_dominators (struct vsir_cfg *cfg)
 
static enum vkd3d_result vsir_cfg_scan_loop (struct vsir_block_list *loop, struct vsir_block *block, struct vsir_block *header)
 
static enum vkd3d_result vsir_cfg_compute_loops (struct vsir_cfg *cfg)
 
static enum vkd3d_result vsir_cfg_sort_nodes (struct vsir_cfg *cfg)
 
static int compare_loop_intervals (const void *ptr1, const void *ptr2)
 
static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals (struct vsir_cfg *cfg)
 
static void vsir_cfg_compute_edge_action (struct vsir_cfg *cfg, struct vsir_block *block, struct vsir_block *successor, struct vsir_cfg_edge_action *action)
 
static enum vkd3d_result vsir_cfg_build_structured_program (struct vsir_cfg *cfg)
 
static void vsir_cfg_remove_trailing_continue (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, unsigned int target)
 
static struct vsir_cfg_structure * vsir_cfg_get_trailing_break (struct vsir_cfg_structure_list *list)
 
static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
 
static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections_recursively (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
 
static enum vkd3d_result vsir_cfg_synthesize_selections (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
 
static enum vkd3d_result vsir_cfg_append_loop (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *new_list, struct vsir_cfg_structure *loop)
 
static enum vkd3d_result vsir_cfg_optimize_recurse (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
 
static void vsir_cfg_count_targets (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
 
static void vsir_cfg_mark_trampolines (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, struct vsir_cfg_structure *loop)
 
static void vsir_cfg_mark_launchers (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, struct vsir_cfg_structure *loop)
 
static enum vkd3d_result vsir_cfg_optimize (struct vsir_cfg *cfg)
 
static enum vkd3d_result vsir_cfg_structure_list_emit (struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, unsigned int loop_idx)
 
static enum vkd3d_result vsir_cfg_structure_list_emit_block (struct vsir_cfg *cfg, struct vsir_block *block)
 
static enum vkd3d_result vsir_cfg_structure_list_emit_loop (struct vsir_cfg *cfg, struct vsir_cfg_structure_loop *loop, unsigned int loop_idx)
 
static enum vkd3d_result vsir_cfg_structure_list_emit_selection (struct vsir_cfg *cfg, struct vsir_cfg_structure_selection *selection, unsigned int loop_idx)
 
static enum vkd3d_result vsir_cfg_structure_list_emit_jump (struct vsir_cfg *cfg, struct vsir_cfg_structure_jump *jump, unsigned int loop_idx)
 
static enum vkd3d_result vsir_cfg_emit_structured_program (struct vsir_cfg *cfg)
 
static enum vkd3d_result vsir_program_structurize_function (struct vsir_program *program, struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, size_t *pos)
 
static enum vkd3d_result vsir_program_structurize (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static void register_map_undominated_use (struct vkd3d_shader_register *reg, struct ssas_to_temps_alloc *alloc, struct vsir_block *block, struct vsir_block **origin_blocks)
 
static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps (struct vsir_cfg *cfg)
 
static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function (struct vsir_program *program, struct vkd3d_shader_message_context *message_context, size_t *pos)
 
static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool use_flat_interpolation (const struct vsir_program *program, struct vkd3d_shader_message_context *message_context, bool *flat)
 
static enum vkd3d_result vsir_program_apply_flat_interpolation (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static enum vkd3d_result insert_alpha_test_before_ret (struct vsir_program *program, const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func, const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx, uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context)
 
static enum vkd3d_result vsir_program_insert_alpha_test (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static enum vkd3d_result insert_clip_planes_before_ret (struct vsir_program *program, const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx, uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos)
 
static enum vkd3d_result vsir_program_insert_clip_planes (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool is_pre_rasterization_shader (enum vkd3d_shader_type type)
 
static enum vkd3d_result insert_point_size_before_ret (struct vsir_program *program, const struct vkd3d_shader_instruction *ret, size_t *ret_pos)
 
static enum vkd3d_result vsir_program_insert_point_size (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static enum vkd3d_result vsir_program_insert_point_size_clamp (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static bool has_texcoord_signature_element (const struct shader_signature *signature)
 
static bool replace_texcoord_with_point_coord (struct vsir_program *program, struct vkd3d_shader_src_param *src, unsigned int coord_temp)
 
static enum vkd3d_result vsir_program_insert_point_coord (struct vsir_program *program, struct vsir_transformation_context *ctx)
 
static void vsir_validate_register_without_indices (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_io_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_temp_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_rastout_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_misctype_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_label_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_sampler_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_resource_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_uav_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_ssa_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_src_param (struct validation_context *ctx, const struct vkd3d_shader_src_param *src)
 
static void vsir_validate_register (struct validation_context *ctx, const struct vkd3d_shader_register *reg)
 
static void vsir_validate_dst_param (struct validation_context *ctx, const struct vkd3d_shader_dst_param *dst)
 
static void vsir_validate_dst_count (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
 
static void vsir_validate_src_count (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
 
static bool vsir_validate_src_min_count (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
 
static bool vsir_validate_src_max_count (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
 
static void vsir_validate_signature_element (struct validation_context *ctx, const struct shader_signature *signature, enum vsir_signature_type signature_type, unsigned int idx)
 
static void vsir_validate_signature (struct validation_context *ctx, const struct shader_signature *signature, enum vsir_signature_type signature_type)
 
static const char * name_from_cf_type (enum vsir_control_flow_type type)
 
static void vsir_validate_cf_type (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, enum vsir_control_flow_type expected_type)
 
static void vsir_validator_push_block (struct validation_context *ctx, enum vkd3d_shader_opcode opcode)
 
static void vsir_validate_hull_shader_phase (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_branch (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_gs_instances (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_hs_max_tessfactor (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_input_primitive (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_output_control_point_count (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_output_topology (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_temps (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_tessellator_domain (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_tessellator_output_primitive (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_tessellator_partitioning (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_dcl_vertices_out (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_else (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_endif (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_endloop (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_endrep (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_endswitch (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_if (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_ifc (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_label (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_loop (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_nop (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_phi (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_rep (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_ret (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_switch (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_switch_monolithic (struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
 
static void vsir_validate_instruction (struct validation_context *ctx)
 
enum vkd3d_result vsir_program_validate (struct vsir_program *program, uint64_t config_flags, const char *source_name, struct vkd3d_shader_message_context *message_context)
 
static void vsir_transform_ (struct vsir_transformation_context *ctx, const char *step_name, enum vkd3d_result(*step)(struct vsir_program *program, struct vsir_transformation_context *ctx))
 
enum vkd3d_result vsir_program_transform_early (struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
 
enum vkd3d_result vsir_program_transform (struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
 

Variables

static const char *const signature_type_names []
 
static const struct sysval_validation_data_element sysval_validation_data []
 
static const unsigned int allowed_signature_phases []
 
static const struct vsir_validator_instruction_desc vsir_validator_instructions []
 

Macro Definition Documentation

◆ CS_BIT

#define CS_BIT   (1u << VKD3D_SHADER_TYPE_COMPUTE)

Definition at line 7442 of file ir.c.

◆ DS_BIT

#define DS_BIT   (1u << VKD3D_SHADER_TYPE_DOMAIN)

Definition at line 7441 of file ir.c.

◆ GS_BIT

#define GS_BIT   (1u << VKD3D_SHADER_TYPE_GEOMETRY)

Definition at line 7439 of file ir.c.

◆ HS_BIT

#define HS_BIT   (1u << VKD3D_SHADER_TYPE_HULL)

Definition at line 7440 of file ir.c.

◆ PS_BIT

#define PS_BIT   (1u << VKD3D_SHADER_TYPE_PIXEL)

Definition at line 7437 of file ir.c.

◆ VKD3D_SHADER_SWIZZLE__

#define VKD3D_SHADER_SWIZZLE__   VKD3D_SHADER_SWIZZLE_X

◆ VS_BIT

#define VS_BIT   (1u << VKD3D_SHADER_TYPE_VERTEX)

Definition at line 7438 of file ir.c.

◆ vsir_transform

#define vsir_transform (   ctx,
  step 
)    vsir_transform_(ctx, #step, step)

Definition at line 8277 of file ir.c.

Enumeration Type Documentation

◆ vsir_signature_type

Enumerator
SIGNATURE_TYPE_INPUT 
SIGNATURE_TYPE_OUTPUT 
SIGNATURE_TYPE_PATCH_CONSTANT 

Definition at line 7423 of file ir.c.

7424{
7428};
@ SIGNATURE_TYPE_OUTPUT
Definition: ir.c:7426
@ SIGNATURE_TYPE_INPUT
Definition: ir.c:7425
@ SIGNATURE_TYPE_PATCH_CONSTANT
Definition: ir.c:7427

Function Documentation

◆ block_compare()

static int block_compare ( const void *  ptr1,
const void *  ptr2 
)
static

Definition at line 3617 of file ir.c.

3618{
3619 const struct vsir_block *block1 = *(const struct vsir_block **)ptr1;
3620 const struct vsir_block *block2 = *(const struct vsir_block **)ptr2;
3621
3622 return vkd3d_u32_compare(block1->label, block2->label);
3623}
static const struct metadata_block block1[]
Definition: metadata.c:3634
static const struct metadata_block block2[]
Definition: metadata.c:3639
static int vkd3d_u32_compare(uint32_t x, uint32_t y)
Definition: vkd3d_common.h:386

Referenced by vsir_block_list_search(), and vsir_block_list_sort().

◆ cf_flattener_alloc_block_id()

static unsigned int cf_flattener_alloc_block_id ( struct cf_flattener *  flattener)
static

Definition at line 2609 of file ir.c.

2610{
2611 return ++flattener->block_id;
2612}
unsigned int block_id
Definition: ir.c:2560

Referenced by cf_flattener_emit_conditional_branch_and_merge(), and cf_flattener_iterate_instruction_array().

◆ cf_flattener_copy_instruction()

static bool cf_flattener_copy_instruction ( struct cf_flattener *  flattener,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 2593 of file ir.c.

2595{
2596 struct vkd3d_shader_instruction *dst_ins;
2597
2599 return true;
2600
2601 if (!(dst_ins = cf_flattener_require_space(flattener, 1)))
2602 return false;
2603
2604 *dst_ins = *instruction;
2605 ++flattener->instruction_count;
2606 return true;
2607}
static struct vkd3d_shader_instruction * cf_flattener_require_space(struct cf_flattener *flattener, size_t count)
Definition: ir.c:2581
size_t instruction_count
Definition: ir.c:2558
@ VKD3DSIH_NOP

Referenced by cf_flattener_iterate_instruction_array().

◆ cf_flattener_emit_branch()

static struct vkd3d_shader_src_param * cf_flattener_emit_branch ( struct cf_flattener *  flattener,
unsigned int  merge_block_id,
unsigned int  continue_block_id,
const struct vkd3d_shader_src_param *  condition,
unsigned int  true_id,
unsigned int  false_id,
unsigned int  flags 
)
static

Definition at line 2642 of file ir.c.

2646{
2647 struct vkd3d_shader_src_param *src_params, *false_branch_param;
2648 struct vkd3d_shader_instruction *ins;
2649
2650 if (!(ins = cf_flattener_require_space(flattener, 1)))
2651 return NULL;
2653
2654 if (condition)
2655 {
2656 if (!(src_params = instruction_src_params_alloc(ins, 4 + !!continue_block_id, flattener)))
2657 return NULL;
2658 src_params[0] = *condition;
2660 {
2661 vsir_src_param_init_label(&src_params[1], false_id);
2662 vsir_src_param_init_label(&src_params[2], true_id);
2663 false_branch_param = &src_params[1];
2664 }
2665 else
2666 {
2667 vsir_src_param_init_label(&src_params[1], true_id);
2668 vsir_src_param_init_label(&src_params[2], false_id);
2669 false_branch_param = &src_params[2];
2670 }
2671 vsir_src_param_init_label(&src_params[3], merge_block_id);
2672 if (continue_block_id)
2673 vsir_src_param_init_label(&src_params[4], continue_block_id);
2674 }
2675 else
2676 {
2677 if (!(src_params = instruction_src_params_alloc(ins, merge_block_id ? 3 : 1, flattener)))
2678 return NULL;
2679 vsir_src_param_init_label(&src_params[0], true_id);
2680 if (merge_block_id)
2681 {
2682 /* An unconditional branch may only have merge information for a loop, which
2683 * must have both a merge block and continue block. */
2684 vsir_src_param_init_label(&src_params[1], merge_block_id);
2685 vsir_src_param_init_label(&src_params[2], continue_block_id);
2686 }
2687 false_branch_param = NULL;
2688 }
2689
2690 ++flattener->instruction_count;
2691
2692 return false_branch_param;
2693}
#define NULL
Definition: types.h:112
GLenum condition
Definition: glext.h:9255
GLbitfield flags
Definition: glext.h:7161
static struct vkd3d_shader_src_param * instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, unsigned int count, struct cf_flattener *flattener)
Definition: ir.c:2614
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
Definition: ir.c:204
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode)
Definition: ir.c:321
struct vkd3d_shader_location location
Definition: ir.c:2553
@ VKD3DSIH_BRANCH
@ VKD3D_SHADER_CONDITIONAL_OP_Z

Referenced by cf_flattener_emit_conditional_branch_and_merge(), cf_flattener_emit_unconditional_branch(), and cf_flattener_iterate_instruction_array().

◆ cf_flattener_emit_conditional_branch_and_merge()

static void cf_flattener_emit_conditional_branch_and_merge ( struct cf_flattener *  flattener,
const struct vkd3d_shader_src_param *  condition,
unsigned int  true_id,
unsigned int  flags 
)
static

Definition at line 2695 of file ir.c.

2697{
2698 unsigned int merge_block_id;
2699
2700 merge_block_id = cf_flattener_alloc_block_id(flattener);
2701 cf_flattener_emit_branch(flattener, merge_block_id, 0, condition, true_id, merge_block_id, flags);
2702 cf_flattener_emit_label(flattener, merge_block_id);
2703}
static struct vkd3d_shader_src_param * cf_flattener_emit_branch(struct cf_flattener *flattener, unsigned int merge_block_id, unsigned int continue_block_id, const struct vkd3d_shader_src_param *condition, unsigned int true_id, unsigned int false_id, unsigned int flags)
Definition: ir.c:2642
static unsigned int cf_flattener_alloc_block_id(struct cf_flattener *flattener)
Definition: ir.c:2609
static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int label_id)
Definition: ir.c:2629

Referenced by cf_flattener_iterate_instruction_array().

◆ cf_flattener_emit_label()

static void cf_flattener_emit_label ( struct cf_flattener *  flattener,
unsigned int  label_id 
)
static

Definition at line 2629 of file ir.c.

2630{
2631 struct vkd3d_shader_instruction *ins;
2632
2633 if (!(ins = cf_flattener_require_space(flattener, 1)))
2634 return;
2635 if (vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program))
2636 ++flattener->instruction_count;
2637 else
2639}
static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, unsigned int label_id, struct vsir_program *program)
Definition: ir.c:354
static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_result error)
Definition: ir.c:2574
struct vsir_program * program
Definition: ir.c:2551
@ VKD3D_ERROR_OUT_OF_MEMORY
Definition: vkd3d_types.h:49

Referenced by cf_flattener_emit_conditional_branch_and_merge(), and cf_flattener_iterate_instruction_array().

◆ cf_flattener_emit_unconditional_branch()

static void cf_flattener_emit_unconditional_branch ( struct cf_flattener *  flattener,
unsigned int  target_block_id 
)
static

Definition at line 2705 of file ir.c.

2706{
2707 cf_flattener_emit_branch(flattener, 0, 0, NULL, target_block_id, 0, 0);
2708}

Referenced by cf_flattener_iterate_instruction_array().

◆ cf_flattener_find_innermost_breakable_cf_construct()

static struct cf_flattener_info * cf_flattener_find_innermost_breakable_cf_construct ( struct cf_flattener *  flattener)
static

Definition at line 2744 of file ir.c.

2745{
2746 int depth;
2747
2748 for (depth = flattener->control_flow_depth - 1; depth >= 0; --depth)
2749 {
2750 if (flattener->control_flow_info[depth].current_block == VKD3D_BLOCK_LOOP
2751 || flattener->control_flow_info[depth].current_block == VKD3D_BLOCK_SWITCH)
2752 return &flattener->control_flow_info[depth];
2753 }
2754
2755 return NULL;
2756}
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
unsigned int control_flow_depth
Definition: ir.c:2569
struct cf_flattener_info * control_flow_info
Definition: ir.c:2570

Referenced by cf_flattener_iterate_instruction_array().

◆ cf_flattener_find_innermost_loop()

static struct cf_flattener_info * cf_flattener_find_innermost_loop ( struct cf_flattener *  flattener)
static

Definition at line 2731 of file ir.c.

2732{
2733 int depth;
2734
2735 for (depth = flattener->control_flow_depth - 1; depth >= 0; --depth)
2736 {
2737 if (flattener->control_flow_info[depth].current_block == VKD3D_BLOCK_LOOP)
2738 return &flattener->control_flow_info[depth];
2739 }
2740
2741 return NULL;
2742}

Referenced by cf_flattener_iterate_instruction_array().

◆ cf_flattener_iterate_instruction_array()

static enum vkd3d_result cf_flattener_iterate_instruction_array ( struct cf_flattener *  flattener,
struct vkd3d_shader_message_context *  message_context 
)
static

Definition at line 2783 of file ir.c.

2785{
2786 struct vkd3d_shader_instruction_array *instructions;
2787 struct vsir_program *program = flattener->program;
2788 bool is_hull_shader, after_declarations_section;
2789 struct vkd3d_shader_instruction *dst_ins;
2790 size_t i;
2791
2792 instructions = &program->instructions;
2793 is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL;
2794 after_declarations_section = is_hull_shader;
2795
2796 if (!cf_flattener_require_space(flattener, instructions->count + 1))
2798
2799 for (i = 0; i < instructions->count; ++i)
2800 {
2801 unsigned int loop_header_block_id, loop_body_block_id, continue_block_id, merge_block_id, true_block_id;
2802 const struct vkd3d_shader_instruction *instruction = &instructions->elements[i];
2803 const struct vkd3d_shader_src_param *src = instruction->src;
2804 struct cf_flattener_info *cf_info;
2805
2806 flattener->location = instruction->location;
2807
2808 /* Declarations should occur before the first code block, which in hull shaders is marked by the first
2809 * phase instruction, and in all other shader types begins with the first label instruction.
2810 * Declaring an indexable temp with function scope is not considered a declaration,
2811 * because it needs to live inside a function. */
2812 if (!after_declarations_section && instruction->opcode != VKD3DSIH_NOP)
2813 {
2814 bool is_function_indexable = instruction->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP
2815 && instruction->declaration.indexable_temp.has_function_scope;
2816
2817 if (!vsir_instruction_is_dcl(instruction) || is_function_indexable)
2818 {
2819 after_declarations_section = true;
2821 }
2822 }
2823
2824 cf_info = flattener->control_flow_depth
2825 ? &flattener->control_flow_info[flattener->control_flow_depth - 1] : NULL;
2826
2827 switch (instruction->opcode)
2828 {
2835 after_declarations_section = false;
2836 break;
2837
2838 case VKD3DSIH_LABEL:
2839 vkd3d_shader_error(message_context, &instruction->location,
2841 "Aborting due to not yet implemented feature: Label instruction.");
2843
2844 case VKD3DSIH_IF:
2845 if (!(cf_info = cf_flattener_push_control_flow_level(flattener)))
2847
2848 true_block_id = cf_flattener_alloc_block_id(flattener);
2849 merge_block_id = cf_flattener_alloc_block_id(flattener);
2850 cf_info->u.if_.false_param = cf_flattener_emit_branch(flattener, merge_block_id, 0,
2851 src, true_block_id, merge_block_id, instruction->flags);
2852 if (!cf_info->u.if_.false_param)
2854
2855 cf_flattener_emit_label(flattener, true_block_id);
2856
2857 cf_info->u.if_.id = flattener->branch_id;
2858 cf_info->u.if_.merge_block_id = merge_block_id;
2859 cf_info->u.if_.else_block_id = 0;
2860 cf_info->inside_block = true;
2861 cf_info->current_block = VKD3D_BLOCK_IF;
2862
2863 cf_flattener_create_block_name(flattener, merge_block_id, "branch%u_merge", flattener->branch_id);
2864 cf_flattener_create_block_name(flattener, true_block_id, "branch%u_true", flattener->branch_id);
2865 ++flattener->branch_id;
2866 break;
2867
2868 case VKD3DSIH_ELSE:
2869 if (cf_info->inside_block)
2870 cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id);
2871
2872 cf_info->u.if_.else_block_id = cf_flattener_alloc_block_id(flattener);
2873 cf_info->u.if_.false_param->reg.idx[0].offset = cf_info->u.if_.else_block_id;
2874
2875 cf_flattener_create_block_name(flattener,
2876 cf_info->u.if_.else_block_id, "branch%u_false", cf_info->u.if_.id);
2877 cf_flattener_emit_label(flattener, cf_info->u.if_.else_block_id);
2878
2879 cf_info->inside_block = true;
2880 break;
2881
2882 case VKD3DSIH_ENDIF:
2883 if (cf_info->inside_block)
2884 cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id);
2885
2886 cf_flattener_emit_label(flattener, cf_info->u.if_.merge_block_id);
2887
2889 break;
2890
2891 case VKD3DSIH_LOOP:
2892 if (!(cf_info = cf_flattener_push_control_flow_level(flattener)))
2894
2895 loop_header_block_id = cf_flattener_alloc_block_id(flattener);
2896 loop_body_block_id = cf_flattener_alloc_block_id(flattener);
2897 continue_block_id = cf_flattener_alloc_block_id(flattener);
2898 merge_block_id = cf_flattener_alloc_block_id(flattener);
2899
2900 cf_flattener_emit_unconditional_branch(flattener, loop_header_block_id);
2901 cf_flattener_emit_label(flattener, loop_header_block_id);
2902 cf_flattener_emit_branch(flattener, merge_block_id, continue_block_id,
2903 NULL, loop_body_block_id, 0, 0);
2904
2905 cf_flattener_emit_label(flattener, loop_body_block_id);
2906
2907 cf_info->u.loop.header_block_id = loop_header_block_id;
2908 cf_info->u.loop.continue_block_id = continue_block_id;
2909 cf_info->u.loop.merge_block_id = merge_block_id;
2911 cf_info->inside_block = true;
2912
2913 cf_flattener_create_block_name(flattener, loop_header_block_id, "loop%u_header", flattener->loop_id);
2914 cf_flattener_create_block_name(flattener, loop_body_block_id, "loop%u_body", flattener->loop_id);
2915 cf_flattener_create_block_name(flattener, continue_block_id, "loop%u_continue", flattener->loop_id);
2916 cf_flattener_create_block_name(flattener, merge_block_id, "loop%u_merge", flattener->loop_id);
2917 ++flattener->loop_id;
2918 break;
2919
2920 case VKD3DSIH_ENDLOOP:
2921 if (cf_info->inside_block)
2922 cf_flattener_emit_unconditional_branch(flattener, cf_info->u.loop.continue_block_id);
2923
2924 cf_flattener_emit_label(flattener, cf_info->u.loop.continue_block_id);
2925 cf_flattener_emit_unconditional_branch(flattener, cf_info->u.loop.header_block_id);
2926 cf_flattener_emit_label(flattener, cf_info->u.loop.merge_block_id);
2927
2929 break;
2930
2931 case VKD3DSIH_SWITCH:
2932 if (!(cf_info = cf_flattener_push_control_flow_level(flattener)))
2934
2935 merge_block_id = cf_flattener_alloc_block_id(flattener);
2936
2937 cf_info->u.switch_.ins_location = flattener->instruction_count;
2938 cf_info->u.switch_.condition = src;
2939
2940 if (!(dst_ins = cf_flattener_require_space(flattener, 1)))
2943 ++flattener->instruction_count;
2944
2945 cf_info->u.switch_.id = flattener->switch_id;
2946 cf_info->u.switch_.merge_block_id = merge_block_id;
2947 cf_info->u.switch_.cases = NULL;
2948 cf_info->u.switch_.cases_size = 0;
2949 cf_info->u.switch_.cases_count = 0;
2950 cf_info->u.switch_.default_block_id = 0;
2951 cf_info->inside_block = false;
2953
2954 cf_flattener_create_block_name(flattener, merge_block_id, "switch%u_merge", flattener->switch_id);
2955 ++flattener->switch_id;
2956
2957 if (!vkd3d_array_reserve((void **)&cf_info->u.switch_.cases, &cf_info->u.switch_.cases_size,
2958 10, sizeof(*cf_info->u.switch_.cases)))
2960
2961 break;
2962
2963 case VKD3DSIH_ENDSWITCH:
2964 {
2965 struct vkd3d_shader_src_param *src_params;
2966 unsigned int j;
2967
2968 if (!cf_info->u.switch_.default_block_id)
2969 cf_info->u.switch_.default_block_id = cf_info->u.switch_.merge_block_id;
2970
2971 cf_flattener_emit_label(flattener, cf_info->u.switch_.merge_block_id);
2972
2973 /* The SWITCH instruction is completed when the endswitch
2974 * instruction is processed because we do not know the number
2975 * of case statements or the default block id in advance.*/
2976 dst_ins = &flattener->instructions[cf_info->u.switch_.ins_location];
2977 if (!(src_params = instruction_src_params_alloc(dst_ins, cf_info->u.switch_.cases_count * 2 + 3, flattener)))
2978 {
2979 vkd3d_free(cf_info->u.switch_.cases);
2981 }
2982 src_params[0] = *cf_info->u.switch_.condition;
2983 vsir_src_param_init_label(&src_params[1], cf_info->u.switch_.default_block_id);
2984 vsir_src_param_init_label(&src_params[2], cf_info->u.switch_.merge_block_id);
2985 for (j = 0; j < cf_info->u.switch_.cases_count; ++j)
2986 {
2987 unsigned int index = j * 2 + 3;
2989 src_params[index].reg.u.immconst_u32[0] = cf_info->u.switch_.cases[j].value;
2990 vsir_src_param_init_label(&src_params[index + 1], cf_info->u.switch_.cases[j].block_id);
2991 }
2992 vkd3d_free(cf_info->u.switch_.cases);
2993
2995 break;
2996 }
2997
2998 case VKD3DSIH_CASE:
2999 {
3000 unsigned int label_id, value;
3001
3002 if (src->swizzle != VKD3D_SHADER_SWIZZLE(X, X, X, X))
3003 {
3004 WARN("Unexpected src swizzle %#x.\n", src->swizzle);
3005 vkd3d_shader_error(message_context, &instruction->location,
3007 "The swizzle for a switch case value is not scalar X.");
3009 }
3010 value = *src->reg.u.immconst_u32;
3011
3012 if (!vkd3d_array_reserve((void **)&cf_info->u.switch_.cases, &cf_info->u.switch_.cases_size,
3013 cf_info->u.switch_.cases_count + 1, sizeof(*cf_info->u.switch_.cases)))
3015
3016 label_id = cf_flattener_alloc_block_id(flattener);
3017 if (cf_info->inside_block) /* fall-through */
3018 cf_flattener_emit_unconditional_branch(flattener, label_id);
3019
3020 cf_info->u.switch_.cases[cf_info->u.switch_.cases_count].value = value;
3021 cf_info->u.switch_.cases[cf_info->u.switch_.cases_count].block_id = label_id;
3022 ++cf_info->u.switch_.cases_count;
3023
3024 cf_flattener_emit_label(flattener, label_id);
3025 cf_flattener_create_block_name(flattener, label_id, "switch%u_case%u", cf_info->u.switch_.id, value);
3026 cf_info->inside_block = true;
3027 break;
3028 }
3029
3030 case VKD3DSIH_DEFAULT:
3031 cf_info->u.switch_.default_block_id = cf_flattener_alloc_block_id(flattener);
3032 if (cf_info->inside_block) /* fall-through */
3033 cf_flattener_emit_unconditional_branch(flattener, cf_info->u.switch_.default_block_id);
3034
3035 cf_flattener_emit_label(flattener, cf_info->u.switch_.default_block_id);
3036
3037 cf_flattener_create_block_name(flattener, cf_info->u.switch_.default_block_id,
3038 "switch%u_default", cf_info->u.switch_.id);
3039 cf_info->inside_block = true;
3040 break;
3041
3042 case VKD3DSIH_BREAK:
3043 {
3044 struct cf_flattener_info *breakable_cf_info;
3045
3046 if (!(breakable_cf_info = cf_flattener_find_innermost_breakable_cf_construct(flattener)))
3047 {
3048 FIXME("Unhandled break instruction.\n");
3050 }
3051
3052 if (breakable_cf_info->current_block == VKD3D_BLOCK_LOOP)
3053 {
3054 cf_flattener_emit_unconditional_branch(flattener, breakable_cf_info->u.loop.merge_block_id);
3055 }
3056 else if (breakable_cf_info->current_block == VKD3D_BLOCK_SWITCH)
3057 {
3058 cf_flattener_emit_unconditional_branch(flattener, breakable_cf_info->u.switch_.merge_block_id);
3059 }
3060
3061 cf_info->inside_block = false;
3062 break;
3063 }
3064
3065 case VKD3DSIH_BREAKP:
3066 {
3067 struct cf_flattener_info *loop_cf_info;
3068
3069 if (!(loop_cf_info = cf_flattener_find_innermost_loop(flattener)))
3070 {
3071 ERR("Invalid 'breakc' instruction outside loop.\n");
3073 }
3074
3076 src, loop_cf_info->u.loop.merge_block_id, instruction->flags);
3077 break;
3078 }
3079
3080 case VKD3DSIH_CONTINUE:
3081 {
3082 struct cf_flattener_info *loop_cf_info;
3083
3084 if (!(loop_cf_info = cf_flattener_find_innermost_loop(flattener)))
3085 {
3086 ERR("Invalid 'continue' instruction outside loop.\n");
3088 }
3089
3090 cf_flattener_emit_unconditional_branch(flattener, loop_cf_info->u.loop.continue_block_id);
3091
3092 cf_info->inside_block = false;
3093 break;
3094 }
3095
3096 case VKD3DSIH_CONTINUEP:
3097 {
3098 struct cf_flattener_info *loop_cf_info;
3099
3100 if (!(loop_cf_info = cf_flattener_find_innermost_loop(flattener)))
3101 {
3102 ERR("Invalid 'continuec' instruction outside loop.\n");
3104 }
3105
3107 src, loop_cf_info->u.loop.continue_block_id, instruction->flags);
3108 break;
3109 }
3110
3111 case VKD3DSIH_RET:
3114
3115 if (cf_info)
3116 cf_info->inside_block = false;
3117 break;
3118
3119 default:
3122 break;
3123 }
3124 }
3125
3126 return flattener->status;
3127}
#define index(s, c)
Definition: various.h:29
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
GLenum src
Definition: glext.h:6340
GLuint index
Definition: glext.h:6031
GLuint program
Definition: glext.h:6723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction)
Definition: ir.c:371
static void cf_flattener_emit_unconditional_branch(struct cf_flattener *flattener, unsigned int target_block_id)
Definition: ir.c:2705
static void cf_flattener_emit_conditional_branch_and_merge(struct cf_flattener *flattener, const struct vkd3d_shader_src_param *condition, unsigned int true_id, unsigned int flags)
Definition: ir.c:2695
static struct cf_flattener_info * cf_flattener_find_innermost_loop(struct cf_flattener *flattener)
Definition: ir.c:2731
static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, const struct vkd3d_shader_instruction *instruction)
Definition: ir.c:2593
static struct cf_flattener_info * cf_flattener_push_control_flow_level(struct cf_flattener *flattener)
Definition: ir.c:2710
static struct cf_flattener_info * cf_flattener_find_innermost_breakable_cf_construct(struct cf_flattener *flattener)
Definition: ir.c:2744
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
Definition: ir.c:190
static void cf_flattener_pop_control_flow_level(struct cf_flattener *flattener)
Definition: ir.c:2723
@ VKD3D_BLOCK_SWITCH
Definition: ir.c:2544
@ VKD3D_BLOCK_IF
Definition: ir.c:2542
@ VKD3D_BLOCK_LOOP
Definition: ir.c:2543
bool inside_block
Definition: ir.c:2546
enum cf_flattener_info::@6005 current_block
struct cf_flattener_switch_info switch_
Definition: ir.c:2537
struct cf_flattener_loop_info loop
Definition: ir.c:2536
union cf_flattener_info::@6004 u
struct cf_flattener_if_info if_
Definition: ir.c:2535
unsigned int loop_id
Definition: ir.c:2566
struct vkd3d_shader_instruction * instructions
Definition: ir.c:2556
enum vkd3d_result status
Definition: ir.c:2554
unsigned int branch_id
Definition: ir.c:2565
unsigned int switch_id
Definition: ir.c:2567
struct shader_reg * src
struct vkd3d_shader_instruction * elements
struct vkd3d_shader_register reg
Definition: pdh_main.c:64
static void vkd3d_free(void *ptr)
Definition: vkd3d_memory.h:52
bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size)
Definition: memory.c:22
#define VKD3D_SHADER_SWIZZLE(x, y, z, w)
@ VKD3D_SHADER_TYPE_HULL
@ VKD3DSPR_IMMCONST
vkd3d_shader_error
@ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED
@ VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE
@ VKD3D_DATA_UINT
@ VKD3DSIH_ENDSWITCH
@ VKD3DSIH_HS_JOIN_PHASE
@ VKD3DSIH_LOOP
@ VKD3DSIH_SWITCH
@ VKD3DSIH_BREAK
@ VKD3DSIH_CASE
@ VKD3DSIH_CONTINUE
@ VKD3DSIH_IF
@ VKD3DSIH_ENDIF
@ VKD3DSIH_HS_CONTROL_POINT_PHASE
@ VKD3DSIH_CONTINUEP
@ VKD3DSIH_HS_FORK_PHASE
@ VKD3DSIH_SWITCH_MONOLITHIC
@ VKD3DSIH_ENDLOOP
@ VKD3DSIH_ELSE
@ VKD3DSIH_DCL_INDEXABLE_TEMP
@ VKD3DSIH_LABEL
@ VKD3DSIH_BREAKP
@ VKD3DSIH_DEFAULT
@ VKD3DSIH_RET
@ VKD3D_ERROR_NOT_IMPLEMENTED
Definition: vkd3d_types.h:55
@ VKD3D_ERROR_INVALID_SHADER
Definition: vkd3d_types.h:53

Referenced by vsir_program_flatten_control_flow_constructs().

◆ cf_flattener_pop_control_flow_level()

static void cf_flattener_pop_control_flow_level ( struct cf_flattener *  flattener)
static

Definition at line 2723 of file ir.c.

2724{
2725 struct cf_flattener_info *cf_info;
2726
2727 cf_info = &flattener->control_flow_info[--flattener->control_flow_depth];
2728 memset(cf_info, 0, sizeof(*cf_info));
2729}
#define memset(x, y, z)
Definition: compat.h:39

Referenced by cf_flattener_iterate_instruction_array().

◆ cf_flattener_push_control_flow_level()

static struct cf_flattener_info * cf_flattener_push_control_flow_level ( struct cf_flattener *  flattener)
static

Definition at line 2710 of file ir.c.

2711{
2712 if (!vkd3d_array_reserve((void **)&flattener->control_flow_info, &flattener->control_flow_info_size,
2713 flattener->control_flow_depth + 1, sizeof(*flattener->control_flow_info)))
2714 {
2715 ERR("Failed to allocate control flow info structure.\n");
2717 return NULL;
2718 }
2719
2720 return &flattener->control_flow_info[flattener->control_flow_depth++];
2721}
size_t control_flow_info_size
Definition: ir.c:2571

Referenced by cf_flattener_iterate_instruction_array().

◆ cf_flattener_require_space()

static struct vkd3d_shader_instruction * cf_flattener_require_space ( struct cf_flattener *  flattener,
size_t  count 
)
static

Definition at line 2581 of file ir.c.

2582{
2583 if (!vkd3d_array_reserve((void **)&flattener->instructions, &flattener->instruction_capacity,
2584 flattener->instruction_count + count, sizeof(*flattener->instructions)))
2585 {
2586 ERR("Failed to allocate instructions.\n");
2588 return NULL;
2589 }
2590 return &flattener->instructions[flattener->instruction_count];
2591}
GLuint GLuint GLsizei count
Definition: gl.h:1545
size_t instruction_capacity
Definition: ir.c:2557

Referenced by cf_flattener_copy_instruction(), cf_flattener_emit_branch(), cf_flattener_emit_label(), and cf_flattener_iterate_instruction_array().

◆ cf_flattener_set_error()

static void cf_flattener_set_error ( struct cf_flattener *  flattener,
enum vkd3d_result  error 
)
static

Definition at line 2574 of file ir.c.

2575{
2576 if (flattener->status != VKD3D_OK)
2577 return;
2578 flattener->status = error;
2579}
#define error(str)
Definition: mkdosfs.c:1605
@ VKD3D_OK
Definition: vkd3d_types.h:43

Referenced by cf_flattener_emit_label(), cf_flattener_iterate_instruction_array(), cf_flattener_push_control_flow_level(), cf_flattener_require_space(), and instruction_src_params_alloc().

◆ compare_loop_intervals()

static int compare_loop_intervals ( const void *  ptr1,
const void *  ptr2 
)
static

Definition at line 4542 of file ir.c.

4543{
4544 const struct cfg_loop_interval *interval1 = ptr1;
4545 const struct cfg_loop_interval *interval2 = ptr2;
4546
4547 if (interval1->begin != interval2->begin)
4548 return vkd3d_u32_compare(interval1->begin, interval2->begin);
4549
4550 return -vkd3d_u32_compare(interval1->end, interval2->end);
4551}

Referenced by vsir_cfg_generate_synthetic_loop_intervals().

◆ control_point_normaliser_emit_hs_input()

static enum vkd3d_result control_point_normaliser_emit_hs_input ( struct control_point_normaliser *  normaliser,
const struct shader_signature *  s,
unsigned int  input_control_point_count,
unsigned int  dst,
const struct vkd3d_shader_location *  location 
)
static

Definition at line 1381 of file ir.c.

1384{
1385 struct vkd3d_shader_instruction *ins;
1387 const struct signature_element *e;
1388 unsigned int i, count;
1389
1390 for (i = 0, count = 1; i < s->element_count; ++i)
1391 count += !!s->elements[i].used_mask;
1392
1393 if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count))
1395
1396 memmove(&normaliser->instructions.elements[dst + count], &normaliser->instructions.elements[dst],
1397 (normaliser->instructions.count - dst) * sizeof(*normaliser->instructions.elements));
1398 normaliser->instructions.count += count;
1399
1400 ins = &normaliser->instructions.elements[dst];
1402 ins->flags = 1;
1403 ++ins;
1404
1405 for (i = 0; i < s->element_count; ++i)
1406 {
1407 e = &s->elements[i];
1408 if (!e->used_mask)
1409 continue;
1410
1411 if (e->sysval_semantic != VKD3D_SHADER_SV_NONE)
1412 {
1415 ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
1416 }
1417 else
1418 {
1420 param = &ins->declaration.dst;
1421 }
1422
1424 param->reg.idx[0].offset = input_control_point_count;
1425 param->reg.idx[1].offset = e->register_index;
1426 param->write_mask = e->mask;
1427
1428 ++ins;
1429 }
1430
1431 return VKD3D_OK;
1432}
GLdouble s
Definition: gl.h:2039
GLenum GLenum dst
Definition: glext.h:6340
GLfloat param
Definition: glext.h:5796
static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param, const struct signature_element *e, enum vkd3d_shader_register_type reg_type, unsigned int idx_count)
Definition: ir.c:1372
#define e
Definition: ke_i.h:82
if(dx< 0)
Definition: linetemp.h:194
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
struct vkd3d_shader_instruction_array instructions
Definition: ir.c:1326
struct vkd3d_shader_register_semantic register_semantic
union vkd3d_shader_instruction::@6020 declaration
struct vkd3d_shader_dst_param * dst
@ VKD3D_SHADER_SV_NONE
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve)
@ VKD3DSPR_INPUT
@ VKD3DSIH_DCL_INPUT
@ VKD3DSIH_DCL_INPUT_SIV
static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_shader_sysval_semantic sysval)

Referenced by instruction_array_normalise_hull_shader_control_point_io().

◆ control_point_normaliser_is_in_control_point_phase()

static bool control_point_normaliser_is_in_control_point_phase ( const struct control_point_normaliser *  normaliser)
static

Definition at line 1331 of file ir.c.

1332{
1333 return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE;
1334}
enum vkd3d_shader_opcode phase
Definition: ir.c:1327

Referenced by shader_dst_param_normalise_outpointid().

◆ convert_parameter_info()

static int convert_parameter_info ( const struct vkd3d_shader_compile_info *  compile_info,
unsigned int *  ret_count,
const struct vkd3d_shader_parameter1 **  ret_parameters 
)
static

Definition at line 31 of file ir.c.

33{
34 const struct vkd3d_shader_spirv_target_info *spirv_info;
36
37 *ret_count = 0;
38 *ret_parameters = NULL;
39
40 if (!(spirv_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO)) || !spirv_info->parameter_count)
41 return VKD3D_OK;
42
43 if (!(parameters = vkd3d_calloc(spirv_info->parameter_count, sizeof(*parameters))))
45
46 for (unsigned int i = 0; i < spirv_info->parameter_count; ++i)
47 {
48 const struct vkd3d_shader_parameter *src = &spirv_info->parameters[i];
50
51 dst->name = src->name;
52 dst->type = src->type;
53 dst->data_type = src->data_type;
54
56 {
57 dst->u.immediate_constant.u.u32 = src->u.immediate_constant.u.u32;
58 }
60 {
61 dst->u.specialization_constant = src->u.specialization_constant;
62 }
63 else
64 {
65 ERR("Invalid parameter type %#x.\n", src->type);
67 }
68 }
69
70 *ret_count = spirv_info->parameter_count;
71 *ret_parameters = parameters;
72
73 return VKD3D_OK;
74}
static BYTE parameters[]
Definition: asn.c:558
const struct vkd3d_shader_parameter * parameters
static void * vkd3d_calloc(size_t count, size_t size)
Definition: vkd3d_memory.h:43
@ VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT
Definition: vkd3d_shader.h:487
@ VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT
Definition: vkd3d_shader.h:482
#define vkd3d_find_struct(c, t)
@ VKD3D_ERROR_INVALID_ARGUMENT
Definition: vkd3d_types.h:51

Referenced by vsir_program_init().

◆ dst_param_init_output()

static void dst_param_init_output ( struct vkd3d_shader_dst_param *  dst,
enum vkd3d_data_type  data_type,
uint32_t  idx,
uint32_t  write_mask 
)
static

Definition at line 312 of file ir.c.

314{
316 dst->reg.idx[0].offset = idx;
317 dst->reg.dimension = VSIR_DIMENSION_VEC4;
318 dst->write_mask = write_mask;
319}
unsigned int idx
Definition: utils.c:40
enum wined3d_data_type data_type
Definition: glsl_shader.c:71
void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
Definition: ir.c:272
@ VKD3DSPR_OUTPUT
@ VSIR_DIMENSION_VEC4

Referenced by vsir_program_remap_output_signature().

◆ dst_param_init_ssa_bool()

static void dst_param_init_ssa_bool ( struct vkd3d_shader_dst_param *  dst,
unsigned int  idx 
)
static

Definition at line 281 of file ir.c.

282{
284 dst->reg.idx[0].offset = idx;
285}
@ VKD3DSPR_SSA
@ VKD3D_DATA_BOOL

Referenced by insert_alpha_test_before_ret(), and vsir_program_lower_switch_to_selection_ladder().

◆ dst_param_init_ssa_float()

static void dst_param_init_ssa_float ( struct vkd3d_shader_dst_param *  dst,
unsigned int  idx 
)
static

Definition at line 287 of file ir.c.

288{
290 dst->reg.idx[0].offset = idx;
291}
@ VKD3D_DATA_FLOAT

Referenced by vsir_program_insert_point_size_clamp().

◆ dst_param_init_temp_bool()

static void dst_param_init_temp_bool ( struct vkd3d_shader_dst_param *  dst,
unsigned int  idx 
)
static

Definition at line 293 of file ir.c.

294{
296 dst->reg.idx[0].offset = idx;
297}
@ VKD3DSPR_TEMP

Referenced by vsir_cfg_structure_list_emit_loop().

◆ dst_param_init_temp_float4()

static void dst_param_init_temp_float4 ( struct vkd3d_shader_dst_param *  dst,
unsigned int  idx 
)
static

Definition at line 299 of file ir.c.

300{
302 dst->reg.idx[0].offset = idx;
303 dst->reg.dimension = VSIR_DIMENSION_VEC4;
304}

Referenced by vsir_program_insert_point_coord().

◆ dst_param_init_temp_uint()

static void dst_param_init_temp_uint ( struct vkd3d_shader_dst_param *  dst,
unsigned int  idx 
)
static

Definition at line 306 of file ir.c.

307{
309 dst->reg.idx[0].offset = idx;
310}

Referenced by vsir_cfg_structure_list_emit_jump().

◆ find_varying_map()

static const struct vkd3d_shader_varying_map * find_varying_map ( const struct vkd3d_shader_varying_map_info *  varying_map,
unsigned int  signature_idx 
)
static

Definition at line 925 of file ir.c.

927{
928 unsigned int i;
929
930 for (i = 0; i < varying_map->varying_count; ++i)
931 {
932 if (varying_map->varying_map[i].output_signature_index == signature_idx)
933 return &varying_map->varying_map[i];
934 }
935
936 return NULL;
937}
const struct vkd3d_shader_varying_map * varying_map

Referenced by vsir_program_remap_output_signature().

◆ flattener_eliminate_phase_related_dcls()

static void flattener_eliminate_phase_related_dcls ( struct hull_flattener *  normaliser,
unsigned int  index,
struct shader_phase_location_array *  locations 
)
static

Definition at line 1190 of file ir.c.

1192{
1193 struct vkd3d_shader_instruction *ins = &normaliser->instructions.elements[index];
1194 struct shader_phase_location *loc;
1195 bool b;
1196
1198 {
1200 /* Reset the phase info. */
1201 normaliser->phase_body_idx = ~0u;
1202 normaliser->phase = ins->opcode;
1203 normaliser->instance_count = 1;
1204 /* Leave the first occurrence and delete the rest. */
1205 if (b)
1207 return;
1208 }
1211 {
1212 normaliser->instance_count = ins->declaration.count + !ins->declaration.count;
1214 return;
1215 }
1217 &ins->declaration.dst.reg))
1218 {
1220 return;
1221 }
1222
1223 if (normaliser->phase == VKD3DSIH_INVALID || vsir_instruction_is_dcl(ins))
1224 return;
1225
1226 if (normaliser->phase_body_idx == ~0u)
1227 normaliser->phase_body_idx = index;
1228
1229 if (ins->opcode == VKD3DSIH_RET)
1230 {
1231 normaliser->last_ret_location = ins->location;
1233 if (locations->count >= ARRAY_SIZE(locations->locations))
1234 {
1235 FIXME("Insufficient space for phase location.\n");
1236 return;
1237 }
1238 loc = &locations->locations[locations->count++];
1239 loc->index = normaliser->phase_body_idx;
1240 loc->instance_count = normaliser->instance_count;
1241 loc->instruction_count = index - normaliser->phase_body_idx;
1242 }
1243}
#define ARRAY_SIZE(A)
Definition: main.h:20
GLsizei const GLint * locations
Definition: glext.h:10542
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flattener)
Definition: ir.c:1171
static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins)
Definition: ir.c:378
static bool shader_register_is_phase_instance_id(const struct vkd3d_shader_register *reg)
Definition: ir.c:185
#define b
Definition: ke_i.h:79
struct vkd3d_shader_location last_ret_location
Definition: ir.c:1168
unsigned int instance_count
Definition: ir.c:1165
enum vkd3d_shader_opcode phase
Definition: ir.c:1167
struct vkd3d_shader_instruction_array instructions
Definition: ir.c:1163
unsigned int phase_body_idx
Definition: ir.c:1166
unsigned int instance_count
Definition: ir.c:1179
unsigned int instruction_count
Definition: ir.c:1180
unsigned int index
Definition: ir.c:1178
struct vkd3d_shader_location location
enum vkd3d_shader_opcode opcode
@ VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT
@ VKD3DSIH_INVALID
@ VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT

Referenced by vsir_program_flatten_hull_shader_phases().

◆ flattener_flatten_phases()

static enum vkd3d_result flattener_flatten_phases ( struct hull_flattener *  normaliser,
struct shader_phase_location_array *  locations 
)
static

Definition at line 1245 of file ir.c.

1247{
1248 struct shader_phase_location *loc;
1249 unsigned int i, j, k, end, count;
1250
1251 for (i = 0, count = 0; i < locations->count; ++i)
1252 count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count;
1253
1254 if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count))
1256 end = normaliser->instructions.count;
1257 normaliser->instructions.count += count;
1258
1259 for (i = locations->count; i > 0; --i)
1260 {
1261 loc = &locations->locations[i - 1];
1262 j = loc->index + loc->instruction_count;
1263 memmove(&normaliser->instructions.elements[j + count], &normaliser->instructions.elements[j],
1264 (end - j) * sizeof(*normaliser->instructions.elements));
1265 end = j;
1266 count -= (loc->instance_count - 1) * loc->instruction_count;
1267 loc->index += count;
1268 }
1269
1270 for (i = 0, count = 0; i < locations->count; ++i)
1271 {
1272 loc = &locations->locations[i];
1273 /* Make a copy of the non-dcl instructions for each instance. */
1274 for (j = 1; j < loc->instance_count; ++j)
1275 {
1276 for (k = 0; k < loc->instruction_count; ++k)
1277 {
1279 loc->index + loc->instruction_count * j + k, loc->index + k))
1281 }
1282 }
1283 /* Replace each reference to the instance id with a constant instance id. */
1284 for (j = 0; j < loc->instance_count; ++j)
1285 {
1286 for (k = 0; k < loc->instruction_count; ++k)
1288 &normaliser->instructions.elements[loc->index + loc->instruction_count * j + k], j);
1289 }
1290 }
1291
1292 return VKD3D_OK;
1293}
GLuint GLuint end
Definition: gl.h:1545
static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_instruction *ins, unsigned int instance_id)
Definition: ir.c:811
int k
Definition: mpi.c:3369
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, unsigned int dst, unsigned int src)

Referenced by vsir_program_flatten_hull_shader_phases().

◆ flattener_is_in_fork_or_join_phase()

static bool flattener_is_in_fork_or_join_phase ( const struct hull_flattener *  flattener)
static

Definition at line 1171 of file ir.c.

1172{
1173 return flattener->phase == VKD3DSIH_HS_FORK_PHASE || flattener->phase == VKD3DSIH_HS_JOIN_PHASE;
1174}

Referenced by flattener_eliminate_phase_related_dcls().

◆ get_flat_constant_register_type()

static bool get_flat_constant_register_type ( const struct vkd3d_shader_register *  reg,
enum vkd3d_shader_d3dbc_constant_register *  set,
uint32_t *  index 
)
static

Definition at line 2295 of file ir.c.

2297{
2298 static const struct
2299 {
2303 }
2304 regs[] =
2305 {
2312 };
2313
2314 unsigned int i;
2315
2316 for (i = 0; i < ARRAY_SIZE(regs); ++i)
2317 {
2318 if (reg->type == regs[i].type)
2319 {
2320 if (reg->idx[0].rel_addr)
2321 {
2322 FIXME("Unhandled relative address.\n");
2323 return false;
2324 }
2325
2326 *set = regs[i].set;
2327 *index = regs[i].offset + reg->idx[0].offset;
2328 return true;
2329 }
2330 }
2331
2332 return false;
2333}
Definition: _set.h:50
set(const _Compare &__comp=_Compare(), const allocator_type &__a=allocator_type())
Definition: _set.h:89
UINT32 uint32_t
Definition: types.h:75
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLintptr offset
Definition: glext.h:5920
static int reg
Definition: i386-dis.c:1290
vkd3d_shader_d3dbc_constant_register
Definition: vkd3d_shader.h:913
@ VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER
Definition: vkd3d_shader.h:919
@ VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER
Definition: vkd3d_shader.h:915
@ VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER
Definition: vkd3d_shader.h:917
vkd3d_shader_register_type
@ VKD3DSPR_CONSTBOOL
@ VKD3DSPR_CONST4
@ VKD3DSPR_CONSTINT
@ VKD3DSPR_CONST
@ VKD3DSPR_CONST2
@ VKD3DSPR_CONST3

Referenced by shader_register_normalise_flat_constants(), and vsir_program_normalise_flat_constants().

◆ get_opcode_from_rel_op()

static bool get_opcode_from_rel_op ( enum vkd3d_shader_rel_op  rel_op,
enum vkd3d_data_type  data_type,
enum vkd3d_shader_opcode *  opcode,
bool *  requires_swap 
)
static

Definition at line 385 of file ir.c.

387{
388 switch (rel_op)
389 {
392 *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_GT);
394 {
395 *opcode = VKD3DSIH_LTO;
396 return true;
397 }
398 break;
399
402 *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_LE);
404 {
405 *opcode = VKD3DSIH_GEO;
406 return true;
407 }
408 break;
409
411 *requires_swap = false;
413 {
414 *opcode = VKD3DSIH_EQO;
415 return true;
416 }
417 break;
418
420 *requires_swap = false;
422 {
423 *opcode = VKD3DSIH_NEO;
424 return true;
425 }
426 break;
427 }
428 return false;
429}
@ VKD3DSIH_NEO
@ VKD3DSIH_EQO
@ VKD3DSIH_LTO
@ VKD3DSIH_GEO
@ VKD3D_SHADER_REL_OP_LT
@ VKD3D_SHADER_REL_OP_GT
@ VKD3D_SHADER_REL_OP_EQ
@ VKD3D_SHADER_REL_OP_GE
@ VKD3D_SHADER_REL_OP_NE
@ VKD3D_SHADER_REL_OP_LE

Referenced by vsir_program_lower_ifc().

◆ has_texcoord_signature_element()

static bool has_texcoord_signature_element ( const struct shader_signature *  signature)
static

Definition at line 6451 of file ir.c.

6452{
6453 for (size_t i = 0; i < signature->element_count; ++i)
6454 {
6455 if (!ascii_strcasecmp(signature->elements[i].semantic_name, "TEXCOORD"))
6456 return true;
6457 }
6458 return false;
6459}
static int ascii_strcasecmp(const char *a, const char *b)
Definition: vkd3d_common.h:437

Referenced by vsir_program_insert_point_coord().

◆ insert_alpha_test_before_ret()

static enum vkd3d_result insert_alpha_test_before_ret ( struct vsir_program *  program,
const struct vkd3d_shader_instruction *  ret,
enum vkd3d_shader_comparison_func  compare_func,
const struct vkd3d_shader_parameter1 *  ref,
uint32_t  colour_signature_idx,
uint32_t  colour_temp,
size_t *  ret_pos,
struct vkd3d_shader_message_context *  message_context 
)
static

Definition at line 5903 of file ir.c.

5907{
5908 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
5909 static const struct vkd3d_shader_location no_loc;
5910 size_t pos = ret - instructions->elements;
5911 struct vkd3d_shader_instruction *ins;
5912
5913 static const struct
5914 {
5915 enum vkd3d_shader_opcode float_opcode;
5916 enum vkd3d_shader_opcode uint_opcode;
5917 bool swap;
5918 }
5919 opcodes[] =
5920 {
5927 };
5928
5929 if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER)
5930 {
5931 if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
5933 ins = &program->instructions.elements[pos];
5934
5937 src_param_init_const_uint(&ins->src[0], 0);
5938
5939 *ret_pos = pos + 1;
5940 return VKD3D_OK;
5941 }
5942
5943 if (!shader_instruction_array_insert_at(&program->instructions, pos, 3))
5945
5946 ins = &program->instructions.elements[pos];
5947
5948 switch (ref->data_type)
5949 {
5951 vsir_instruction_init_with_params(program, ins, &ret->location, opcodes[compare_func].float_opcode, 1, 2);
5952 src_param_init_temp_float(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp);
5953 src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1],
5955 break;
5956
5958 vsir_instruction_init_with_params(program, ins, &ret->location, opcodes[compare_func].uint_opcode, 1, 2);
5959 src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp);
5960 src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1],
5962 break;
5963
5966 "Alpha test reference data type must be a single component.");
5968
5969 default:
5970 FIXME("Unhandled parameter data type %#x.\n", ref->data_type);
5972 }
5973
5974 dst_param_init_ssa_bool(&ins->dst[0], program->ssa_count);
5975 ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4;
5976 ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
5977
5978 ++ins;
5981 src_param_init_ssa_bool(&ins->src[0], program->ssa_count);
5982
5983 ++program->ssa_count;
5984
5985 ++ins;
5988 ins->dst[0].reg.idx[0].offset = colour_signature_idx;
5989 ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
5990 ins->dst[0].write_mask = program->output_signature.elements[colour_signature_idx].mask;
5991 src_param_init_temp_float(&ins->src[0], colour_temp);
5992 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
5993 ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
5994
5995 *ret_pos = pos + 3;
5996 return VKD3D_OK;
5997}
return ret
Definition: mutex.c:147
static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx)
Definition: ir.c:252
static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx)
Definition: ir.c:266
static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
Definition: ir.c:211
static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
Definition: ir.c:281
bool vsir_instruction_init_with_params(struct vsir_program *program, struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count)
Definition: ir.c:329
static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value)
Definition: ir.c:198
static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
Definition: ir.c:234
#define swap(a, b)
Definition: qsort.c:63
Definition: polytest.cpp:36
Definition: send.c:48
struct vkd3d_shader_src_param * src
@ VKD3D_SHADER_COMPARISON_FUNC_EQUAL
@ VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL
@ VKD3D_SHADER_COMPARISON_FUNC_NEVER
@ VKD3D_SHADER_COMPARISON_FUNC_GREATER
@ VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL
@ VKD3D_SHADER_COMPARISON_FUNC_LESS
@ VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL
@ VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4
Definition: vkd3d_shader.h:516
@ VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32
Definition: vkd3d_shader.h:507
@ VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32
Definition: vkd3d_shader.h:509
#define VKD3D_SHADER_NO_SWIZZLE
@ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF
Definition: vkd3d_shader.h:575
bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, unsigned int idx, unsigned int count)
@ VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER
vkd3d_shader_opcode
@ VKD3DSIH_UGE
@ VKD3DSIH_IEQ
@ VKD3DSIH_DISCARD
@ VKD3DSIH_INE
@ VKD3DSIH_MOV
@ VKD3DSIH_ULT

Referenced by vsir_program_insert_alpha_test().

◆ insert_clip_planes_before_ret()

static enum vkd3d_result insert_clip_planes_before_ret ( struct vsir_program *  program,
const struct vkd3d_shader_instruction *  ret,
uint32_t  mask,
uint32_t  position_signature_idx,
uint32_t  position_temp,
uint32_t  low_signature_idx,
uint32_t  high_signature_idx,
size_t *  ret_pos 
)
static

Definition at line 6082 of file ir.c.

6085{
6086 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
6087 size_t pos = ret - instructions->elements;
6088 struct vkd3d_shader_instruction *ins;
6089 unsigned int output_idx = 0;
6090
6093
6094 ins = &program->instructions.elements[pos];
6095
6096 for (unsigned int i = 0; i < 8; ++i)
6097 {
6098 if (!(mask & (1u << i)))
6099 continue;
6100
6102 src_param_init_temp_float4(&ins->src[0], position_temp);
6104 ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE;
6105 ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
6106
6108 if (output_idx < 4)
6109 ins->dst[0].reg.idx[0].offset = low_signature_idx;
6110 else
6111 ins->dst[0].reg.idx[0].offset = high_signature_idx;
6112 ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
6113 ins->dst[0].write_mask = (1u << (output_idx % 4));
6114 ++output_idx;
6115
6116 ++ins;
6117 }
6118
6121 ins->dst[0].reg.idx[0].offset = position_signature_idx;
6122 ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
6123 ins->dst[0].write_mask = program->output_signature.elements[position_signature_idx].mask;
6124 src_param_init_temp_float(&ins->src[0], position_temp);
6125 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
6126 ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
6127
6128 *ret_pos = pos + vkd3d_popcount(mask) + 1;
6129 return VKD3D_OK;
6130}
GLenum GLint GLuint mask
Definition: glext.h:6028
static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsigned int idx)
Definition: ir.c:258
static unsigned int vkd3d_popcount(unsigned int v)
Definition: vkd3d_common.h:280
@ VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0
Definition: vkd3d_shader.h:644
@ VKD3DSIH_DP4

Referenced by vsir_program_insert_clip_planes().

◆ insert_point_size_before_ret()

static enum vkd3d_result insert_point_size_before_ret ( struct vsir_program *  program,
const struct vkd3d_shader_instruction *  ret,
size_t *  ret_pos 
)
static

Definition at line 6272 of file ir.c.

6274{
6275 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
6276 size_t pos = ret - instructions->elements;
6277 struct vkd3d_shader_instruction *ins;
6278
6279 if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
6281
6282 ins = &program->instructions.elements[pos];
6283
6286 ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
6288
6289 *ret_pos = pos + 1;
6290 return VKD3D_OK;
6291}
@ VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE
Definition: vkd3d_shader.h:670
@ VKD3DSPR_RASTOUT
@ VSIR_RASTOUT_POINT_SIZE

Referenced by vsir_program_insert_point_size().

◆ instruction_array_normalise_hull_shader_control_point_io()

static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 1434 of file ir.c.

1436{
1437 struct vkd3d_shader_instruction_array *instructions;
1438 struct control_point_normaliser normaliser;
1439 unsigned int input_control_point_count;
1441 struct vkd3d_shader_instruction *ins;
1442 enum vkd3d_result ret;
1443 unsigned int i, j;
1444
1445 VKD3D_ASSERT(program->normalisation_level == VSIR_NOT_NORMALISED);
1446
1447 if (program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
1448 {
1449 program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO;
1450 return VKD3D_OK;
1451 }
1452
1453 if (!(normaliser.outpointid_param = vsir_program_create_outpointid_param(program)))
1454 {
1455 ERR("Failed to allocate src param.\n");
1457 }
1458 normaliser.instructions = program->instructions;
1459 instructions = &normaliser.instructions;
1460 normaliser.phase = VKD3DSIH_INVALID;
1461
1462 for (i = 0; i < normaliser.instructions.count; ++i)
1463 {
1464 ins = &instructions->elements[i];
1465
1466 switch (ins->opcode)
1467 {
1471 normaliser.phase = ins->opcode;
1472 break;
1473 default:
1474 if (vsir_instruction_is_dcl(ins))
1475 break;
1476 for (j = 0; j < ins->dst_count; ++j)
1477 shader_dst_param_normalise_outpointid(&ins->dst[j], &normaliser);
1478 break;
1479 }
1480 }
1481
1482 normaliser.phase = VKD3DSIH_INVALID;
1483 input_control_point_count = 1;
1484
1485 for (i = 0; i < instructions->count; ++i)
1486 {
1487 ins = &instructions->elements[i];
1488
1489 switch (ins->opcode)
1490 {
1492 input_control_point_count = ins->declaration.count;
1493 break;
1495 program->instructions = normaliser.instructions;
1496 program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO;
1497 return VKD3D_OK;
1500 /* ins may be relocated if the instruction array expands. */
1501 location = ins->location;
1502 ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature,
1503 input_control_point_count, i, &location);
1504 program->instructions = normaliser.instructions;
1505 program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO;
1506 return ret;
1507 default:
1508 break;
1509 }
1510 }
1511
1512 program->instructions = normaliser.instructions;
1513 program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO;
1514 return VKD3D_OK;
1515}
static void shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param *dst_param, struct control_point_normaliser *normaliser)
Definition: ir.c:1355
static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser, const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst, const struct vkd3d_shader_location *location)
Definition: ir.c:1381
struct vkd3d_shader_src_param * vsir_program_create_outpointid_param(struct vsir_program *program)
Definition: ir.c:1336
#define VKD3D_ASSERT(cond)
Definition: vkd3d_common.h:49
@ VSIR_NOT_NORMALISED
@ VSIR_NORMALISED_HULL_CONTROL_POINT_IO
@ VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT
vkd3d_result
Definition: vkd3d_types.h:41

Referenced by vsir_program_transform().

◆ instruction_src_params_alloc()

static struct vkd3d_shader_src_param * instruction_src_params_alloc ( struct vkd3d_shader_instruction *  ins,
unsigned int  count,
struct cf_flattener *  flattener 
)
static

Definition at line 2614 of file ir.c.

2616{
2618
2619 if (!(params = vsir_program_get_src_params(flattener->program, count)))
2620 {
2622 return NULL;
2623 }
2624 ins->src = params;
2625 ins->src_count = count;
2626 return params;
2627}
GLenum const GLfloat * params
Definition: glext.h:5645
static struct vkd3d_shader_src_param * vsir_program_get_src_params(struct vsir_program *program, unsigned int count)

Referenced by cf_flattener_emit_branch(), and cf_flattener_iterate_instruction_array().

◆ io_normaliser_add_index_range()

static void io_normaliser_add_index_range ( struct io_normaliser *  normaliser,
const struct vkd3d_shader_instruction *  ins 
)
static

Definition at line 1630 of file ir.c.

1632{
1634 const struct vkd3d_shader_register *reg = &range->dst.reg;
1635 const struct shader_signature *signature;
1636 uint8_t (*range_map)[VKD3D_VEC4_SIZE];
1637 struct signature_element *element;
1638 unsigned int reg_idx, write_mask;
1639
1640 switch (reg->type)
1641 {
1642 case VKD3DSPR_INPUT:
1644 range_map = normaliser->input_range_map;
1645 signature = normaliser->input_signature;
1646 break;
1648 range_map = normaliser->output_range_map;
1649 signature = normaliser->output_signature;
1650 break;
1651 case VKD3DSPR_OUTPUT:
1653 {
1654 range_map = normaliser->output_range_map;
1655 signature = normaliser->output_signature;
1656 break;
1657 }
1658 /* fall through */
1660 range_map = normaliser->pc_range_map;
1661 signature = normaliser->patch_constant_signature;
1662 break;
1663 default:
1664 /* Validated in the TPF reader. */
1666 }
1667
1668 reg_idx = reg->idx[reg->idx_count - 1].offset;
1669 write_mask = range->dst.write_mask;
1671 range_map_set_register_range(range_map, reg_idx, range->register_count, element->mask, true);
1672}
range
Definition: d3dx9_private.h:58
struct signature_element * vsir_signature_find_element_for_reg(const struct shader_signature *signature, unsigned int reg_idx, unsigned int write_mask)
Definition: ir.c:1573
static void range_map_set_register_range(uint8_t range_map[][VKD3D_VEC4_SIZE], unsigned int register_idx, unsigned int register_count, uint32_t write_mask, bool is_dcl_indexrange)
Definition: ir.c:1590
static bool io_normaliser_is_in_fork_or_join_phase(const struct io_normaliser *normaliser)
Definition: ir.c:1543
#define uint8_t
Definition: nsiface.idl:59
struct shader_signature * patch_constant_signature
Definition: ir.c:1524
uint8_t pc_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE]
Definition: ir.c:1538
uint8_t output_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE]
Definition: ir.c:1537
struct shader_signature * output_signature
Definition: ir.c:1523
struct shader_signature * input_signature
Definition: ir.c:1522
uint8_t input_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE]
Definition: ir.c:1536
struct vkd3d_shader_index_range index_range
#define vkd3d_unreachable()
Definition: vkd3d_common.h:119
@ VKD3DSPR_INCONTROLPOINT
@ VKD3DSPR_OUTCONTROLPOINT
@ VKD3DSPR_PATCHCONST
#define VKD3D_VEC4_SIZE

Referenced by vsir_program_normalise_io_registers().

◆ io_normaliser_is_in_control_point_phase()

static bool io_normaliser_is_in_control_point_phase ( const struct io_normaliser *  normaliser)
static

Definition at line 1548 of file ir.c.

1549{
1550 return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE;
1551}
enum vkd3d_shader_opcode phase
Definition: ir.c:1528

Referenced by shader_dst_param_io_normalise().

◆ io_normaliser_is_in_fork_or_join_phase()

static bool io_normaliser_is_in_fork_or_join_phase ( const struct io_normaliser *  normaliser)
static

Definition at line 1543 of file ir.c.

1544{
1545 return normaliser->phase == VKD3DSIH_HS_FORK_PHASE || normaliser->phase == VKD3DSIH_HS_JOIN_PHASE;
1546}

Referenced by io_normaliser_add_index_range(), and shader_dst_param_io_normalise().

◆ is_pre_rasterization_shader()

static bool is_pre_rasterization_shader ( enum vkd3d_shader_type  type)
static

Definition at line 6264 of file ir.c.

6265{
6270}
@ VKD3D_SHADER_TYPE_VERTEX
@ VKD3D_SHADER_TYPE_GEOMETRY
@ VKD3D_SHADER_TYPE_DOMAIN

Referenced by vsir_program_insert_point_size(), and vsir_program_insert_point_size_clamp().

◆ label_from_src_param()

static unsigned int label_from_src_param ( const struct vkd3d_shader_src_param *  param)
static

◆ lower_switch_to_if_ladder_add_block_mapping()

static bool lower_switch_to_if_ladder_add_block_mapping ( struct lower_switch_to_if_ladder_block_mapping **  block_map,
size_t *  map_capacity,
size_t *  map_count,
unsigned int  switch_label,
unsigned int  if_label,
unsigned int  target_label 
)
static

Definition at line 3187 of file ir.c.

3189{
3190 if (!vkd3d_array_reserve((void **)block_map, map_capacity, *map_count + 1, sizeof(**block_map)))
3191 {
3192 ERR("Failed to allocate block mapping.\n");
3193 return false;
3194 }
3195
3196 (*block_map)[*map_count].switch_label = switch_label;
3197 (*block_map)[*map_count].if_label = if_label;
3198 (*block_map)[*map_count].target_label = target_label;
3199
3200 *map_count += 1;
3201
3202 return true;
3203}

Referenced by vsir_program_lower_switch_to_selection_ladder().

◆ materialize_ssas_to_temps_process_reg()

static void materialize_ssas_to_temps_process_reg ( struct vsir_program *  program,
struct ssas_to_temps_alloc *  alloc,
struct vkd3d_shader_register *  reg 
)
static

Definition at line 3360 of file ir.c.

3362{
3363 unsigned int i;
3364
3365 if (reg->type == VKD3DSPR_SSA && alloc->table[reg->idx[0].offset] != UINT_MAX)
3366 {
3367 reg->type = VKD3DSPR_TEMP;
3368 reg->idx[0].offset = alloc->table[reg->idx[0].offset];
3369 }
3370
3371 for (i = 0; i < reg->idx_count; ++i)
3372 if (reg->idx[i].rel_addr)
3374}
#define UINT_MAX
Definition: limits.h:27
static void materialize_ssas_to_temps_process_reg(struct vsir_program *program, struct ssas_to_temps_alloc *alloc, struct vkd3d_shader_register *reg)
Definition: ir.c:3360
#define alloc
Definition: rosglue.h:13

Referenced by materialize_ssas_to_temps_process_reg(), vsir_cfg_materialize_undominated_ssas_to_temps(), and vsir_program_materialise_phi_ssas_to_temps().

◆ name_from_cf_type()

static const char * name_from_cf_type ( enum vsir_control_flow_type  type)
static

Definition at line 7648 of file ir.c.

7649{
7650 switch (type)
7651 {
7652 case VSIR_CF_STRUCTURED:
7653 return "structured";
7654 case VSIR_CF_BLOCKS:
7655 return "block-based";
7656 default:
7658 }
7659}
@ VSIR_CF_BLOCKS
@ VSIR_CF_STRUCTURED

Referenced by vsir_validate_cf_type().

◆ range_map_get_register_count()

static unsigned int range_map_get_register_count ( uint8_t  range_map[][VKD3D_VEC4_SIZE],
unsigned int  register_idx,
uint32_t  write_mask 
)
static

Definition at line 1584 of file ir.c.

1586{
1587 return range_map[register_idx][vsir_write_mask_get_component_idx(write_mask)];
1588}
static unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask)

Referenced by shader_signature_merge().

◆ range_map_set_register_range()

static void range_map_set_register_range ( uint8_t  range_map[][VKD3D_VEC4_SIZE],
unsigned int  register_idx,
unsigned int  register_count,
uint32_t  write_mask,
bool  is_dcl_indexrange 
)
static

Definition at line 1590 of file ir.c.

1592{
1593 unsigned int i, j, r, c, component_idx, component_count;
1594
1595 VKD3D_ASSERT(write_mask <= VKD3DSP_WRITEMASK_ALL);
1596 component_idx = vsir_write_mask_get_component_idx(write_mask);
1598
1599 VKD3D_ASSERT(register_idx < MAX_REG_OUTPUT && MAX_REG_OUTPUT - register_idx >= register_count);
1600
1601 if (range_map[register_idx][component_idx] > register_count && is_dcl_indexrange)
1602 {
1603 /* Validated in the TPF reader. */
1604 VKD3D_ASSERT(range_map[register_idx][component_idx] != UINT8_MAX);
1605 return;
1606 }
1607 if (range_map[register_idx][component_idx] == register_count)
1608 {
1609 /* Already done. This happens when fxc splits a register declaration by
1610 * component(s). The dcl_indexrange instructions are split too. */
1611 return;
1612 }
1613 range_map[register_idx][component_idx] = register_count;
1614
1615 for (i = 0; i < register_count; ++i)
1616 {
1617 r = register_idx + i;
1618 for (j = !i; j < component_count; ++j)
1619 {
1620 c = component_idx + j;
1621 /* A synthetic patch constant range which overlaps an existing range can start upstream of it
1622 * for fork/join phase instancing, but ranges declared by dcl_indexrange should not overlap.
1623 * The latter is validated in the TPF reader. */
1624 VKD3D_ASSERT(!range_map[r][c] || !is_dcl_indexrange);
1625 range_map[r][c] = UINT8_MAX;
1626 }
1627 }
1628}
unsigned int component_count
#define UINT8_MAX
Definition: stdint.h:83
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80
static unsigned int vsir_write_mask_component_count(uint32_t write_mask)
#define VKD3DSP_WRITEMASK_ALL

Referenced by io_normaliser_add_index_range(), and shader_signature_map_patch_constant_index_ranges().

◆ register_map_undominated_use()

static void register_map_undominated_use ( struct vkd3d_shader_register *  reg,
struct ssas_to_temps_alloc *  alloc,
struct vsir_block *  block,
struct vsir_block **  origin_blocks 
)
static

Definition at line 5688 of file ir.c.

5690{
5691 unsigned int i;
5692
5693 if (register_is_ssa(reg))
5694 {
5695 i = reg->idx[0].offset;
5696 if (alloc->table[i] == UINT_MAX && !vsir_block_dominates(origin_blocks[i], block))
5697 alloc->table[i] = alloc->next_temp_idx++;
5698 }
5699
5700 for (i = 0; i < reg->idx_count; ++i)
5701 if (reg->idx[i].rel_addr)
5702 register_map_undominated_use(&reg->idx[i].rel_addr->reg, alloc, block, origin_blocks);
5703}
static bool vsir_block_dominates(struct vsir_block *b1, struct vsir_block *b2)
Definition: ir.c:3866
static void register_map_undominated_use(struct vkd3d_shader_register *reg, struct ssas_to_temps_alloc *alloc, struct vsir_block *block, struct vsir_block **origin_blocks)
Definition: ir.c:5688
static bool register_is_ssa(const struct vkd3d_shader_register *reg)
static unsigned int block
Definition: xmlmemory.c:101

Referenced by register_map_undominated_use(), and vsir_cfg_materialize_undominated_ssas_to_temps().

◆ remove_unread_output_components()

static void remove_unread_output_components ( const struct shader_signature *  signature,
struct vkd3d_shader_instruction *  ins,
struct vkd3d_shader_dst_param *  dst 
)
static

Definition at line 970 of file ir.c.

972{
973 const struct signature_element *e;
974
975 switch (dst->reg.type)
976 {
977 case VKD3DSPR_OUTPUT:
978 e = vsir_signature_find_element_for_reg(signature, dst->reg.idx[0].offset, 0);
979 break;
980
981 case VKD3DSPR_ATTROUT:
983 SM1_COLOR_REGISTER_OFFSET + dst->reg.idx[0].offset, 0);
984 break;
985
986 case VKD3DSPR_RASTOUT:
988 SM1_RASTOUT_REGISTER_OFFSET + dst->reg.idx[0].offset, 0);
989 break;
990
991 default:
992 return;
993 }
994
995 /* We already changed the mask earlier. */
996 dst->write_mask &= e->mask;
997
998 if (!dst->write_mask)
999 {
1000 if (ins->dst_count == 1)
1002 else
1004 }
1005}
@ VKD3DSPR_NULL
@ VKD3DSPR_ATTROUT
@ VKD3D_DATA_UNUSED
#define SM1_COLOR_REGISTER_OFFSET
#define SM1_RASTOUT_REGISTER_OFFSET

Referenced by vsir_program_remap_output_signature().

◆ replace_texcoord_with_point_coord()

static bool replace_texcoord_with_point_coord ( struct vsir_program *  program,
struct vkd3d_shader_src_param *  src,
unsigned int  coord_temp 
)
static

Definition at line 6462 of file ir.c.

6464{
6465 uint32_t prev_swizzle = src->swizzle;
6466 const struct signature_element *e;
6467
6468 /* The input semantic may have a nontrivial mask, which we need to
6469 * correct for. E.g. if the mask is .yz, and we read from .y, that needs
6470 * to become .x. */
6471 static const uint32_t inverse_swizzles[16] =
6472 {
6473 /* Use _ for "undefined" components, for clarity. */
6474#define VKD3D_SHADER_SWIZZLE__ VKD3D_SHADER_SWIZZLE_X
6475 0,
6476 /* .x */ VKD3D_SHADER_SWIZZLE(X, _, _, _),
6477 /* .y */ VKD3D_SHADER_SWIZZLE(_, X, _, _),
6478 /* .xy */ VKD3D_SHADER_SWIZZLE(X, Y, _, _),
6479 /* .z */ VKD3D_SHADER_SWIZZLE(_, _, X, _),
6480 /* .xz */ VKD3D_SHADER_SWIZZLE(X, _, Y, _),
6481 /* .yz */ VKD3D_SHADER_SWIZZLE(_, X, Y, _),
6482 /* .xyz */ VKD3D_SHADER_SWIZZLE(X, Y, Z, _),
6483 /* .w */ VKD3D_SHADER_SWIZZLE(_, _, _, X),
6484 /* .xw */ VKD3D_SHADER_SWIZZLE(X, _, _, Y),
6485 /* .yw */ VKD3D_SHADER_SWIZZLE(_, X, _, Y),
6486 /* .xyw */ VKD3D_SHADER_SWIZZLE(X, Y, _, Z),
6487 /* .zw */ VKD3D_SHADER_SWIZZLE(_, _, X, Y),
6488 /* .xzw */ VKD3D_SHADER_SWIZZLE(X, _, Y, Z),
6489 /* .yzw */ VKD3D_SHADER_SWIZZLE(_, X, Y, Z),
6490 /* .xyzw */ VKD3D_SHADER_SWIZZLE(X, Y, Z, W),
6491#undef VKD3D_SHADER_SWIZZLE__
6492 };
6493
6494 if (src->reg.type != VKD3DSPR_INPUT)
6495 return false;
6496 e = &program->input_signature.elements[src->reg.idx[0].offset];
6497
6498 if (ascii_strcasecmp(e->semantic_name, "TEXCOORD"))
6499 return false;
6500
6501 src->reg.type = VKD3DSPR_TEMP;
6502 src->reg.idx[0].offset = coord_temp;
6503
6504 /* If the mask is already contiguous and zero-based, no need to remap
6505 * the swizzle. */
6506 if (!(e->mask & (e->mask + 1)))
6507 return true;
6508
6509 src->swizzle = 0;
6510 for (unsigned int i = 0; i < 4; ++i)
6511 {
6512 src->swizzle |= vsir_swizzle_get_component(inverse_swizzles[e->mask],
6514 }
6515
6516 return true;
6517}
#define Z(I)
#define Y(I)
#define _(op)
Definition: opcodes.c:24
#define VKD3D_SHADER_SWIZZLE_SHIFT(idx)
static unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx)

Referenced by vsir_program_insert_point_coord().

◆ reserve_instructions()

static bool reserve_instructions ( struct vkd3d_shader_instruction **  instructions,
size_t *  capacity,
size_t  count 
)
static

Definition at line 3166 of file ir.c.

3167{
3168 if (!vkd3d_array_reserve((void **)instructions, capacity, count, sizeof(**instructions)))
3169 {
3170 ERR("Failed to allocate instructions.\n");
3171 return false;
3172 }
3173
3174 return true;
3175}

Referenced by vsir_cfg_structure_list_emit_block(), vsir_cfg_structure_list_emit_jump(), vsir_cfg_structure_list_emit_loop(), vsir_cfg_structure_list_emit_selection(), vsir_program_lower_switch_to_selection_ladder(), vsir_program_materialise_phi_ssas_to_temps(), and vsir_program_structurize().

◆ shader_dst_param_io_init()

static void shader_dst_param_io_init ( struct vkd3d_shader_dst_param *  param,
const struct signature_element *  e,
enum vkd3d_shader_register_type  reg_type,
unsigned int  idx_count 
)
static

Definition at line 1372 of file ir.c.

1374{
1375 param->write_mask = e->mask;
1376 param->modifiers = 0;
1377 param->shift = 0;
1378 vsir_register_init(&param->reg, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
1379}
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
Definition: ir.c:164
enum vkd3d_shader_register_type reg_type
Definition: spirv.c:4885
static enum vkd3d_data_type vkd3d_data_type_from_component_type(enum vkd3d_shader_component_type component_type)

Referenced by control_point_normaliser_emit_hs_input().

◆ shader_dst_param_io_normalise()

static bool shader_dst_param_io_normalise ( struct vkd3d_shader_dst_param *  dst_param,
bool  is_io_dcl,
struct io_normaliser *  normaliser 
)
static

Definition at line 1952 of file ir.c.

1954 {
1955 unsigned int id_idx, reg_idx, write_mask, element_idx;
1956 struct vkd3d_shader_register *reg = &dst_param->reg;
1957 struct vkd3d_shader_dst_param **dcl_params;
1958 const struct shader_signature *signature;
1959 const struct signature_element *e;
1960
1961 write_mask = dst_param->write_mask;
1962
1963 switch (reg->type)
1964 {
1965 case VKD3DSPR_OUTPUT:
1966 reg_idx = reg->idx[reg->idx_count - 1].offset;
1968 {
1969 signature = normaliser->patch_constant_signature;
1970 /* Convert patch constant outputs to the patch constant register type to avoid the need
1971 * to convert compiler symbols when accessed as inputs in a later stage. */
1972 reg->type = VKD3DSPR_PATCHCONST;
1973 dcl_params = normaliser->pc_dcl_params;
1974 }
1975 else
1976 {
1977 signature = normaliser->output_signature;
1978 dcl_params = normaliser->output_dcl_params;
1979 }
1980 break;
1981
1983 reg_idx = reg->idx[reg->idx_count - 1].offset;
1984 signature = normaliser->patch_constant_signature;
1985 dcl_params = normaliser->pc_dcl_params;
1986 break;
1987
1988 case VKD3DSPR_COLOROUT:
1989 reg_idx = reg->idx[0].offset;
1990 signature = normaliser->output_signature;
1991 reg->type = VKD3DSPR_OUTPUT;
1992 dcl_params = normaliser->output_dcl_params;
1993 break;
1994
1996 case VKD3DSPR_INPUT:
1997 reg_idx = reg->idx[reg->idx_count - 1].offset;
1998 signature = normaliser->input_signature;
1999 reg->type = VKD3DSPR_INPUT;
2000 dcl_params = normaliser->input_dcl_params;
2001 break;
2002
2003 case VKD3DSPR_ATTROUT:
2004 reg_idx = SM1_COLOR_REGISTER_OFFSET + reg->idx[0].offset;
2005 signature = normaliser->output_signature;
2006 reg->type = VKD3DSPR_OUTPUT;
2007 dcl_params = normaliser->output_dcl_params;
2008 break;
2009
2010 case VKD3DSPR_RASTOUT:
2011 /* Leave point size as a system value for the backends to consume. */
2012 if (reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
2013 return true;
2014 reg_idx = SM1_RASTOUT_REGISTER_OFFSET + reg->idx[0].offset;
2015 signature = normaliser->output_signature;
2016 reg->type = VKD3DSPR_OUTPUT;
2017 dcl_params = normaliser->output_dcl_params;
2018 /* Fog and point size are scalar, but fxc/d3dcompiler emits a full
2019 * write mask when writing to them. */
2020 if (reg->idx[0].offset > 0)
2021 write_mask = VKD3DSP_WRITEMASK_0;
2022 break;
2023
2024 default:
2025 return true;
2026 }
2027
2028 id_idx = reg->idx_count - 1;
2029 if (!shader_signature_find_element_for_reg(signature, reg_idx, write_mask, &element_idx))
2031 e = &signature->elements[element_idx];
2032
2033 if (is_io_dcl)
2034 {
2035 /* Validated in the TPF reader. */
2036 VKD3D_ASSERT(element_idx < ARRAY_SIZE(normaliser->input_dcl_params));
2037
2038 if (dcl_params[element_idx])
2039 {
2040 /* Merge split declarations into a single one. */
2041 dcl_params[element_idx]->write_mask |= dst_param->write_mask;
2042 /* Turn this into a nop. */
2043 return false;
2044 }
2045 else
2046 {
2047 dcl_params[element_idx] = dst_param;
2048 }
2049 }
2050
2052 {
2053 if (is_io_dcl)
2054 {
2055 /* Emit an array size for the control points for consistency with inputs. */
2056 reg->idx[0].offset = normaliser->output_control_point_count;
2057 }
2058 else
2059 {
2060 /* The control point id param. */
2061 VKD3D_ASSERT(reg->idx[0].rel_addr);
2062 }
2063 id_idx = 1;
2064 }
2065
2066 if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
2067 {
2068 if (is_io_dcl)
2069 {
2070 /* For control point I/O, idx 0 contains the control point count.
2071 * Ensure it is moved up to the next slot. */
2072 reg->idx[id_idx].offset = reg->idx[0].offset;
2073 reg->idx[0].offset = e->register_count;
2074 ++id_idx;
2075 }
2076 else
2077 {
2078 id_idx = shader_register_normalise_arrayed_addressing(reg, id_idx, e->register_index);
2079 }
2080 }
2081
2082 /* Replace the register index with the signature element index */
2083 reg->idx[id_idx].offset = element_idx;
2084 reg->idx_count = id_idx + 1;
2085
2086 return true;
2087}
static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_shader_register *reg, unsigned int id_idx, unsigned int register_index)
Definition: ir.c:1918
static bool shader_signature_find_element_for_reg(const struct shader_signature *signature, unsigned int reg_idx, unsigned int write_mask, unsigned int *element_idx)
Definition: ir.c:1553
static bool io_normaliser_is_in_control_point_phase(const struct io_normaliser *normaliser)
Definition: ir.c:1548
struct vkd3d_shader_dst_param * pc_dcl_params[MAX_REG_OUTPUT]
Definition: ir.c:1535
unsigned int output_control_point_count
Definition: ir.c:1529
struct vkd3d_shader_dst_param * output_dcl_params[MAX_REG_OUTPUT]
Definition: ir.c:1534
struct vkd3d_shader_dst_param * input_dcl_params[MAX_REG_OUTPUT]
Definition: ir.c:1533
struct vkd3d_shader_register reg
@ VKD3DSPR_COLOROUT
static bool vsir_sysval_semantic_is_tess_factor(enum vkd3d_shader_sysval_semantic sysval_semantic)
#define VKD3DSP_WRITEMASK_0

Referenced by shader_instruction_normalise_io_params().

◆ shader_dst_param_normalise_outpointid()

static void shader_dst_param_normalise_outpointid ( struct vkd3d_shader_dst_param *  dst_param,
struct control_point_normaliser *  normaliser 
)
static

Definition at line 1355 of file ir.c.

1357{
1358 struct vkd3d_shader_register *reg = &dst_param->reg;
1359
1361 {
1362 /* The TPF reader validates idx_count. */
1363 VKD3D_ASSERT(reg->idx_count == 1);
1364 reg->idx[1] = reg->idx[0];
1365 /* The control point id param is implicit here. Avoid later complications by inserting it. */
1366 reg->idx[0].offset = 0;
1367 reg->idx[0].rel_addr = normaliser->outpointid_param;
1368 ++reg->idx_count;
1369 }
1370}
static bool control_point_normaliser_is_in_control_point_phase(const struct control_point_normaliser *normaliser)
Definition: ir.c:1331
struct vkd3d_shader_src_param * outpointid_param
Definition: ir.c:1328

Referenced by instruction_array_normalise_hull_shader_control_point_io().

◆ shader_instruction_eliminate_phase_instance_id()

static void shader_instruction_eliminate_phase_instance_id ( struct vkd3d_shader_instruction *  ins,
unsigned int  instance_id 
)
static

Definition at line 811 of file ir.c.

813{
815 unsigned int i;
816
817 for (i = 0; i < ins->src_count; ++i)
818 {
819 reg = (struct vkd3d_shader_register *)&ins->src[i].reg;
821 {
823 reg->u.immconst_u32[0] = instance_id;
824 continue;
825 }
827 }
828
829 for (i = 0; i < ins->dst_count; ++i)
830 shader_register_eliminate_phase_addressing(&ins->dst[i].reg, instance_id);
831}
static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg, unsigned int instance_id)
Definition: ir.c:796

Referenced by flattener_flatten_phases().

◆ shader_instruction_normalise_io_params()

static void shader_instruction_normalise_io_params ( struct vkd3d_shader_instruction *  ins,
struct io_normaliser *  normaliser 
)
static

Definition at line 2169 of file ir.c.

2171{
2172 struct vkd3d_shader_register *reg;
2173 unsigned int i;
2174
2175 switch (ins->opcode)
2176 {
2177 case VKD3DSIH_DCL_INPUT:
2178 if (normaliser->shader_type == VKD3D_SHADER_TYPE_HULL)
2179 {
2180 reg = &ins->declaration.dst.reg;
2181
2182 if (reg->type == VKD3DSPR_OUTCONTROLPOINT)
2183 normaliser->use_vocp = true;
2184
2185 /* We don't need to keep OUTCONTROLPOINT or PATCHCONST input declarations since their
2186 * equivalents were declared earlier, but INCONTROLPOINT may be the first occurrence. */
2187 if (reg->type == VKD3DSPR_OUTCONTROLPOINT || reg->type == VKD3DSPR_PATCHCONST)
2189 else if (reg->type == VKD3DSPR_INCONTROLPOINT)
2190 reg->type = VKD3DSPR_INPUT;
2191 }
2192 /* fall through */
2195 if (!shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser))
2197 break;
2203 if (!shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true, normaliser))
2205 break;
2209 normaliser->phase = ins->opcode;
2210 memset(normaliser->input_dcl_params, 0, sizeof(normaliser->input_dcl_params));
2211 memset(normaliser->output_dcl_params, 0, sizeof(normaliser->output_dcl_params));
2212 memset(normaliser->pc_dcl_params, 0, sizeof(normaliser->pc_dcl_params));
2213 break;
2214 default:
2215 if (vsir_instruction_is_dcl(ins))
2216 break;
2217 for (i = 0; i < ins->dst_count; ++i)
2218 shader_dst_param_io_normalise(&ins->dst[i], false, normaliser);
2219 for (i = 0; i < ins->src_count; ++i)
2220 shader_src_param_io_normalise(&ins->src[i], normaliser);
2221 break;
2222 }
2223}
static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_param, bool is_io_dcl, struct io_normaliser *normaliser)
Definition: ir.c:1952
static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_param, struct io_normaliser *normaliser)
Definition: ir.c:2089
bool use_vocp
Definition: ir.c:1540
enum vkd3d_shader_type shader_type
Definition: ir.c:1520
@ VKD3DSIH_DCL_INPUT_PS
@ VKD3DSIH_DCL_OUTPUT
@ VKD3DSIH_DCL_OUTPUT_SIV
@ VKD3DSIH_DCL_INPUT_SGV
@ VKD3DSIH_DCL_INPUT_PS_SIV
@ VKD3DSIH_DCL_INPUT_PS_SGV

Referenced by vsir_program_normalise_io_registers().

◆ shader_register_eliminate_phase_addressing()

static void shader_register_eliminate_phase_addressing ( struct vkd3d_shader_register *  reg,
unsigned int  instance_id 
)
static

Definition at line 796 of file ir.c.

798{
799 unsigned int i;
800
801 for (i = 0; i < reg->idx_count; ++i)
802 {
803 if (reg->idx[i].rel_addr && shader_register_is_phase_instance_id(&reg->idx[i].rel_addr->reg))
804 {
805 reg->idx[i].rel_addr = NULL;
806 reg->idx[i].offset += instance_id;
807 }
808 }
809}

Referenced by shader_instruction_eliminate_phase_instance_id().

◆ shader_register_is_phase_instance_id()

static bool shader_register_is_phase_instance_id ( const struct vkd3d_shader_register *  reg)
inlinestatic

◆ shader_register_normalise_arrayed_addressing()

static unsigned int shader_register_normalise_arrayed_addressing ( struct vkd3d_shader_register *  reg,
unsigned int  id_idx,
unsigned int  register_index 
)
static

Definition at line 1918 of file ir.c.

1920{
1921 VKD3D_ASSERT(id_idx < ARRAY_SIZE(reg->idx) - 1);
1922
1923 /* For a relative-addressed register index, move the id up a slot to separate it from the address,
1924 * because rel_addr can be replaced with a constant offset in some cases. */
1925 if (reg->idx[id_idx].rel_addr)
1926 {
1927 reg->idx[id_idx + 1].rel_addr = NULL;
1928 reg->idx[id_idx + 1].offset = reg->idx[id_idx].offset;
1929 reg->idx[id_idx].offset -= register_index;
1930 if (id_idx)
1931 {
1932 /* idx[id_idx] now contains the array index, which must be moved below the control point id. */
1933 struct vkd3d_shader_register_index tmp = reg->idx[id_idx];
1934 reg->idx[id_idx] = reg->idx[id_idx - 1];
1935 reg->idx[id_idx - 1] = tmp;
1936 }
1937 ++id_idx;
1938 }
1939 /* Otherwise we have no address for the arrayed register, so insert one. This happens e.g. where
1940 * tessellation level registers are merged into an array because they're an array in SPIR-V. */
1941 else
1942 {
1943 ++id_idx;
1944 memmove(&reg->idx[1], &reg->idx[0], id_idx * sizeof(reg->idx[0]));
1945 reg->idx[0].rel_addr = NULL;
1946 reg->idx[0].offset = reg->idx[id_idx].offset - register_index;
1947 }
1948
1949 return id_idx;
1950}

Referenced by shader_dst_param_io_normalise(), and shader_src_param_io_normalise().

◆ shader_register_normalise_flat_constants()

static void shader_register_normalise_flat_constants ( struct vkd3d_shader_src_param *  param,
const struct flat_constants_normaliser *  normaliser 
)
static

Definition at line 2335 of file ir.c.

2337{
2340 size_t i, j;
2341
2343 return;
2344
2345 for (i = 0; i < normaliser->def_count; ++i)
2346 {
2347 if (normaliser->defs[i].set == set && normaliser->defs[i].index == index)
2348 {
2349 param->reg.type = VKD3DSPR_IMMCONST;
2350 param->reg.idx_count = 0;
2351 param->reg.dimension = VSIR_DIMENSION_VEC4;
2352 for (j = 0; j < 4; ++j)
2353 param->reg.u.immconst_u32[j] = normaliser->defs[i].value[j];
2354 return;
2355 }
2356 }
2357
2358 param->reg.type = VKD3DSPR_CONSTBUFFER;
2359 param->reg.idx[0].offset = set; /* register ID */
2360 param->reg.idx[1].offset = set; /* register index */
2361 param->reg.idx[2].offset = index; /* buffer index */
2362 param->reg.idx_count = 3;
2363}
static bool get_flat_constant_register_type(const struct vkd3d_shader_register *reg, enum vkd3d_shader_d3dbc_constant_register *set, uint32_t *index)
Definition: ir.c:2295
struct flat_constant_def * defs
Definition: ir.c:2291
@ VKD3DSPR_CONSTBUFFER

Referenced by vsir_program_normalise_flat_constants().

◆ shader_signature_find_element_for_reg()

static bool shader_signature_find_element_for_reg ( const struct shader_signature *  signature,
unsigned int  reg_idx,
unsigned int  write_mask,
unsigned int *  element_idx 
)
static

Definition at line 1553 of file ir.c.

1555{
1556 const struct signature_element *e;
1557 unsigned int i;
1558
1559 for (i = 0; i < signature->element_count; ++i)
1560 {
1561 e = &signature->elements[i];
1562 if (e->register_index <= reg_idx && e->register_count > reg_idx - e->register_index
1563 && (e->mask & write_mask) == write_mask)
1564 {
1565 *element_idx = i;
1566 return true;
1567 }
1568 }
1569
1570 return false;
1571}

Referenced by shader_dst_param_io_normalise(), shader_src_param_io_normalise(), and vsir_signature_find_element_for_reg().

◆ shader_signature_map_patch_constant_index_ranges()

static void shader_signature_map_patch_constant_index_ranges ( struct shader_signature *  s,
uint8_t  range_map[][VKD3D_VEC4_SIZE] 
)
static

Definition at line 1698 of file ir.c.

1700{
1701 struct signature_element *e, *f;
1702 unsigned int i, j, register_count;
1703
1704 qsort(s->elements, s->element_count, sizeof(s->elements[0]), signature_element_mask_compare);
1705
1706 for (i = 0; i < s->element_count; i += register_count)
1707 {
1708 e = &s->elements[i];
1709 register_count = 1;
1710
1711 if (!e->sysval_semantic)
1712 continue;
1713
1714 for (j = i + 1; j < s->element_count; ++j, ++register_count)
1715 {
1716 f = &s->elements[j];
1717 if (f->register_index != e->register_index + register_count || !sysval_semantics_should_merge(e, f))
1718 break;
1719 }
1720 if (register_count < 2)
1721 continue;
1722
1723 range_map_set_register_range(range_map, e->register_index, register_count, e->mask, false);
1724 }
1725}
_ACRTIMP void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *))
GLfloat f
Definition: glext.h:7540
static bool sysval_semantics_should_merge(const struct signature_element *e, const struct signature_element *f)
Definition: ir.c:1682
static int signature_element_mask_compare(const void *a, const void *b)
Definition: ir.c:1674
#define f
Definition: ke_i.h:83

Referenced by shader_signature_merge().

◆ shader_signature_merge()

static bool shader_signature_merge ( struct shader_signature *  s,
uint8_t  range_map[][VKD3D_VEC4_SIZE],
bool  is_patch_constant 
)
static

Definition at line 1812 of file ir.c.

1814{
1815 unsigned int i, j, element_count, new_count, register_count;
1816 struct signature_element *elements;
1817 struct signature_element *e, *f;
1818 bool used;
1819
1820 element_count = s->element_count;
1821 if (!(elements = vkd3d_malloc(element_count * sizeof(*elements))))
1822 return false;
1823 memcpy(elements, s->elements, element_count * sizeof(*elements));
1824
1825 for (i = 0; i < element_count; ++i)
1826 elements[i].sort_index = i;
1827
1828 qsort(elements, element_count, sizeof(elements[0]), signature_element_register_compare);
1829
1830 for (i = 0, new_count = 0; i < element_count; i = j, elements[new_count++] = *e)
1831 {
1832 e = &elements[i];
1833 j = i + 1;
1834
1835 if (e->register_index == ~0u)
1836 continue;
1837
1838 /* Do not merge if the register index will be relative-addressed. */
1839 if (range_map_get_register_count(range_map, e->register_index, e->mask) > 1)
1840 continue;
1841
1842 used = e->used_mask;
1843
1844 for (; j < element_count; ++j)
1845 {
1846 f = &elements[j];
1847
1848 /* Merge different components of the same register unless sysvals are different,
1849 * or it will be relative-addressed. */
1850 if (f->register_index != e->register_index || f->sysval_semantic != e->sysval_semantic
1851 || range_map_get_register_count(range_map, f->register_index, f->mask) > 1)
1852 break;
1853
1854 TRACE("Merging %s, reg %u, mask %#x, sysval %#x with %s, mask %#x, sysval %#x.\n", e->semantic_name,
1855 e->register_index, e->mask, e->sysval_semantic, f->semantic_name, f->mask, f->sysval_semantic);
1856 VKD3D_ASSERT(!(e->mask & f->mask));
1857
1858 e->mask |= f->mask;
1859 e->used_mask |= f->used_mask;
1860 e->semantic_index = min(e->semantic_index, f->semantic_index);
1861
1862 /* The first element may have no interpolation mode if it is unused. Elements which
1863 * actually have different interpolation modes are assigned different registers. */
1864 if (f->used_mask && !used)
1865 {
1866 if (e->interpolation_mode && e->interpolation_mode != f->interpolation_mode)
1867 FIXME("Mismatching interpolation modes %u and %u.\n", e->interpolation_mode, f->interpolation_mode);
1868 else
1869 e->interpolation_mode = f->interpolation_mode;
1870 }
1871
1872 vkd3d_free((void *)f->semantic_name);
1873 }
1874 }
1875 element_count = new_count;
1876 vkd3d_free(s->elements);
1877 s->elements = elements;
1878 s->element_count = element_count;
1879
1880 if (is_patch_constant)
1882
1883 for (i = 0, new_count = 0; i < element_count; i += register_count, elements[new_count++] = *e)
1884 {
1885 e = &elements[i];
1886 register_count = 1;
1887
1888 if (e->register_index >= MAX_REG_OUTPUT)
1889 continue;
1890
1891 register_count = range_map_get_register_count(range_map, e->register_index, e->mask);
1894
1895 if (register_count > 1)
1896 {
1897 TRACE("Merging %s, base reg %u, count %u.\n", e->semantic_name, e->register_index, register_count);
1898 e->register_count = register_count;
1900
1901 for (j = 1; j < register_count; ++j)
1902 {
1903 f = &elements[i + j];
1904 vkd3d_free((void *)f->semantic_name);
1905 }
1906 }
1907 }
1908 element_count = new_count;
1909
1910 /* Restoring the original order is required for sensible trace output. */
1911 qsort(elements, element_count, sizeof(elements[0]), signature_element_index_compare);
1912
1913 s->element_count = element_count;
1914
1915 return true;
1916}
static int used
Definition: adh-main.c:39
static void shader_signature_map_patch_constant_index_ranges(struct shader_signature *s, uint8_t range_map[][VKD3D_VEC4_SIZE])
Definition: ir.c:1698
static unsigned int signature_element_range_expand_mask(struct signature_element *e, unsigned int register_count, uint8_t range_map[][VKD3D_VEC4_SIZE])
Definition: ir.c:1767
static unsigned int range_map_get_register_count(uint8_t range_map[][VKD3D_VEC4_SIZE], unsigned int register_idx, uint32_t write_mask)
Definition: ir.c:1584
static int signature_element_index_compare(const void *a, const void *b)
Definition: ir.c:1760
static int signature_element_register_compare(const void *a, const void *b)
Definition: ir.c:1727
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static ULONG ** element_count
Definition: exception.c:124
#define min(a, b)
Definition: monoChain.cc:55
#define TRACE(s)
Definition: solgame.cpp:4
static void * vkd3d_malloc(size_t size)
Definition: vkd3d_memory.h:28
#define MAX_REG_OUTPUT

Referenced by vsir_program_normalise_io_registers().

◆ shader_src_param_io_normalise()

static void shader_src_param_io_normalise ( struct vkd3d_shader_src_param *  src_param,
struct io_normaliser *  normaliser 
)
static

Definition at line 2089 of file ir.c.

2091{
2092 unsigned int i, id_idx, reg_idx, write_mask, element_idx, component_idx;
2093 struct vkd3d_shader_register *reg = &src_param->reg;
2094 const struct shader_signature *signature;
2095 const struct signature_element *e;
2096
2097 /* Input/output registers from one phase can be used as inputs in
2098 * subsequent phases. Specifically:
2099 *
2100 * - Control phase inputs are available as "vicp" in fork and join
2101 * phases.
2102 * - Control phase outputs are available as "vocp" in fork and join
2103 * phases.
2104 * - Fork phase patch constants are available as "vpc" in join
2105 * phases.
2106 *
2107 * We handle "vicp" here by converting INCONTROLPOINT src registers to
2108 * type INPUT so they match the control phase declarations. We handle
2109 * "vocp" by converting OUTCONTROLPOINT registers to type OUTPUT.
2110 * Merging fork and join phases handles "vpc". */
2111
2112 switch (reg->type)
2113 {
2115 reg_idx = reg->idx[reg->idx_count - 1].offset;
2116 signature = normaliser->patch_constant_signature;
2117 break;
2118
2120 reg->type = VKD3DSPR_INPUT;
2121 /* fall through */
2122 case VKD3DSPR_INPUT:
2123 if (normaliser->major < 3 && normaliser->shader_type == VKD3D_SHADER_TYPE_PIXEL)
2124 reg_idx = SM1_COLOR_REGISTER_OFFSET + reg->idx[0].offset;
2125 else
2126 reg_idx = reg->idx[reg->idx_count - 1].offset;
2127 signature = normaliser->input_signature;
2128 break;
2129
2131 reg->type = VKD3DSPR_OUTPUT;
2132 /* fall through */
2133 case VKD3DSPR_OUTPUT:
2134 reg_idx = reg->idx[reg->idx_count - 1].offset;
2135 signature = normaliser->output_signature;
2136 break;
2137
2138 case VKD3DSPR_TEXTURE:
2139 if (normaliser->shader_type != VKD3D_SHADER_TYPE_PIXEL)
2140 return;
2141 reg->type = VKD3DSPR_INPUT;
2142 reg_idx = reg->idx[0].offset;
2143 signature = normaliser->input_signature;
2144 break;
2145
2146 default:
2147 return;
2148 }
2149
2150 id_idx = reg->idx_count - 1;
2151 write_mask = VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(src_param->swizzle, 0);
2152 if (!shader_signature_find_element_for_reg(signature, reg_idx, write_mask, &element_idx))
2154
2155 e = &signature->elements[element_idx];
2156 if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
2157 id_idx = shader_register_normalise_arrayed_addressing(reg, id_idx, e->register_index);
2158 reg->idx[id_idx].offset = element_idx;
2159 reg->idx_count = id_idx + 1;
2160
2161 if ((component_idx = vsir_write_mask_get_component_idx(e->mask)))
2162 {
2163 for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
2164 if (vsir_swizzle_get_component(src_param->swizzle, i))
2165 src_param->swizzle -= component_idx << VKD3D_SHADER_SWIZZLE_SHIFT(i);
2166 }
2167}
uint8_t major
Definition: ir.c:1521
@ VKD3D_SHADER_TYPE_PIXEL
@ VKD3DSPR_TEXTURE

Referenced by shader_instruction_normalise_io_params().

◆ signature_element_index_compare()

static int signature_element_index_compare ( const void *  a,
const void *  b 
)
static

Definition at line 1760 of file ir.c.

1761{
1762 const struct signature_element *e = a, *f = b;
1763
1764 return vkd3d_u32_compare(e->sort_index, f->sort_index);
1765}
#define a
Definition: ke_i.h:78

Referenced by shader_signature_merge().

◆ signature_element_mask_compare()

static int signature_element_mask_compare ( const void *  a,
const void *  b 
)
static

Definition at line 1674 of file ir.c.

1675{
1676 const struct signature_element *e = a, *f = b;
1677 int ret;
1678
1679 return (ret = vkd3d_u32_compare(e->mask, f->mask)) ? ret : vkd3d_u32_compare(e->register_index, f->register_index);
1680}

Referenced by shader_signature_map_patch_constant_index_ranges().

◆ signature_element_range_expand_mask()

static unsigned int signature_element_range_expand_mask ( struct signature_element *  e,
unsigned int  register_count,
uint8_t  range_map[][VKD3D_VEC4_SIZE] 
)
static

Definition at line 1767 of file ir.c.

1769{
1770 unsigned int i, j, component_idx, component_count, merged_write_mask = e->mask;
1771
1772 /* dcl_indexrange instructions can declare a subset of the full mask, and the masks of
1773 * the elements within the range may differ. TPF's handling of arrayed inputs with
1774 * dcl_indexrange is really just a hack. Here we create a mask which covers all element
1775 * masks, and check for collisions with other ranges. */
1776
1777 for (i = 1; i < register_count; ++i)
1778 merged_write_mask |= e[i].mask;
1779
1780 if (merged_write_mask == e->mask)
1781 return merged_write_mask;
1782
1783 /* Reaching this point is very rare to begin with, and collisions are even rarer or
1784 * impossible. If the latter shows up, the fallback in shader_signature_find_element_for_reg()
1785 * may be sufficient. */
1786
1787 component_idx = vsir_write_mask_get_component_idx(e->mask);
1789
1790 for (i = e->register_index; i < e->register_index + register_count; ++i)
1791 {
1792 for (j = 0; j < component_idx; ++j)
1793 if (range_map[i][j])
1794 break;
1795 for (j = component_idx + component_count; j < VKD3D_VEC4_SIZE; ++j)
1796 if (range_map[i][j])
1797 break;
1798 }
1799
1800 if (i == register_count)
1801 {
1802 WARN("Expanding mask %#x to %#x for %s, base reg %u, count %u.\n", e->mask, merged_write_mask,
1803 e->semantic_name, e->register_index, register_count);
1804 return merged_write_mask;
1805 }
1806
1807 WARN("Cannot expand mask %#x to %#x for %s, base reg %u, count %u.\n", e->mask, merged_write_mask,
1808 e->semantic_name, e->register_index, register_count);
1809 return e->mask;
1810}

Referenced by shader_signature_merge().

◆ signature_element_register_compare()

static int signature_element_register_compare ( const void *  a,
const void *  b 
)
static

Definition at line 1727 of file ir.c.

1728{
1729 const struct signature_element *e = a, *f = b;
1730 int ret;
1731
1732 if ((ret = vkd3d_u32_compare(e->register_index, f->register_index)))
1733 return ret;
1734
1735 /* System values like SV_RenderTargetArrayIndex and SV_ViewPortArrayIndex
1736 * can get packed into the same I/O register as non-system values, but
1737 * only at the end. E.g.:
1738 *
1739 * vs_4_0
1740 * ...
1741 * .output
1742 * ...
1743 * .param B.x, o1.x, uint
1744 * .param C.y, o1.y, uint
1745 * .param SV_RenderTargetArrayIndex.z, o1.z, uint, RTINDEX
1746 * .text
1747 * ...
1748 * mov o1.xy, v1.xyxx
1749 * mov o1.z, v1.z
1750 * ret
1751 *
1752 * Because I/O normalisation doesn't split writes like the mov to o1.xy
1753 * above, we want to make sure that o1.x and o1.y continue to be packed
1754 * into a single register after I/O normalisation, so we order system
1755 * values after non-system values here, allowing the non-system values to
1756 * get merged into a single register. */
1757 return vkd3d_u32_compare(f->sysval_semantic, e->sysval_semantic);
1758}

Referenced by shader_signature_merge().

◆ src_param_init_const_uint()

static void src_param_init_const_uint ( struct vkd3d_shader_src_param *  src,
uint32_t  value 
)
static

◆ src_param_init_parameter()

static void src_param_init_parameter ( struct vkd3d_shader_src_param *  src,
uint32_t  idx,
enum vkd3d_data_type  type 
)
static

◆ src_param_init_ssa_bool()

static void src_param_init_ssa_bool ( struct vkd3d_shader_src_param *  src,
unsigned int  idx 
)
static

Definition at line 234 of file ir.c.

235{
237 src->reg.idx[0].offset = idx;
238}

Referenced by insert_alpha_test_before_ret(), and vsir_program_lower_switch_to_selection_ladder().

◆ src_param_init_ssa_float()

static void src_param_init_ssa_float ( struct vkd3d_shader_src_param *  src,
unsigned int  idx 
)
static

Definition at line 240 of file ir.c.

241{
243 src->reg.idx[0].offset = idx;
244}

Referenced by vsir_program_insert_point_size_clamp().

◆ src_param_init_temp_bool()

static void src_param_init_temp_bool ( struct vkd3d_shader_src_param *  src,
unsigned int  idx 
)
static

Definition at line 246 of file ir.c.

247{
249 src->reg.idx[0].offset = idx;
250}

Referenced by vsir_cfg_structure_list_emit_loop().

◆ src_param_init_temp_float()

static void src_param_init_temp_float ( struct vkd3d_shader_src_param *  src,
unsigned int  idx 
)
static

Definition at line 252 of file ir.c.

253{
255 src->reg.idx[0].offset = idx;
256}

Referenced by insert_alpha_test_before_ret(), and insert_clip_planes_before_ret().

◆ src_param_init_temp_float4()

static void src_param_init_temp_float4 ( struct vkd3d_shader_src_param *  src,
unsigned int  idx 
)
static

Definition at line 258 of file ir.c.

259{
261 src->reg.dimension = VSIR_DIMENSION_VEC4;
262 src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
263 src->reg.idx[0].offset = idx;
264}

Referenced by insert_clip_planes_before_ret().

◆ src_param_init_temp_uint()

static void src_param_init_temp_uint ( struct vkd3d_shader_src_param *  src,
unsigned int  idx 
)
static

Definition at line 266 of file ir.c.

267{
269 src->reg.idx[0].offset = idx;
270}

Referenced by insert_alpha_test_before_ret(), and vsir_cfg_structure_list_emit_loop().

◆ ssas_to_temps_alloc_init()

static bool ssas_to_temps_alloc_init ( struct ssas_to_temps_alloc *  alloc,
unsigned int  ssa_count,
unsigned int  temp_count 
)
static

Definition at line 3343 of file ir.c.

3344{
3345 size_t i = ssa_count * sizeof(*alloc->table);
3346
3347 if (!(alloc->table = vkd3d_malloc(i)))
3348 {
3349 ERR("Failed to allocate SSA table.\n");
3350 return false;
3351 }
3352 memset(alloc->table, 0xff, i);
3353
3354 alloc->next_temp_idx = temp_count;
3355 return true;
3356}

Referenced by vsir_cfg_materialize_undominated_ssas_to_temps(), and vsir_program_materialise_phi_ssas_to_temps().

◆ ssas_to_temps_block_info_cleanup()

static void ssas_to_temps_block_info_cleanup ( struct ssas_to_temps_block_info *  block_info,
size_t  count 
)
static

Definition at line 3387 of file ir.c.

3389{
3390 size_t i;
3391
3392 for (i = 0; i < count; ++i)
3393 vkd3d_free(block_info[i].incomings);
3394
3395 vkd3d_free(block_info);
3396}

Referenced by vsir_program_materialise_phi_ssas_to_temps().

◆ sysval_semantics_should_merge()

static bool sysval_semantics_should_merge ( const struct signature_element *  e,
const struct signature_element *  f 
)
static

Definition at line 1682 of file ir.c.

1683{
1684 if (e->sysval_semantic < VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE
1685 || e->sysval_semantic > VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN)
1686 return false;
1687
1688 return e->sysval_semantic == f->sysval_semantic
1689 /* Line detail and density must be merged together to match the SPIR-V array.
1690 * This deletes one of the two sysvals, but these are not used. */
1691 || (e->sysval_semantic == VKD3D_SHADER_SV_TESS_FACTOR_LINEDET
1692 && f->sysval_semantic == VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN)
1693 || (e->sysval_semantic == VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN
1694 && f->sysval_semantic == VKD3D_SHADER_SV_TESS_FACTOR_LINEDET);
1695}
@ VKD3D_SHADER_SV_TESS_FACTOR_LINEDET
@ VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE
@ VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN

Referenced by shader_signature_map_patch_constant_index_ranges().

◆ target_allows_subset_masks()

static bool target_allows_subset_masks ( const struct vkd3d_shader_compile_info *  info)
static

Definition at line 939 of file ir.c.

940{
941 const struct vkd3d_shader_spirv_target_info *spirv_info;
943
944 switch (info->target_type)
945 {
947 spirv_info = vkd3d_find_struct(info->next, SPIRV_TARGET_INFO);
949
950 switch (environment)
951 {
953 return true;
954
957 /* FIXME: Allow KHR_maintenance4. */
958 return false;
959
960 default:
961 FIXME("Unrecognized environment %#x.\n", environment);
962 return false;
963 }
964
965 default:
966 return true;
967 }
968}
enum vkd3d_shader_spirv_environment environment
Definition: spirv.c:4841
enum vkd3d_shader_spirv_environment environment
@ VKD3D_SHADER_TARGET_SPIRV_BINARY
vkd3d_shader_spirv_environment
@ VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0
@ VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5
@ VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_1

Referenced by vsir_program_remap_output_signature().

◆ use_flat_interpolation()

static bool use_flat_interpolation ( const struct vsir_program *  program,
struct vkd3d_shader_message_context *  message_context,
bool *  flat 
)
static

Definition at line 5849 of file ir.c.

5851{
5852 static const struct vkd3d_shader_location no_loc;
5853 const struct vkd3d_shader_parameter1 *parameter;
5854
5855 *flat = false;
5856
5858 return true;
5859
5861 {
5863 "Unsupported flat interpolation parameter type %#x.", parameter->type);
5864 return false;
5865 }
5867 {
5869 "Invalid flat interpolation parameter data type %#x.", parameter->data_type);
5870 return false;
5871 }
5872
5873 *flat = parameter->u.immediate_constant.u.u32;
5874 return true;
5875}
const struct vkd3d_shader_parameter1 * vsir_program_get_parameter(const struct vsir_program *program, enum vkd3d_shader_parameter_name name)
Definition: ir.c:120
enum vkd3d_shader_parameter_type type
Definition: vkd3d_shader.h:875
struct vkd3d_shader_parameter_immediate_constant1 immediate_constant
Definition: vkd3d_shader.h:887
enum vkd3d_shader_parameter_data_type data_type
Definition: vkd3d_shader.h:880
union vkd3d_shader_parameter1::@5986 u
@ VKD3D_SHADER_PARAMETER_NAME_FLAT_INTERPOLATION
Definition: vkd3d_shader.h:599
@ VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE

Referenced by vsir_program_apply_flat_interpolation().

◆ VKD3D_PRINTF_FUNC()

static void VKD3D_PRINTF_FUNC ( 3  ,
4   
)
static

Definition at line 2758 of file ir.c.

2760{
2762 size_t block_name_count;
2763 va_list args;
2764
2765 --block_id;
2766
2767 block_name_count = max(flattener->block_name_count, block_id + 1);
2768 if (!vkd3d_array_reserve((void **)&flattener->block_names, &flattener->block_name_capacity,
2769 block_name_count, sizeof(*flattener->block_names)))
2770 return;
2771 memset(&flattener->block_names[flattener->block_name_count], 0,
2772 (block_name_count - flattener->block_name_count) * sizeof(*flattener->block_names));
2773 flattener->block_name_count = block_name_count;
2774
2776 va_start(args, fmt);
2778 va_end(args);
2779
2780 flattener->block_names[block_id] = buffer.buffer;
2781}
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
GLuint buffer
Definition: glext.h:5915
#define args
Definition: format.c:66
Definition: match.c:390
Definition: dsound.c:943
#define max(a, b)
Definition: svc.c:63
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer)
int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args)

◆ vkd3d_shader_instruction_make_nop()

◆ vsir_block_cleanup()

static void vsir_block_cleanup ( struct vsir_block *  block)
static

Definition at line 3608 of file ir.c.

3609{
3610 if (block->label == 0)
3611 return;
3612 vsir_block_list_cleanup(&block->predecessors);
3613 vsir_block_list_cleanup(&block->successors);
3614 vkd3d_free(block->dominates);
3615}
static void vsir_block_list_cleanup(struct vsir_block_list *list)
Definition: ir.c:3537

Referenced by vsir_cfg_cleanup().

◆ vsir_block_dominates()

static bool vsir_block_dominates ( struct vsir_block *  b1,
struct vsir_block *  b2 
)
static

Definition at line 3866 of file ir.c.

3867{
3868 return bitmap_is_set(b1->dominates, b2->label - 1);
3869}
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:538
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:529
static bool bitmap_is_set(const uint32_t *map, unsigned int idx)
Definition: vkd3d_common.h:408

Referenced by register_map_undominated_use(), vsir_cfg_compute_dominators(), vsir_cfg_compute_loops(), vsir_cfg_generate_synthetic_loop_intervals(), and vsir_cfg_sort_nodes().

◆ vsir_block_init()

static enum vkd3d_result vsir_block_init ( struct vsir_block *  block,
unsigned int  label,
size_t  block_count 
)
static

Definition at line 3585 of file ir.c.

3586{
3587 size_t byte_count;
3588
3589 if (block_count > SIZE_MAX - (sizeof(*block->dominates) * CHAR_BIT - 1))
3591
3592 byte_count = VKD3D_BITMAP_SIZE(block_count) * sizeof(*block->dominates);
3593
3595 memset(block, 0, sizeof(*block));
3596 block->label = label;
3597 vsir_block_list_init(&block->predecessors);
3598 vsir_block_list_init(&block->successors);
3599
3600 if (!(block->dominates = vkd3d_malloc(byte_count)))
3602
3603 memset(block->dominates, 0xff, byte_count);
3604
3605 return VKD3D_OK;
3606}
#define CHAR_BIT
Definition: cabinet.h:45
#define SIZE_MAX
Definition: limits.h:49
static void vsir_block_list_init(struct vsir_block_list *list)
Definition: ir.c:3532
static const WCHAR label[]
Definition: itemdlg.c:1608
#define VKD3D_BITMAP_SIZE(x)
Definition: vkd3d_common.h:396

Referenced by vsir_cfg_init().

◆ vsir_block_list_add()

static enum vkd3d_result vsir_block_list_add ( struct vsir_block_list *  list,
struct vsir_block *  block 
)
static

Definition at line 3555 of file ir.c.

3556{
3557 size_t i;
3558
3559 for (i = 0; i < list->count; ++i)
3560 if (block == list->blocks[i])
3561 return VKD3D_FALSE;
3562
3564}
Definition: list.h:39
static enum vkd3d_result vsir_block_list_add_checked(struct vsir_block_list *list, struct vsir_block *block)
Definition: ir.c:3542
@ VKD3D_FALSE
Definition: vkd3d_types.h:45

Referenced by vsir_cfg_add_edge(), and vsir_cfg_scan_loop().

◆ vsir_block_list_add_checked()

static enum vkd3d_result vsir_block_list_add_checked ( struct vsir_block_list *  list,
struct vsir_block *  block 
)
static

Definition at line 3542 of file ir.c.

3543{
3544 if (!vkd3d_array_reserve((void **)&list->blocks, &list->capacity, list->count + 1, sizeof(*list->blocks)))
3545 {
3546 ERR("Cannot extend block list.\n");
3548 }
3549
3550 list->blocks[list->count++] = block;
3551
3552 return VKD3D_OK;
3553}

Referenced by vsir_block_list_add(), and vsir_cfg_sort_nodes().

◆ vsir_block_list_cleanup()

static void vsir_block_list_cleanup ( struct vsir_block_list *  list)
static

Definition at line 3537 of file ir.c.

3538{
3539 vkd3d_free(list->blocks);
3540}

Referenced by vsir_block_cleanup(), vsir_cfg_cleanup(), and vsir_cfg_sort_nodes().

◆ vsir_block_list_init()

static void vsir_block_list_init ( struct vsir_block_list *  list)
static

Definition at line 3532 of file ir.c.

3533{
3534 memset(list, 0, sizeof(*list));
3535}

Referenced by vsir_block_init(), vsir_cfg_compute_loops(), vsir_cfg_init(), and vsir_cfg_sort_nodes().

◆ vsir_block_list_remove_index()

static void vsir_block_list_remove_index ( struct vsir_block_list *  list,
size_t  idx 
)
static

Definition at line 3567 of file ir.c.

3568{
3569 --list->count;
3570 memmove(&list->blocks[idx], &list->blocks[idx + 1], (list->count - idx) * sizeof(*list->blocks));
3571}

Referenced by vsir_cfg_sort_nodes().

◆ vsir_block_list_search()

static bool vsir_block_list_search ( struct vsir_block_list *  list,
struct vsir_block *  block 
)
static

Definition at line 3630 of file ir.c.

3631{
3632 return !!bsearch(&block, list->blocks, list->count, sizeof(*list->blocks), block_compare);
3633}
static int block_compare(const void *ptr1, const void *ptr2)
Definition: ir.c:3617
#define bsearch

Referenced by vsir_cfg_sort_nodes().

◆ vsir_block_list_sort()

static void vsir_block_list_sort ( struct vsir_block_list *  list)
static

Definition at line 3625 of file ir.c.

3626{
3627 qsort(list->blocks, list->count, sizeof(*list->blocks), block_compare);
3628}

Referenced by vsir_cfg_compute_loops().

◆ vsir_cfg_add_edge()

static enum vkd3d_result vsir_cfg_add_edge ( struct vsir_cfg *  cfg,
struct vsir_block *  block,
struct vkd3d_shader_src_param *  successor_param 
)
static

Definition at line 3871 of file ir.c.

3873{
3874 unsigned int target = label_from_src_param(successor_param);
3875 struct vsir_block *successor = &cfg->blocks[target - 1];
3876 enum vkd3d_result ret;
3877
3878 VKD3D_ASSERT(successor->label != 0);
3879
3880 if ((ret = vsir_block_list_add(&block->successors, successor)) < 0)
3881 return ret;
3882
3883 if ((ret = vsir_block_list_add(&successor->predecessors, block)) < 0)
3884 return ret;
3885
3886 return VKD3D_OK;
3887}
static enum vkd3d_result vsir_block_list_add(struct vsir_block_list *list, struct vsir_block *block)
Definition: ir.c:3555
static unsigned int label_from_src_param(const struct vkd3d_shader_src_param *param)
Definition: ir.c:3160
Definition: tools.h:99
unsigned int label
Definition: ir.c:3575
struct vsir_block * blocks
Definition: ir.c:3774

Referenced by vsir_cfg_init().

◆ vsir_cfg_add_loop_interval()

static enum vkd3d_result vsir_cfg_add_loop_interval ( struct vsir_cfg *  cfg,
unsigned int  begin,
unsigned int  end,
bool  synthetic 
)
static

Definition at line 3847 of file ir.c.

3849{
3850 struct cfg_loop_interval *interval;
3851
3853 cfg->loop_interval_count + 1, sizeof(*cfg->loop_intervals)))
3855
3857
3858 interval->begin = begin;
3859 interval->end = end;
3860 interval->synthetic = synthetic;
3861 interval->target_count = 0;
3862
3863 return VKD3D_OK;
3864}
size_t loop_interval_count
Definition: ir.c:3817
size_t loop_interval_capacity
Definition: ir.c:3817
struct vsir_cfg::cfg_loop_interval * loop_intervals

Referenced by vsir_cfg_generate_synthetic_loop_intervals(), and vsir_cfg_sort_nodes().

◆ vsir_cfg_append_loop()

static enum vkd3d_result vsir_cfg_append_loop ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  new_list,
struct vsir_cfg_structure *  loop 
)
static

Definition at line 5075 of file ir.c.

5077{
5078 struct vsir_cfg_structure_list *loop_body = &loop->u.loop.body;
5079 unsigned int target, loop_idx = loop->u.loop.idx;
5080 struct vsir_cfg_structure *trailing_break;
5081 enum vkd3d_result ret;
5082
5083 trailing_break = vsir_cfg_get_trailing_break(loop_body);
5084
5085 /* If the loop's last instruction is not a break, we cannot remove
5086 * the loop itself. */
5087 if (!trailing_break)
5088 {
5089 if ((ret = vsir_cfg_structure_list_append_from_region(new_list, loop, 1)) < 0)
5090 return ret;
5091 memset(loop, 0, sizeof(*loop));
5092 return VKD3D_OK;
5093 }
5094
5095 target = trailing_break->u.jump.target;
5096 VKD3D_ASSERT(cfg->loop_intervals[target].target_count > 0);
5097
5098 /* If the loop is not targeted by any jump, we can remove it. The
5099 * trailing `break' then targets another loop, so we have to keep
5100 * it. */
5101 if (cfg->loop_intervals[loop_idx].target_count == 0)
5102 {
5104 &loop_body->structures[0], loop_body->count)) < 0)
5105 return ret;
5106 loop_body->count = 0;
5107 return VKD3D_OK;
5108 }
5109
5110 /* If the loop is targeted only by its own trailing `break'
5111 * instruction, then we can remove it together with the `break'
5112 * itself. */
5113 if (target == loop_idx && cfg->loop_intervals[loop_idx].target_count == 1)
5114 {
5115 --cfg->loop_intervals[loop_idx].target_count;
5117 &loop_body->structures[0], loop_body->count - 1)) < 0)
5118 return ret;
5119 loop_body->count = 0;
5120 return VKD3D_OK;
5121 }
5122
5123 if ((ret = vsir_cfg_structure_list_append_from_region(new_list, loop, 1)) < 0)
5124 return ret;
5125 memset(loop, 0, sizeof(*loop));
5126
5127 return VKD3D_OK;
5128}
static struct vsir_cfg_structure * vsir_cfg_get_trailing_break(struct vsir_cfg_structure_list *list)
Definition: ir.c:4919
static enum vkd3d_result vsir_cfg_structure_list_append_from_region(struct vsir_cfg_structure_list *list, struct vsir_cfg_structure *begin, size_t size)
Definition: ir.c:3722
struct vsir_cfg_structure * structures
Definition: ir.c:3637
union vsir_cfg_structure::@6006 u
struct vsir_cfg_structure::@6006::vsir_cfg_structure_loop loop
struct vsir_cfg_structure::@6006::vsir_cfg_structure_jump jump

Referenced by vsir_cfg_optimize_recurse().

◆ vsir_cfg_build_structured_program()

static enum vkd3d_result vsir_cfg_build_structured_program ( struct vsir_cfg *  cfg)
static

Definition at line 4740 of file ir.c.

4741{
4742 unsigned int i, stack_depth = 1, open_interval_idx = 0;
4744
4745 /* It's enough to allocate up to the maximum interval stacking
4746 * depth (plus one for the full program), but this is simpler. */
4747 if (!(stack = vkd3d_calloc(cfg->loop_interval_count + 1, sizeof(*stack))))
4748 goto fail;
4749 cfg->structured_program.end = cfg->order.count;
4750 stack[0] = &cfg->structured_program;
4751
4752 for (i = 0; i < cfg->order.count; ++i)
4753 {
4754 struct vsir_block *block = cfg->order.blocks[i];
4755 struct vsir_cfg_structure *structure;
4756
4757 VKD3D_ASSERT(stack_depth > 0);
4758
4759 /* Open loop intervals. */
4760 while (open_interval_idx < cfg->loop_interval_count)
4761 {
4762 struct cfg_loop_interval *interval = &cfg->loop_intervals[open_interval_idx];
4763
4764 if (interval->begin != i)
4765 break;
4766
4767 if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_LOOP)))
4768 goto fail;
4769 structure->u.loop.idx = open_interval_idx++;
4770
4771 structure->u.loop.body.end = interval->end;
4772 stack[stack_depth++] = &structure->u.loop.body;
4773 }
4774
4775 /* Execute the block. */
4776 if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_BLOCK)))
4777 goto fail;
4778 structure->u.block = block;
4779
4780 /* Generate between zero and two jump instructions. */
4781 switch (block->end->opcode)
4782 {
4783 case VKD3DSIH_BRANCH:
4784 {
4785 struct vsir_cfg_edge_action action_true, action_false;
4786 bool invert_condition = false;
4787
4788 if (vsir_register_is_label(&block->end->src[0].reg))
4789 {
4790 unsigned int target = label_from_src_param(&block->end->src[0]);
4791 struct vsir_block *successor = &cfg->blocks[target - 1];
4792
4793 vsir_cfg_compute_edge_action(cfg, block, successor, &action_true);
4794 action_false = action_true;
4795 }
4796 else
4797 {
4798 unsigned int target = label_from_src_param(&block->end->src[1]);
4799 struct vsir_block *successor = &cfg->blocks[target - 1];
4800
4801 vsir_cfg_compute_edge_action(cfg, block, successor, &action_true);
4802
4803 target = label_from_src_param(&block->end->src[2]);
4804 successor = &cfg->blocks[target - 1];
4805
4806 vsir_cfg_compute_edge_action(cfg, block, successor, &action_false);
4807 }
4808
4809 /* This will happen if the branch is unconditional,
4810 * but also if it's conditional with the same target
4811 * in both branches, which can happen in some corner
4812 * cases, e.g. when converting switch instructions to
4813 * selection ladders. */
4814 if (action_true.successor == action_false.successor)
4815 {
4816 VKD3D_ASSERT(action_true.jump_type == action_false.jump_type);
4817 }
4818 else
4819 {
4820 /* At most one branch can just fall through to the
4821 * next block, in which case we make sure it's the
4822 * false branch. */
4823 if (action_true.jump_type == JUMP_NONE)
4824 {
4825 invert_condition = true;
4826 }
4827 else if (stack_depth >= 2)
4828 {
4829 struct vsir_cfg_structure_list *inner_loop_frame = stack[stack_depth - 2];
4830 struct vsir_cfg_structure *inner_loop = &inner_loop_frame->structures[inner_loop_frame->count - 1];
4831
4832 VKD3D_ASSERT(inner_loop->type == STRUCTURE_TYPE_LOOP);
4833
4834 /* Otherwise, if one of the branches is
4835 * continue-ing the inner loop we're inside,
4836 * make sure it's the false branch (because it
4837 * will be optimized out later). */
4838 if (action_true.jump_type == JUMP_CONTINUE && action_true.target == inner_loop->u.loop.idx)
4839 invert_condition = true;
4840 }
4841
4842 if (invert_condition)
4843 {
4844 struct vsir_cfg_edge_action tmp = action_true;
4845 action_true = action_false;
4846 action_false = tmp;
4847 }
4848
4849 VKD3D_ASSERT(action_true.jump_type != JUMP_NONE);
4850
4851 if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP)))
4852 goto fail;
4853 structure->u.jump.type = action_true.jump_type;
4854 structure->u.jump.target = action_true.target;
4855 structure->u.jump.condition = &block->end->src[0];
4856 structure->u.jump.invert_condition = invert_condition;
4857 }
4858
4859 if (action_false.jump_type != JUMP_NONE)
4860 {
4861 if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP)))
4862 goto fail;
4863 structure->u.jump.type = action_false.jump_type;
4864 structure->u.jump.target = action_false.target;
4865 }
4866 break;
4867 }
4868
4869 case VKD3DSIH_RET:
4870 if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP)))
4871 goto fail;
4872 structure->u.jump.type = JUMP_RET;
4873 break;
4874
4875 default:
4877 }
4878
4879 /* Close loop intervals. */
4880 while (stack_depth > 0)
4881 {
4882 if (stack[stack_depth - 1]->end != i + 1)
4883 break;
4884
4885 --stack_depth;
4886 }
4887 }
4888
4889 VKD3D_ASSERT(stack_depth == 0);
4890 VKD3D_ASSERT(open_interval_idx == cfg->loop_interval_count);
4891
4892 if (TRACE_ON())
4894
4896
4897 return VKD3D_OK;
4898
4899fail:
4901
4903}
#define TRACE_ON(x)
Definition: compat.h:75
static void vsir_cfg_dump_structured_program(struct vsir_cfg *cfg)
Definition: ir.c:4009
static void vsir_cfg_compute_edge_action(struct vsir_cfg *cfg, struct vsir_block *block, struct vsir_block *successor, struct vsir_cfg_edge_action *action)
Definition: ir.c:4683
static struct vsir_cfg_structure * vsir_cfg_structure_list_append(struct vsir_cfg_structure_list *list, enum vsir_cfg_structure_type type)
Definition: ir.c:3706
Definition: format.c:80
struct vsir_block * block
Definition: ir.c:3660
@ STRUCTURE_TYPE_LOOP
Definition: ir.c:3649
bool invert_condition
Definition: ir.c:3673
enum vsir_cfg_structure::vsir_cfg_structure_type type
struct vsir_cfg_structure_list structured_program
Definition: ir.c:3819
struct vsir_block_list order
Definition: ir.c:3783
static bool vsir_register_is_label(const struct vkd3d_shader_register *reg)

Referenced by vsir_program_structurize_function().

◆ vsir_cfg_cleanup()

static void vsir_cfg_cleanup ( struct vsir_cfg *  cfg)
static

Definition at line 3824 of file ir.c.

3825{
3826 size_t i;
3827
3828 for (i = 0; i < cfg->block_count; ++i)
3829 vsir_block_cleanup(&cfg->blocks[i]);
3830
3831 for (i = 0; i < cfg->loops_count; ++i)
3833
3835
3837
3838 vkd3d_free(cfg->blocks);
3839 vkd3d_free(cfg->loops);
3842
3843 if (TRACE_ON())
3845}
static void vsir_cfg_structure_list_cleanup(struct vsir_cfg_structure_list *list)
Definition: ir.c:3697
static void vsir_block_cleanup(struct vsir_block *block)
Definition: ir.c:3608
size_t loops_count
Definition: ir.c:3780
struct vkd3d_string_buffer debug_buffer
Definition: ir.c:3777
struct vsir_block_list * loops
Definition: ir.c:3779
size_t block_count
Definition: ir.c:3776
size_t * loops_by_header
Definition: ir.c:3781
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer)

Referenced by vsir_cfg_init(), vsir_program_materialize_undominated_ssas_to_temps_in_function(), and vsir_program_structurize_function().

◆ vsir_cfg_compute_dominators()

static void vsir_cfg_compute_dominators ( struct vsir_cfg *  cfg)
static

Definition at line 4162 of file ir.c.

4163{
4164 size_t i, j;
4165
4166 for (i = 0; i < cfg->block_count; ++i)
4167 {
4168 struct vsir_block *block = &cfg->blocks[i];
4169
4170 if (block->label == 0)
4171 continue;
4172
4174
4175 if (TRACE_ON())
4176 {
4177 vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block %u dominates:", block->label);
4178 for (j = 0; j < cfg->block_count; j++)
4179 {
4180 struct vsir_block *block2 = &cfg->blocks[j];
4181
4182 if (block2->label == 0 || !vsir_block_dominates(block, block2))
4183 continue;
4184
4185 if (cfg->debug_buffer.content_size > 512)
4186 {
4187 TRACE("%s...\n", cfg->debug_buffer.buffer);
4189 vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block %u dominates: ...", block->label);
4190 }
4191 vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label);
4192 }
4193 TRACE("%s\n", cfg->debug_buffer.buffer);
4195 }
4196 }
4197}
static void vsir_cfg_compute_dominators_recurse(struct vsir_block *current, struct vsir_block *reference)
Definition: ir.c:4144
struct vsir_block * entry
Definition: ir.c:3775
void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer)
int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format,...)

Referenced by vsir_program_materialize_undominated_ssas_to_temps_in_function(), and vsir_program_structurize_function().

◆ vsir_cfg_compute_dominators_recurse()

static void vsir_cfg_compute_dominators_recurse ( struct vsir_block *  current,
struct vsir_block *  reference 
)
static

Definition at line 4144 of file ir.c.

4145{
4146 size_t i;
4147
4148 VKD3D_ASSERT(current->label != 0);
4149
4150 if (current == reference)
4151 return;
4152
4153 if (!bitmap_is_set(reference->dominates, current->label - 1))
4154 return;
4155
4156 bitmap_clear(reference->dominates, current->label - 1);
4157
4158 for (i = 0; i < current->successors.count; ++i)
4160}
GLint reference
Definition: glext.h:11729
struct task_struct * current
Definition: linux.c:32
static bool bitmap_clear(uint32_t *map, unsigned int idx)
Definition: vkd3d_common.h:398

Referenced by vsir_cfg_compute_dominators(), and vsir_cfg_compute_dominators_recurse().

◆ vsir_cfg_compute_edge_action()

static void vsir_cfg_compute_edge_action ( struct vsir_cfg *  cfg,
struct vsir_block *  block,
struct vsir_block *  successor,
struct vsir_cfg_edge_action *  action 
)
static

Definition at line 4683 of file ir.c.

4685{
4686 unsigned int i;
4687
4688 action->target = UINT_MAX;
4689 action->successor = successor;
4690
4691 if (successor->order_pos <= block->order_pos)
4692 {
4693 /* The successor is before the current block, so we have to
4694 * use `continue'. The target loop is the innermost that
4695 * contains the current block and has the successor as
4696 * `continue' target. */
4697 for (i = 0; i < cfg->loop_interval_count; ++i)
4698 {
4699 struct cfg_loop_interval *interval = &cfg->loop_intervals[i];
4700
4701 if (interval->begin == successor->order_pos && block->order_pos < interval->end)
4702 action->target = i;
4703
4704 if (interval->begin > successor->order_pos)
4705 break;
4706 }
4707
4708 VKD3D_ASSERT(action->target != UINT_MAX);
4709 action->jump_type = JUMP_CONTINUE;
4710 }
4711 else
4712 {
4713 /* The successor is after the current block, so we have to use
4714 * `break', or possibly just jump to the following block. The
4715 * target loop is the outermost that contains the current
4716 * block and has the successor as `break' target. */
4717 for (i = 0; i < cfg->loop_interval_count; ++i)
4718 {
4719 struct cfg_loop_interval *interval = &cfg->loop_intervals[i];
4720
4721 if (interval->begin <= block->order_pos && interval->end == successor->order_pos)
4722 {
4723 action->target = i;
4724 break;
4725 }
4726 }
4727
4728 if (action->target == UINT_MAX)
4729 {
4730 VKD3D_ASSERT(successor->order_pos == block->order_pos + 1);
4731 action->jump_type = JUMP_NONE;
4732 }
4733 else
4734 {
4735 action->jump_type = JUMP_BREAK;
4736 }
4737 }
4738}
action
Definition: namespace.c:707
unsigned int order_pos
Definition: ir.c:3575

Referenced by vsir_cfg_build_structured_program().

◆ vsir_cfg_compute_loops()

static enum vkd3d_result vsir_cfg_compute_loops ( struct vsir_cfg *  cfg)
static

Definition at line 4242 of file ir.c.

4243{
4244 size_t i, j, k;
4245
4246 if (!(cfg->loops_by_header = vkd3d_calloc(cfg->block_count, sizeof(*cfg->loops_by_header))))
4248 memset(cfg->loops_by_header, 0xff, cfg->block_count * sizeof(*cfg->loops_by_header));
4249
4250 for (i = 0; i < cfg->block_count; ++i)
4251 {
4252 struct vsir_block *block = &cfg->blocks[i];
4253
4254 if (block->label == 0)
4255 continue;
4256
4257 for (j = 0; j < block->successors.count; ++j)
4258 {
4259 struct vsir_block *header = block->successors.blocks[j];
4260 struct vsir_block_list *loop;
4261 enum vkd3d_result ret;
4262
4263 /* Is this a back edge? */
4265 continue;
4266
4267 if (!vkd3d_array_reserve((void **)&cfg->loops, &cfg->loops_capacity, cfg->loops_count + 1, sizeof(*cfg->loops)))
4269
4270 loop = &cfg->loops[cfg->loops_count];
4272
4273 if ((ret = vsir_cfg_scan_loop(loop, block, header)) < 0)
4274 return ret;
4275
4277
4278 if (TRACE_ON())
4279 {
4280 vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop:", block->label, header->label);
4281
4282 for (k = 0; k < loop->count; ++k)
4283 {
4284 if (cfg->debug_buffer.content_size > 512)
4285 {
4286 TRACE("%s...\n", cfg->debug_buffer.buffer);
4288 vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop: ...",
4289 block->label, header->label);
4290 }
4291 vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", loop->blocks[k]->label);
4292 }
4293
4294 TRACE("%s\n", cfg->debug_buffer.buffer);
4296 }
4297
4298 if (cfg->loops_by_header[header->label - 1] != SIZE_MAX)
4299 {
4300 FIXME("Block %u is header to more than one loop, this is not implemented.\n", header->label);
4302 "Block %u is header to more than one loop, this is not implemented.", header->label);
4304 }
4305
4306 cfg->loops_by_header[header->label - 1] = cfg->loops_count;
4307
4308 ++cfg->loops_count;
4309 }
4310 }
4311
4312 return VKD3D_OK;
4313}
static void vsir_block_list_sort(struct vsir_block_list *list)
Definition: ir.c:3625
static enum vkd3d_result vsir_cfg_scan_loop(struct vsir_block_list *loop, struct vsir_block *block, struct vsir_block *header)
Definition: ir.c:4221
struct vsir_block ** blocks
Definition: ir.c:3528
size_t count
Definition: ir.c:3529
struct vkd3d_shader_message_context * message_context
Definition: ir.c:3770
size_t loops_capacity
Definition: ir.c:3780

Referenced by vsir_program_structurize_function().

◆ vsir_cfg_count_targets()

static void vsir_cfg_count_targets ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list 
)
static

Definition at line 5197 of file ir.c.

5198{
5199 size_t i;
5200
5201 for (i = 0; i < list->count; ++i)
5202 {
5203 struct vsir_cfg_structure *structure = &list->structures[i];
5204
5205 switch (structure->type)
5206 {
5208 break;
5209
5211 vsir_cfg_count_targets(cfg, &structure->u.loop.body);
5212 break;
5213
5215 vsir_cfg_count_targets(cfg, &structure->u.selection.if_body);
5216 vsir_cfg_count_targets(cfg, &structure->u.selection.else_body);
5217 break;
5218
5220 if (structure->u.jump.type == JUMP_BREAK || structure->u.jump.type == JUMP_CONTINUE)
5221 ++cfg->loop_intervals[structure->u.jump.target].target_count;
5222 break;
5223 }
5224 }
5225}
static void vsir_cfg_count_targets(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
Definition: ir.c:5197
struct vsir_cfg_structure::@6006::vsir_cfg_structure_selection selection
@ STRUCTURE_TYPE_SELECTION
Definition: ir.c:3651
@ STRUCTURE_TYPE_BLOCK
Definition: ir.c:3647
@ STRUCTURE_TYPE_JUMP
Definition: ir.c:3656

Referenced by vsir_cfg_count_targets(), and vsir_cfg_optimize().

◆ vsir_cfg_dump_dot()

static void vsir_cfg_dump_dot ( struct vsir_cfg *  cfg)
static

Definition at line 3889 of file ir.c.

3890{
3891 size_t i, j;
3892
3893 TRACE("digraph cfg {\n");
3894
3895 for (i = 0; i < cfg->block_count; ++i)
3896 {
3897 struct vsir_block *block = &cfg->blocks[i];
3898 const char *shape;
3899
3900 if (block->label == 0)
3901 continue;
3902
3903 switch (block->end->opcode)
3904 {
3905 case VKD3DSIH_RET:
3906 shape = "trapezium";
3907 break;
3908
3909 case VKD3DSIH_BRANCH:
3910 shape = vsir_register_is_label(&block->end->src[0].reg) ? "ellipse" : "box";
3911 break;
3912
3913 default:
3915 }
3916
3917 TRACE(" n%u [label=\"%u\", shape=\"%s\"];\n", block->label, block->label, shape);
3918
3919 for (j = 0; j < block->successors.count; ++j)
3920 TRACE(" n%u -> n%u;\n", block->label, block->successors.blocks[j]->label);
3921 }
3922
3923 TRACE("}\n");
3924}

Referenced by vsir_cfg_init().

◆ vsir_cfg_dump_structured_program()

static void vsir_cfg_dump_structured_program ( struct vsir_cfg *  cfg)
static

Definition at line 4009 of file ir.c.

4010{
4011 unsigned int i;
4012
4013 for (i = 0; i < cfg->structured_program.count; ++i)
4014 vsir_cfg_structure_dump(cfg, &cfg->structured_program.structures[i]);
4015}
static void vsir_cfg_structure_dump(struct vsir_cfg *cfg, struct vsir_cfg_structure *structure)
Definition: ir.c:3928

Referenced by vsir_cfg_build_structured_program(), and vsir_cfg_optimize().

◆ vsir_cfg_emit_structured_program()

static enum vkd3d_result vsir_cfg_emit_structured_program ( struct vsir_cfg *  cfg)
static

Definition at line 5581 of file ir.c.

5582{
5584}
static enum vkd3d_result vsir_cfg_structure_list_emit(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, unsigned int loop_idx)
Definition: ir.c:5539

Referenced by vsir_program_structurize_function().

◆ vsir_cfg_generate_synthetic_loop_intervals()

static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals ( struct vsir_cfg *  cfg)
static

Definition at line 4553 of file ir.c.

4554{
4555 enum vkd3d_result ret;
4556 size_t i, j, k;
4557
4558 for (i = 0; i < cfg->block_count; ++i)
4559 {
4560 struct vsir_block *block = &cfg->blocks[i];
4561
4562 if (block->label == 0)
4563 continue;
4564
4565 for (j = 0; j < block->successors.count; ++j)
4566 {
4567 struct vsir_block *successor = block->successors.blocks[j];
4568 struct cfg_loop_interval *extend = NULL;
4569 unsigned int begin;
4570 enum
4571 {
4572 ACTION_DO_NOTHING,
4573 ACTION_CREATE_NEW,
4574 ACTION_EXTEND,
4575 } action = ACTION_CREATE_NEW;
4576
4577 /* We've already constructed loop intervals for the back
4578 * edges, there's nothing more to do. */
4579 if (vsir_block_dominates(successor, block))
4580 continue;
4581
4582 VKD3D_ASSERT(block->order_pos < successor->order_pos);
4583
4584 /* Jumping from a block to the following one is always
4585 * possible, so nothing to do. */
4586 if (block->order_pos + 1 == successor->order_pos)
4587 continue;
4588
4589 /* Let's look for a loop interval that already breaks at
4590 * `successor' and either contains or can be extended to
4591 * contain `block'. */
4592 for (k = 0; k < cfg->loop_interval_count; ++k)
4593 {
4594 struct cfg_loop_interval *interval = &cfg->loop_intervals[k];
4595
4596 if (interval->end != successor->order_pos)
4597 continue;
4598
4599 if (interval->begin <= block->order_pos)
4600 {
4601 action = ACTION_DO_NOTHING;
4602 break;
4603 }
4604
4605 if (interval->synthetic)
4606 {
4607 action = ACTION_EXTEND;
4608 extend = interval;
4609 break;
4610 }
4611 }
4612
4613 if (action == ACTION_DO_NOTHING)
4614 continue;
4615
4616 /* Ok, we have to decide where the new or replacing
4617 * interval has to begin. These are the rules: 1. it must
4618 * begin before `block'; 2. intervals must be properly
4619 * nested; 3. the new interval should begin as late as
4620 * possible, to limit control flow depth and extension. */
4621 begin = block->order_pos;
4622
4623 /* Our candidate interval is always [begin,
4624 * successor->order_pos), and we move `begin' backward
4625 * until the candidate interval contains all the intervals
4626 * whose endpoint lies in the candidate interval
4627 * itself. */
4628 for (k = 0; k < cfg->loop_interval_count; ++k)
4629 {
4630 struct cfg_loop_interval *interval = &cfg->loop_intervals[k];
4631
4632 if (begin < interval->end && interval->end < successor->order_pos)
4633 begin = min(begin, interval->begin);
4634 }
4635
4636 /* New we have to care about the intervals whose begin
4637 * point lies in the candidate interval. We cannot move
4638 * the candidate interval endpoint, because it is
4639 * important that the loop break target matches
4640 * `successor'. So we have to move that interval's begin
4641 * point to the begin point of the candidate interval,
4642 * i.e. `begin'. But what if the interval we should extend
4643 * backward is not synthetic? This cannot happen,
4644 * fortunately, because it would mean that there is a jump
4645 * entering a loop via a block which is not the loop
4646 * header, so the CFG would not be reducible. */
4647 for (k = 0; k < cfg->loop_interval_count; ++k)
4648 {
4649 struct cfg_loop_interval *interval = &cfg->loop_intervals[k];
4650
4651 if (interval->begin < successor->order_pos && successor->order_pos < interval->end)
4652 {
4653 if (interval->synthetic)
4654 interval->begin = min(begin, interval->begin);
4655 VKD3D_ASSERT(begin >= interval->begin);
4656 }
4657 }
4658
4659 if (action == ACTION_EXTEND)
4660 extend->begin = begin;
4661 else if ((ret = vsir_cfg_add_loop_interval(cfg, begin, successor->order_pos, true)) < 0)
4662 return ret;
4663 }
4664 }
4665
4667
4668 if (TRACE_ON())
4669 for (i = 0; i < cfg->loop_interval_count; ++i)
4670 TRACE("%s loop interval %u - %u\n", cfg->loop_intervals[i].synthetic ? "Synthetic" : "Natural",
4671 cfg->loop_intervals[i].begin, cfg->loop_intervals[i].end);
4672
4673 return VKD3D_OK;
4674}
static int compare_loop_intervals(const void *ptr1, const void *ptr2)
Definition: ir.c:4542
static enum vkd3d_result vsir_cfg_add_loop_interval(struct vsir_cfg *cfg, unsigned int begin, unsigned int end, bool synthetic)
Definition: ir.c:3847

Referenced by vsir_program_structurize_function().

◆ vsir_cfg_get_trailing_break()

static struct vsir_cfg_structure * vsir_cfg_get_trailing_break ( struct vsir_cfg_structure_list *  list)
static

Definition at line 4919 of file ir.c.

4920{
4921 struct vsir_cfg_structure *structure;
4922 size_t count = list->count;
4923
4924 if (count == 0)
4925 return NULL;
4926
4927 structure = &list->structures[count - 1];
4928
4929 if (structure->type != STRUCTURE_TYPE_JUMP || structure->u.jump.type != JUMP_BREAK
4930 || structure->u.jump.condition)
4931 return NULL;
4932
4933 return structure;
4934}

Referenced by vsir_cfg_append_loop(), vsir_cfg_move_breaks_out_of_selections(), and vsir_cfg_optimize_recurse().

◆ vsir_cfg_init()

static enum vkd3d_result vsir_cfg_init ( struct vsir_cfg *  cfg,
struct vsir_program *  program,
struct vkd3d_shader_message_context *  message_context,
struct vsir_cfg_emit_target *  target,
size_t *  pos 
)
static

Definition at line 4017 of file ir.c.

4020{
4021 struct vsir_block *current_block = NULL;
4022 enum vkd3d_result ret;
4023 size_t i;
4024
4025 memset(cfg, 0, sizeof(*cfg));
4026 cfg->message_context = message_context;
4027 cfg->program = program;
4028 cfg->block_count = program->block_count;
4029 cfg->target = target;
4030 cfg->function_begin = *pos;
4031
4033
4034 if (!(cfg->blocks = vkd3d_calloc(cfg->block_count, sizeof(*cfg->blocks))))
4036
4037 if (TRACE_ON())
4039
4040 for (i = *pos; i < program->instructions.count; ++i)
4041 {
4042 struct vkd3d_shader_instruction *instruction = &program->instructions.elements[i];
4043 bool finish = false;
4044
4045 switch (instruction->opcode)
4046 {
4047 case VKD3DSIH_PHI:
4050
4051 case VKD3DSIH_LABEL:
4052 {
4053 unsigned int label = label_from_src_param(&instruction->src[0]);
4054
4055 VKD3D_ASSERT(!current_block);
4056 VKD3D_ASSERT(label > 0);
4057 VKD3D_ASSERT(label <= cfg->block_count);
4058 current_block = &cfg->blocks[label - 1];
4059 VKD3D_ASSERT(current_block->label == 0);
4060 if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0)
4061 goto fail;
4062 current_block->begin = &program->instructions.elements[i + 1];
4063 if (!cfg->entry)
4064 cfg->entry = current_block;
4065 break;
4066 }
4067
4068 case VKD3DSIH_BRANCH:
4069 case VKD3DSIH_RET:
4070 VKD3D_ASSERT(current_block);
4071 current_block->end = instruction;
4072 current_block = NULL;
4073 break;
4074
4078 VKD3D_ASSERT(!current_block);
4079 finish = true;
4080 break;
4081
4082 default:
4083 break;
4084 }
4085
4086 if (finish)
4087 break;
4088 }
4089
4090 *pos = i;
4091 cfg->function_end = *pos;
4092
4093 for (i = 0; i < cfg->block_count; ++i)
4094 {
4095 struct vsir_block *block = &cfg->blocks[i];
4096
4097 if (block->label == 0)
4098 continue;
4099
4100 switch (block->end->opcode)
4101 {
4102 case VKD3DSIH_RET:
4103 break;
4104
4105 case VKD3DSIH_BRANCH:
4106 if (vsir_register_is_label(&block->end->src[0].reg))
4107 {
4108 if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[0])) < 0)
4109 goto fail;
4110 }
4111 else
4112 {
4113 if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[1])) < 0)
4114 goto fail;
4115
4116 if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[2])) < 0)
4117 goto fail;
4118 }
4119 break;
4120
4121 default:
4123 }
4124 }
4125
4126 if (TRACE_ON())
4127 vsir_cfg_dump_dot(cfg);
4128
4129 return VKD3D_OK;
4130
4131fail:
4132 vsir_cfg_cleanup(cfg);
4133
4134 return ret;
4135}
static void vsir_cfg_dump_dot(struct vsir_cfg *cfg)
Definition: ir.c:3889
static void vsir_cfg_cleanup(struct vsir_cfg *cfg)
Definition: ir.c:3824
static enum vkd3d_result vsir_cfg_add_edge(struct vsir_cfg *cfg, struct vsir_block *block, struct vkd3d_shader_src_param *successor_param)
Definition: ir.c:3871
static enum vkd3d_result vsir_block_init(struct vsir_block *block, unsigned int label, size_t block_count)
Definition: ir.c:3585
#define finish()
Definition: seh0024.c:15
struct vkd3d_shader_instruction * end
Definition: ir.c:3580
struct vkd3d_shader_instruction * begin
Definition: ir.c:3580
struct vsir_cfg_emit_target * target
Definition: ir.c:3821
struct vsir_program * program
Definition: ir.c:3771
size_t function_begin
Definition: ir.c:3772
size_t function_end
Definition: ir.c:3773
@ VKD3DSIH_PHI

Referenced by vsir_program_materialize_undominated_ssas_to_temps_in_function(), and vsir_program_structurize_function().

◆ vsir_cfg_mark_launchers()

static void vsir_cfg_mark_launchers ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list,
struct vsir_cfg_structure *  loop 
)
static

Definition at line 5277 of file ir.c.

5279{
5280 size_t i;
5281
5282 for (i = 0; i < list->count; ++i)
5283 {
5284 struct vsir_cfg_structure *structure = &list->structures[i];
5285
5286 switch (structure->type)
5287 {
5289 break;
5290
5292 vsir_cfg_mark_launchers(cfg, &structure->u.loop.body, structure);
5293 break;
5294
5296 vsir_cfg_mark_launchers(cfg, &structure->u.selection.if_body, loop);
5297 vsir_cfg_mark_launchers(cfg, &structure->u.selection.else_body, loop);
5298 break;
5299
5301 if (structure->u.jump.type != JUMP_BREAK && structure->u.jump.type != JUMP_CONTINUE)
5302 break;
5304 if (loop->u.loop.needs_trampoline)
5305 structure->u.jump.needs_launcher = true;
5306 break;
5307 }
5308 }
5309}
static void vsir_cfg_mark_launchers(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, struct vsir_cfg_structure *loop)
Definition: ir.c:5277

Referenced by vsir_cfg_mark_launchers(), and vsir_cfg_optimize().

◆ vsir_cfg_mark_trampolines()

static void vsir_cfg_mark_trampolines ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list,
struct vsir_cfg_structure *  loop 
)
static

Definition at line 5232 of file ir.c.

5234{
5235 size_t i;
5236
5237 for (i = 0; i < list->count; ++i)
5238 {
5239 struct vsir_cfg_structure *structure = &list->structures[i];
5240
5241 switch (structure->type)
5242 {
5244 break;
5245
5247 structure->u.loop.outer_loop = loop;
5248 vsir_cfg_mark_trampolines(cfg, &structure->u.loop.body, structure);
5249 break;
5250
5252 vsir_cfg_mark_trampolines(cfg, &structure->u.selection.if_body, loop);
5253 vsir_cfg_mark_trampolines(cfg, &structure->u.selection.else_body, loop);
5254 break;
5255
5257 {
5258 struct vsir_cfg_structure *l;
5259 if (structure->u.jump.type != JUMP_BREAK && structure->u.jump.type != JUMP_CONTINUE)
5260 break;
5261 for (l = loop; l && l->u.loop.idx != structure->u.jump.target; l = l->u.loop.outer_loop)
5262 {
5264 l->u.loop.needs_trampoline = true;
5265 }
5266 break;
5267 }
5268 }
5269 }
5270}
r l[0]
Definition: byte_order.h:168
static void vsir_cfg_mark_trampolines(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, struct vsir_cfg_structure *loop)
Definition: ir.c:5232

Referenced by vsir_cfg_mark_trampolines(), and vsir_cfg_optimize().

◆ vsir_cfg_materialize_undominated_ssas_to_temps()

static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps ( struct vsir_cfg *  cfg)
static

Definition at line 5710 of file ir.c.

5711{
5712 struct vsir_program *program = cfg->program;
5713 struct ssas_to_temps_alloc alloc = {0};
5714 struct vsir_block **origin_blocks;
5715 unsigned int j;
5716 size_t i;
5717
5718 if (!(origin_blocks = vkd3d_calloc(program->ssa_count, sizeof(*origin_blocks))))
5719 {
5720 ERR("Failed to allocate origin block array.\n");
5722 }
5723 if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count))
5724 {
5725 vkd3d_free(origin_blocks);
5727 }
5728
5729 for (i = 0; i < cfg->block_count; ++i)
5730 {
5731 struct vsir_block *block = &cfg->blocks[i];
5732 struct vkd3d_shader_instruction *ins;
5733
5734 if (block->label == 0)
5735 continue;
5736
5737 for (ins = block->begin; ins <= block->end; ++ins)
5738 {
5739 for (j = 0; j < ins->dst_count; ++j)
5740 {
5741 if (register_is_ssa(&ins->dst[j].reg))
5742 origin_blocks[ins->dst[j].reg.idx[0].offset] = block;
5743 }
5744 }
5745 }
5746
5747 for (i = 0; i < cfg->block_count; ++i)
5748 {
5749 struct vsir_block *block = &cfg->blocks[i];
5750 struct vkd3d_shader_instruction *ins;
5751
5752 if (block->label == 0)
5753 continue;
5754
5755 for (ins = block->begin; ins <= block->end; ++ins)
5756 {
5757 for (j = 0; j < ins->src_count; ++j)
5758 register_map_undominated_use(&ins->src[j].reg, &alloc, block, origin_blocks);
5759 }
5760 }
5761
5762 if (alloc.next_temp_idx == program->temp_count)
5763 goto done;
5764
5765 TRACE("Emitting temps for %u values with undominated usage.\n", alloc.next_temp_idx - program->temp_count);
5766
5767 for (i = cfg->function_begin; i < cfg->function_end; ++i)
5768 {
5769 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
5770
5771 for (j = 0; j < ins->dst_count; ++j)
5773
5774 for (j = 0; j < ins->src_count; ++j)
5776 }
5777
5778 program->temp_count = alloc.next_temp_idx;
5779done:
5780 vkd3d_free(origin_blocks);
5781 vkd3d_free(alloc.table);
5782
5783 return VKD3D_OK;
5784}
static bool ssas_to_temps_alloc_init(struct ssas_to_temps_alloc *alloc, unsigned int ssa_count, unsigned int temp_count)
Definition: ir.c:3343

Referenced by vsir_program_materialize_undominated_ssas_to_temps_in_function().

◆ vsir_cfg_move_breaks_out_of_selections()

static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list 
)
static

Definition at line 4947 of file ir.c.

4949{
4950 struct vsir_cfg_structure *selection, *if_break, *else_break, *new_break;
4951 unsigned int if_target, else_target, max_target;
4952 size_t pos = list->count - 1;
4953
4954 selection = &list->structures[pos];
4956
4957 if_break = vsir_cfg_get_trailing_break(&selection->u.selection.if_body);
4958 else_break = vsir_cfg_get_trailing_break(&selection->u.selection.else_body);
4959
4960 if (!if_break || !else_break)
4961 return VKD3D_OK;
4962
4963 if_target = if_break->u.jump.target;
4964 else_target = else_break->u.jump.target;
4965 max_target = max(if_target, else_target);
4966
4969 new_break->u.jump.type = JUMP_BREAK;
4970 new_break->u.jump.target = max_target;
4971 ++cfg->loop_intervals[max_target].target_count;
4972
4973 /* Pointer `selection' could have been invalidated by the append
4974 * operation. */
4975 selection = &list->structures[pos];
4977
4978 if (if_target == max_target)
4979 {
4980 --selection->u.selection.if_body.count;
4981 VKD3D_ASSERT(cfg->loop_intervals[if_target].target_count > 0);
4982 --cfg->loop_intervals[if_target].target_count;
4983 }
4984
4985 if (else_target == max_target)
4986 {
4987 --selection->u.selection.else_body.count;
4988 VKD3D_ASSERT(cfg->loop_intervals[else_target].target_count > 0);
4989 --cfg->loop_intervals[else_target].target_count;
4990 }
4991
4992 /* If a branch becomes empty, make it the else branch, so we save a block. */
4993 if (selection->u.selection.if_body.count == 0)
4994 {
4995 struct vsir_cfg_structure_list tmp;
4996
4997 selection->u.selection.invert_condition = !selection->u.selection.invert_condition;
4998 tmp = selection->u.selection.if_body;
4999 selection->u.selection.if_body = selection->u.selection.else_body;
5000 selection->u.selection.else_body = tmp;
5001 }
5002
5003 return VKD3D_OK;
5004}
static void else_break(short *before, short class)
Definition: breaking.c:71
int selection
Definition: ctm.c:92

Referenced by vsir_cfg_move_breaks_out_of_selections_recursively(), and vsir_cfg_synthesize_selections().

◆ vsir_cfg_move_breaks_out_of_selections_recursively()

static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections_recursively ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list 
)
static

Definition at line 5006 of file ir.c.

5008{
5010
5011 if (list->count == 0)
5012 return VKD3D_OK;
5013
5014 trailing = &list->structures[list->count - 1];
5015
5017 return VKD3D_OK;
5018
5021
5023}
static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections_recursively(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
Definition: ir.c:5006
static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
Definition: ir.c:4947

Referenced by vsir_cfg_move_breaks_out_of_selections_recursively(), and vsir_cfg_optimize_recurse().

◆ vsir_cfg_optimize()

static enum vkd3d_result vsir_cfg_optimize ( struct vsir_cfg *  cfg)
static

Definition at line 5311 of file ir.c.

5312{
5313 enum vkd3d_result ret;
5314
5316
5318
5319 /* Trampolines and launchers cannot be marked with the same pass,
5320 * because a jump might have to be marked as launcher even when it
5321 * targets its innermost loop, if other jumps in the same loop
5322 * need a trampoline anyway. So launchers can be discovered only
5323 * once all the trampolines are known. */
5326
5327 if (TRACE_ON())
5329
5330 return ret;
5331}
static enum vkd3d_result vsir_cfg_optimize_recurse(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
Definition: ir.c:5130

Referenced by vsir_program_structurize_function().

◆ vsir_cfg_optimize_recurse()

static enum vkd3d_result vsir_cfg_optimize_recurse ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list 
)
static

Definition at line 5130 of file ir.c.

5131{
5132 struct vsir_cfg_structure_list old_list = *list, *new_list = list;
5133 enum vkd3d_result ret;
5134 size_t i;
5135
5136 memset(new_list, 0, sizeof(*new_list));
5137
5138 for (i = 0; i < old_list.count; ++i)
5139 {
5140 struct vsir_cfg_structure *loop = &old_list.structures[i], *selection;
5141 struct vsir_cfg_structure_list *loop_body;
5142
5143 if (loop->type != STRUCTURE_TYPE_LOOP)
5144 {
5145 if ((ret = vsir_cfg_structure_list_append_from_region(new_list, loop, 1)) < 0)
5146 goto out;
5147 memset(loop, 0, sizeof(*loop));
5148 continue;
5149 }
5150
5151 loop_body = &loop->u.loop.body;
5152
5153 if (loop_body->count == 0)
5154 {
5155 if ((ret = vsir_cfg_structure_list_append_from_region(new_list, loop, 1)) < 0)
5156 goto out;
5157 memset(loop, 0, sizeof(*loop));
5158 continue;
5159 }
5160
5161 vsir_cfg_remove_trailing_continue(cfg, loop_body, loop->u.loop.idx);
5162
5163 if ((ret = vsir_cfg_optimize_recurse(cfg, loop_body)) < 0)
5164 goto out;
5165
5166 if ((ret = vsir_cfg_synthesize_selections(cfg, loop_body)) < 0)
5167 goto out;
5168
5169 if ((ret = vsir_cfg_append_loop(cfg, new_list, loop)) < 0)
5170 goto out;
5171
5172 /* If the last pushed instruction is a selection and one of the branches terminates with a
5173 * `break', start pushing to the other branch, in the hope of eventually push a `break'
5174 * there too and be able to remove a loop. */
5175 if (new_list->count == 0)
5176 continue;
5177
5178 selection = &new_list->structures[new_list->count - 1];
5179
5180 if (selection->type == STRUCTURE_TYPE_SELECTION)
5181 {
5182 if (vsir_cfg_get_trailing_break(&selection->u.selection.if_body))
5183 new_list = &selection->u.selection.else_body;
5184 else if (vsir_cfg_get_trailing_break(&selection->u.selection.else_body))
5185 new_list = &selection->u.selection.if_body;
5186 }
5187 }
5188
5190
5191out:
5193
5194 return ret;
5195}
static void vsir_cfg_remove_trailing_continue(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list, unsigned int target)
Definition: ir.c:4905
static enum vkd3d_result vsir_cfg_synthesize_selections(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
Definition: ir.c:5025
static enum vkd3d_result vsir_cfg_append_loop(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *new_list, struct vsir_cfg_structure *loop)
Definition: ir.c:5075
#define list
Definition: rosglue.h:35
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by vsir_cfg_optimize(), and vsir_cfg_optimize_recurse().

◆ vsir_cfg_remove_trailing_continue()

static void vsir_cfg_remove_trailing_continue ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list,
unsigned int  target 
)
static

Definition at line 4905 of file ir.c.

4907{
4908 struct vsir_cfg_structure *last = &list->structures[list->count - 1];
4909
4910 if (last->type == STRUCTURE_TYPE_JUMP && last->u.jump.type == JUMP_CONTINUE
4911 && !last->u.jump.condition && last->u.jump.target == target)
4912 {
4913 --list->count;
4914 VKD3D_ASSERT(cfg->loop_intervals[target].target_count > 0);
4915 --cfg->loop_intervals[target].target_count;
4916 }
4917}
static const LARGE_INTEGER *static const HANDLE const LARGE_INTEGER *static PSLIST_ENTRY PSLIST_ENTRY last
Definition: sync.c:64
unsigned int target
Definition: ir.c:3686
struct _LARGE_INTEGER::@2736 u

Referenced by vsir_cfg_optimize_recurse().

◆ vsir_cfg_scan_loop()

static enum vkd3d_result vsir_cfg_scan_loop ( struct vsir_block_list *  loop,
struct vsir_block *  block,
struct vsir_block *  header 
)
static

Definition at line 4221 of file ir.c.

4223{
4224 enum vkd3d_result ret;
4225 size_t i;
4226
4227 if ((ret = vsir_block_list_add(loop, block)) < 0)
4228 return ret;
4229
4230 if (ret == VKD3D_FALSE || block == header)
4231 return VKD3D_OK;
4232
4233 for (i = 0; i < block->predecessors.count; ++i)
4234 {
4235 if ((ret = vsir_cfg_scan_loop(loop, block->predecessors.blocks[i], header)) < 0)
4236 return ret;
4237 }
4238
4239 return VKD3D_OK;
4240}

Referenced by vsir_cfg_compute_loops(), and vsir_cfg_scan_loop().

◆ vsir_cfg_sort_nodes()

static enum vkd3d_result vsir_cfg_sort_nodes ( struct vsir_cfg *  cfg)
static

Definition at line 4352 of file ir.c.

4353{
4354 struct vsir_cfg_node_sorter sorter = { .cfg = cfg };
4355 unsigned int *in_degrees = NULL;
4356 enum vkd3d_result ret;
4357 size_t i;
4358
4359 if (!(in_degrees = vkd3d_calloc(cfg->block_count, sizeof(*in_degrees))))
4361
4362 for (i = 0; i < cfg->block_count; ++i)
4363 {
4364 struct vsir_block *block = &cfg->blocks[i];
4365
4366 if (block->label == 0)
4367 {
4368 in_degrees[i] = UINT_MAX;
4369 continue;
4370 }
4371
4372 in_degrees[i] = block->predecessors.count;
4373
4374 /* Do not count back edges. */
4375 if (cfg->loops_by_header[i] != SIZE_MAX)
4376 {
4377 VKD3D_ASSERT(in_degrees[i] > 0);
4378 in_degrees[i] -= 1;
4379 }
4380
4381 if (in_degrees[i] == 0 && block != cfg->entry)
4382 {
4383 WARN("Unexpected entry point %u.\n", block->label);
4385 "Block %u is unreachable from the entry point.", block->label);
4387 goto fail;
4388 }
4389 }
4390
4391 if (in_degrees[cfg->entry->label - 1] != 0)
4392 {
4393 WARN("Entry point has %u incoming forward edges.\n", in_degrees[cfg->entry->label - 1]);
4395 "The entry point block has %u incoming forward edges.", in_degrees[cfg->entry->label - 1]);
4397 goto fail;
4398 }
4399
4401
4402 if ((ret = vsir_block_list_add_checked(&sorter.available_blocks, cfg->entry)) < 0)
4403 goto fail;
4404
4405 while (sorter.available_blocks.count != 0)
4406 {
4407 struct vsir_cfg_node_sorter_stack_item *inner_stack_item = NULL;
4408 struct vsir_block *block;
4409 size_t new_seen_count;
4410
4411 if (sorter.stack_count != 0)
4412 inner_stack_item = &sorter.stack[sorter.stack_count - 1];
4413
4414 for (i = sorter.available_blocks.count - 1; ; --i)
4415 {
4416 if (i == SIZE_MAX)
4417 {
4418 ERR("Couldn't find any viable next block, is the input CFG reducible?\n");
4420 goto fail;
4421 }
4422
4423 block = sorter.available_blocks.blocks[i];
4424
4425 if (!inner_stack_item || vsir_block_list_search(inner_stack_item->loop, block))
4426 break;
4427 }
4428
4429 /* If the node is a loop header, open the loop. */
4430 if (sorter.cfg->loops_by_header[block->label - 1] != SIZE_MAX)
4431 {
4432 struct vsir_block_list *loop = &sorter.cfg->loops[sorter.cfg->loops_by_header[block->label - 1]];
4433
4434 if (loop)
4435 {
4436 if (!vkd3d_array_reserve((void **)&sorter.stack, &sorter.stack_capacity,
4437 sorter.stack_count + 1, sizeof(*sorter.stack)))
4439
4440 inner_stack_item = &sorter.stack[sorter.stack_count++];
4441 inner_stack_item->loop = loop;
4442 inner_stack_item->seen_count = 0;
4443 inner_stack_item->begin = sorter.cfg->order.count;
4444 }
4445 }
4446
4448 block->order_pos = cfg->order.count;
4449 if ((ret = vsir_block_list_add_checked(&cfg->order, block)) < 0)
4450 goto fail;
4451
4452 /* Close loops: since each loop is a strict subset of any
4453 * outer loop, we just need to track how many blocks we've
4454 * seen; when I close a loop I mark the same number of seen
4455 * blocks for the next outer loop. */
4456 new_seen_count = 1;
4457 while (sorter.stack_count != 0)
4458 {
4459 inner_stack_item = &sorter.stack[sorter.stack_count - 1];
4460
4461 inner_stack_item->seen_count += new_seen_count;
4462
4463 VKD3D_ASSERT(inner_stack_item->seen_count <= inner_stack_item->loop->count);
4464 if (inner_stack_item->seen_count != inner_stack_item->loop->count)
4465 break;
4466
4467 if ((ret = vsir_cfg_add_loop_interval(cfg, inner_stack_item->begin,
4468 cfg->order.count, false)) < 0)
4469 goto fail;
4470
4471 new_seen_count = inner_stack_item->loop->count;
4472 --sorter.stack_count;
4473 }
4474
4475 /* Remove (forward) edges and make new nodes available. */
4476 for (i = 0; i < block->successors.count; ++i)
4477 {
4478 struct vsir_block *successor = block->successors.blocks[i];
4479
4480 if (vsir_block_dominates(successor, block))
4481 continue;
4482
4483 VKD3D_ASSERT(in_degrees[successor->label - 1] > 0);
4484 --in_degrees[successor->label - 1];
4485
4486 if (in_degrees[successor->label - 1] == 0)
4487 {
4488 if ((ret = vsir_block_list_add_checked(&sorter.available_blocks, successor)) < 0)
4489 goto fail;
4490 }
4491 }
4492 }
4493
4494 if (cfg->order.count != cfg->block_count)
4495 {
4496 /* There is a cycle of forward edges. */
4497 WARN("The control flow graph is not reducible.\n");
4499 "The control flow graph is not reducible.");
4501 goto fail;
4502 }
4503
4504 VKD3D_ASSERT(sorter.stack_count == 0);
4505
4506 vkd3d_free(in_degrees);
4507 vkd3d_free(sorter.stack);
4509
4510 if (TRACE_ON())
4511 {
4512 vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order:");
4513
4514 for (i = 0; i < cfg->order.count; ++i)
4515 {
4516 if (cfg->debug_buffer.content_size > 512)
4517 {
4518 TRACE("%s...\n", cfg->debug_buffer.buffer);
4520 vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order: ...");
4521 }
4522 vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", cfg->order.blocks[i]->label);
4523 }
4524
4525 TRACE("%s\n", cfg->debug_buffer.buffer);
4527 }
4528
4529 return VKD3D_OK;
4530
4531fail:
4532 vkd3d_free(in_degrees);
4533 vkd3d_free(sorter.stack);
4535
4536 return ret;
4537}
static void vsir_block_list_remove_index(struct vsir_block_list *list, size_t idx)
Definition: ir.c:3567
static bool vsir_block_list_search(struct vsir_block_list *list, struct vsir_block *block)
Definition: ir.c:3630
size_t stack_count
Definition: ir.c:4324
struct vsir_block_list available_blocks
Definition: ir.c:4325
struct vsir_cfg * cfg
Definition: ir.c:4317
size_t stack_capacity
Definition: ir.c:4324
struct vsir_cfg_node_sorter::vsir_cfg_node_sorter_stack_item * stack
@ VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW

Referenced by vsir_program_structurize_function().

◆ vsir_cfg_structure_cleanup()

static void vsir_cfg_structure_cleanup ( struct vsir_cfg_structure *  structure)
static

Definition at line 3742 of file ir.c.

3743{
3744 switch (structure->type)
3745 {
3746 case STRUCTURE_TYPE_LOOP:
3747 vsir_cfg_structure_list_cleanup(&structure->u.loop.body);
3748 break;
3749
3750 case STRUCTURE_TYPE_SELECTION:
3751 vsir_cfg_structure_list_cleanup(&structure->u.selection.if_body);
3752 vsir_cfg_structure_list_cleanup(&structure->u.selection.else_body);
3753 break;
3754
3755 default:
3756 break;
3757 }
3758}

Referenced by vsir_cfg_structure_list_cleanup().

◆ vsir_cfg_structure_dump()

static void vsir_cfg_structure_dump ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure *  structure 
)
static

Definition at line 3928 of file ir.c.

3929{
3930 switch (structure->type)
3931 {
3932 case STRUCTURE_TYPE_BLOCK:
3933 TRACE("%sblock %u\n", cfg->debug_buffer.buffer, structure->u.block->label);
3934 break;
3935
3936 case STRUCTURE_TYPE_LOOP:
3937 TRACE("%s%u : loop {\n", cfg->debug_buffer.buffer, structure->u.loop.idx);
3938
3939 vsir_cfg_structure_list_dump(cfg, &structure->u.loop.body);
3940
3941 TRACE("%s} # %u%s\n", cfg->debug_buffer.buffer, structure->u.loop.idx,
3942 structure->u.loop.needs_trampoline ? ", tramp" : "");
3943 break;
3944
3945 case STRUCTURE_TYPE_SELECTION:
3946 TRACE("%sif {\n", cfg->debug_buffer.buffer);
3947
3948 vsir_cfg_structure_list_dump(cfg, &structure->u.selection.if_body);
3949
3950 if (structure->u.selection.else_body.count == 0)
3951 {
3952 TRACE("%s}\n", cfg->debug_buffer.buffer);
3953 }
3954 else
3955 {
3956 TRACE("%s} else {\n", cfg->debug_buffer.buffer);
3957
3958 vsir_cfg_structure_list_dump(cfg, &structure->u.selection.else_body);
3959
3960 TRACE("%s}\n", cfg->debug_buffer.buffer);
3961 }
3962 break;
3963
3964 case STRUCTURE_TYPE_JUMP:
3965 {
3966 const char *type_str;
3967
3968 switch (structure->u.jump.type)
3969 {
3970 case JUMP_RET:
3971 TRACE("%sret\n", cfg->debug_buffer.buffer);
3972 return;
3973
3974 case JUMP_BREAK:
3975 type_str = "break";
3976 break;
3977
3978 case JUMP_CONTINUE:
3979 type_str = "continue";
3980 break;
3981
3982 default:
3984 }
3985
3986 TRACE("%s%s%s %u%s\n", cfg->debug_buffer.buffer, type_str,
3987 structure->u.jump.condition ? "c" : "", structure->u.jump.target,
3988 structure->u.jump.needs_launcher ? " # launch" : "");
3989 break;
3990 }
3991
3992 default:
3994 }
3995}
static void vsir_cfg_structure_list_dump(struct vsir_cfg *cfg, struct vsir_cfg_structure_list *list)
Definition: ir.c:3997

Referenced by vsir_cfg_dump_structured_program(), and vsir_cfg_structure_list_dump().

◆ vsir_cfg_structure_init()

static void vsir_cfg_structure_init ( struct vsir_cfg_structure *  structure,
enum vsir_cfg_structure_type  type 
)
static

Definition at line 3736 of file ir.c.

3737{
3738 memset(structure, 0, sizeof(*structure));
3739 structure->type = type;
3740}

Referenced by vsir_cfg_structure_list_append(), and vsir_cfg_synthesize_selections().

◆ vsir_cfg_structure_list_append()

static struct vsir_cfg_structure * vsir_cfg_structure_list_append ( struct vsir_cfg_structure_list *  list,
enum vsir_cfg_structure_type  type 
)
static

Definition at line 3706 of file ir.c.

3708{
3709 struct vsir_cfg_structure *ret;
3710
3711 if (!vkd3d_array_reserve((void **)&list->structures, &list->capacity, list->count + 1,
3712 sizeof(*list->structures)))
3713 return NULL;
3714
3715 ret = &list->structures[list->count++];
3716
3718
3719 return ret;
3720}
static void vsir_cfg_structure_init(struct vsir_cfg_structure *structure, enum vsir_cfg_structure_type type)
Definition: ir.c:3736

Referenced by vsir_cfg_build_structured_program(), vsir_cfg_move_breaks_out_of_selections(), and vsir_cfg_synthesize_selections().

◆ vsir_cfg_structure_list_append_from_region()

static enum vkd3d_result vsir_cfg_structure_list_append_from_region ( struct vsir_cfg_structure_list *  list,
struct vsir_cfg_structure *  begin,
size_t  size 
)
static

Definition at line 3722 of file ir.c.

3724{
3725 if (!vkd3d_array_reserve((void **)&list->structures, &list->capacity, list->count + size,
3726 sizeof(*list->structures)))
3728
3729 memcpy(&list->structures[list->count], begin, size * sizeof(*begin));
3730
3731 list->count += size;
3732
3733 return VKD3D_OK;
3734}
GLsizeiptr size
Definition: glext.h:5919

Referenced by vsir_cfg_append_loop(), vsir_cfg_optimize_recurse(), and vsir_cfg_synthesize_selections().

◆ vsir_cfg_structure_list_cleanup()

static void vsir_cfg_structure_list_cleanup ( struct vsir_cfg_structure_list *  list)
static

Definition at line 3697 of file ir.c.

3698{
3699 unsigned int i;
3700
3701 for (i = 0; i < list->count; ++i)
3702 vsir_cfg_structure_cleanup(&list->structures[i]);
3703 vkd3d_free(list->structures);
3704}
static void vsir_cfg_structure_cleanup(struct vsir_cfg_structure *structure)
Definition: ir.c:3742

Referenced by vsir_cfg_cleanup(), vsir_cfg_optimize_recurse(), and vsir_cfg_structure_cleanup().

◆ vsir_cfg_structure_list_dump()

static void vsir_cfg_structure_list_dump ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list 
)
static

Definition at line 3997 of file ir.c.

3998{
3999 unsigned int i;
4000
4002
4003 for (i = 0; i < list->count; ++i)
4004 vsir_cfg_structure_dump(cfg, &list->structures[i]);
4005
4006 vkd3d_string_buffer_truncate(&cfg->debug_buffer, cfg->debug_buffer.content_size - 2);
4007}
void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t size)

Referenced by vsir_cfg_structure_dump().

◆ vsir_cfg_structure_list_emit()

static enum vkd3d_result vsir_cfg_structure_list_emit ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list,
unsigned int  loop_idx 
)
static

Definition at line 5539 of file ir.c.

5541{
5542 enum vkd3d_result ret;
5543 size_t i;
5544
5545 for (i = 0; i < list->count; ++i)
5546 {
5547 struct vsir_cfg_structure *structure = &list->structures[i];
5548
5549 switch (structure->type)
5550 {
5552 if ((ret = vsir_cfg_structure_list_emit_block(cfg, structure->u.block)) < 0)
5553 return ret;
5554 break;
5555
5557 if ((ret = vsir_cfg_structure_list_emit_loop(cfg, &structure->u.loop, loop_idx)) < 0)
5558 return ret;
5559 break;
5560
5562 if ((ret = vsir_cfg_structure_list_emit_selection(cfg, &structure->u.selection,
5563 loop_idx)) < 0)
5564 return ret;
5565 break;
5566
5568 if ((ret = vsir_cfg_structure_list_emit_jump(cfg, &structure->u.jump,
5569 loop_idx)) < 0)
5570 return ret;
5571 break;
5572
5573 default:
5575 }
5576 }
5577
5578 return VKD3D_OK;
5579}
static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg *cfg, struct vsir_cfg_structure_selection *selection, unsigned int loop_idx)
Definition: ir.c:5428
static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg, struct vsir_block *block)
Definition: ir.c:5336
static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, struct vsir_cfg_structure_jump *jump, unsigned int loop_idx)
Definition: ir.c:5471
static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, struct vsir_cfg_structure_loop *loop, unsigned int loop_idx)
Definition: ir.c:5353

Referenced by vsir_cfg_emit_structured_program(), vsir_cfg_structure_list_emit_loop(), and vsir_cfg_structure_list_emit_selection().

◆ vsir_cfg_structure_list_emit_block()

static enum vkd3d_result vsir_cfg_structure_list_emit_block ( struct vsir_cfg *  cfg,
struct vsir_block *  block 
)
static

Definition at line 5336 of file ir.c.

5338{
5339 struct vsir_cfg_emit_target *target = cfg->target;
5340
5341 if (!reserve_instructions(&target->instructions, &target->ins_capacity,
5342 target->ins_count + (block->end - block->begin)))
5344
5345 memcpy(&target->instructions[target->ins_count], block->begin,
5346 (char *)block->end - (char *)block->begin);
5347
5348 target->ins_count += block->end - block->begin;
5349
5350 return VKD3D_OK;
5351}
static bool reserve_instructions(struct vkd3d_shader_instruction **instructions, size_t *capacity, size_t count)
Definition: ir.c:3166

Referenced by vsir_cfg_structure_list_emit().

◆ vsir_cfg_structure_list_emit_jump()

static enum vkd3d_result vsir_cfg_structure_list_emit_jump ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_jump *  jump,
unsigned int  loop_idx 
)
static

Definition at line 5471 of file ir.c.

5473{
5474 struct vsir_cfg_emit_target *target = cfg->target;
5475 const struct vkd3d_shader_location no_loc = {0};
5476 /* Encode the jump target as the loop index plus a bit to remember whether
5477 * we're breaking or continue-ing. */
5478 unsigned int jump_target = jump->target << 1;
5479 enum vkd3d_shader_opcode opcode;
5480
5481 switch (jump->type)
5482 {
5483 case JUMP_CONTINUE:
5484 /* If we're continue-ing the loop we're directly inside, then we can emit a
5485 * `continue'. Otherwise we first have to break all the loops between here
5486 * and the loop to continue, recording our intention to continue
5487 * in the lowest bit of jump_target. */
5488 if (jump->target == loop_idx)
5489 {
5490 opcode = jump->condition ? VKD3DSIH_CONTINUEP : VKD3DSIH_CONTINUE;
5491 break;
5492 }
5493 jump_target |= 1;
5494 /* fall through */
5495
5496 case JUMP_BREAK:
5497 opcode = jump->condition ? VKD3DSIH_BREAKP : VKD3DSIH_BREAK;
5498 break;
5499
5500 case JUMP_RET:
5501 VKD3D_ASSERT(!jump->condition);
5502 opcode = VKD3DSIH_RET;
5503 break;
5504
5505 default:
5507 }
5508
5509 if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 2))
5511
5512 if (jump->needs_launcher)
5513 {
5514 if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
5515 &no_loc, VKD3DSIH_MOV, 1, 1))
5517
5518 dst_param_init_temp_uint(&target->instructions[target->ins_count].dst[0], target->jump_target_temp_idx);
5519 src_param_init_const_uint(&target->instructions[target->ins_count].src[0], jump_target);
5520
5521 ++target->ins_count;
5522 }
5523
5524 if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
5525 &no_loc, opcode, 0, !!jump->condition))
5527
5528 if (jump->invert_condition)
5529 target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
5530
5531 if (jump->condition)
5532 target->instructions[target->ins_count].src[0] = *jump->condition;
5533
5534 ++target->ins_count;
5535
5536 return VKD3D_OK;
5537}
static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx)
Definition: ir.c:306

Referenced by vsir_cfg_structure_list_emit().

◆ vsir_cfg_structure_list_emit_loop()

static enum vkd3d_result vsir_cfg_structure_list_emit_loop ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_loop *  loop,
unsigned int  loop_idx 
)
static

Definition at line 5353 of file ir.c.

5355{
5356 struct vsir_cfg_emit_target *target = cfg->target;
5357 const struct vkd3d_shader_location no_loc = {0};
5358 enum vkd3d_result ret;
5359
5360 if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
5362
5363 vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_LOOP);
5364
5365 if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0)
5366 return ret;
5367
5368 if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 5))
5370
5371 vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDLOOP);
5372
5373 /* Add a trampoline to implement multilevel jumping depending on the stored
5374 * jump_target value. */
5375 if (loop->needs_trampoline)
5376 {
5377 /* If the multilevel jump is a `continue' and the target is the loop we're inside
5378 * right now, then we can finally do the `continue'. */
5379 const unsigned int outer_continue_target = loop_idx << 1 | 1;
5380 /* If the multilevel jump is a `continue' to any other target, or if it is a `break'
5381 * and the target is not the loop we just finished emitting, then it means that
5382 * we have to reach an outer loop, so we keep breaking. */
5383 const unsigned int inner_break_target = loop->idx << 1;
5384
5385 if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
5386 &no_loc, VKD3DSIH_IEQ, 1, 2))
5388
5389 dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count);
5390 src_param_init_temp_uint(&target->instructions[target->ins_count].src[0], target->jump_target_temp_idx);
5391 src_param_init_const_uint(&target->instructions[target->ins_count].src[1], outer_continue_target);
5392
5393 ++target->ins_count;
5394
5395 if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
5396 &no_loc, VKD3DSIH_CONTINUEP, 0, 1))
5398
5399 src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count);
5400
5401 ++target->ins_count;
5402 ++target->temp_count;
5403
5404 if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
5405 &no_loc, VKD3DSIH_IEQ, 1, 2))
5407
5408 dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count);
5409 src_param_init_temp_uint(&target->instructions[target->ins_count].src[0], target->jump_target_temp_idx);
5410 src_param_init_const_uint(&target->instructions[target->ins_count].src[1], inner_break_target);
5411
5412 ++target->ins_count;
5413
5414 if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
5415 &no_loc, VKD3DSIH_BREAKP, 0, 1))
5417 target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
5418
5419 src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count);
5420
5421 ++target->ins_count;
5422 ++target->temp_count;
5423 }
5424
5425 return VKD3D_OK;
5426}
static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
Definition: ir.c:246
static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
Definition: ir.c:293

Referenced by vsir_cfg_structure_list_emit().

◆ vsir_cfg_structure_list_emit_selection()

static enum vkd3d_result vsir_cfg_structure_list_emit_selection ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_selection *  selection,
unsigned int  loop_idx 
)
static

Definition at line 5428 of file ir.c.

5430{
5431 struct vsir_cfg_emit_target *target = cfg->target;
5432 const struct vkd3d_shader_location no_loc = {0};
5433 enum vkd3d_result ret;
5434
5435 if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
5437
5438 if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
5439 &no_loc, VKD3DSIH_IF, 0, 1))
5441
5442 target->instructions[target->ins_count].src[0] = *selection->condition;
5443
5444 if (selection->invert_condition)
5445 target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
5446
5447 ++target->ins_count;
5448
5449 if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->if_body, loop_idx)) < 0)
5450 return ret;
5451
5452 if (selection->else_body.count != 0)
5453 {
5454 if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
5456
5457 vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ELSE);
5458
5459 if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->else_body, loop_idx)) < 0)
5460 return ret;
5461 }
5462
5463 if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
5465
5466 vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDIF);
5467
5468 return VKD3D_OK;
5469}

Referenced by vsir_cfg_structure_list_emit().

◆ vsir_cfg_synthesize_selections()

static enum vkd3d_result vsir_cfg_synthesize_selections ( struct vsir_cfg *  cfg,
struct vsir_cfg_structure_list *  list 
)
static

Definition at line 5025 of file ir.c.

5027{
5028 enum vkd3d_result ret;
5029 size_t i;
5030
5031 for (i = 0; i < list->count; ++i)
5032 {
5033 struct vsir_cfg_structure *structure = &list->structures[i], new_selection, *new_jump;
5034
5035 if (structure->type != STRUCTURE_TYPE_JUMP || !structure->u.jump.condition)
5036 continue;
5037
5039 new_selection.u.selection.condition = structure->u.jump.condition;
5040 new_selection.u.selection.invert_condition = structure->u.jump.invert_condition;
5041
5042 if (!(new_jump = vsir_cfg_structure_list_append(&new_selection.u.selection.if_body,
5045 new_jump->u.jump.type = structure->u.jump.type;
5046 new_jump->u.jump.target = structure->u.jump.target;
5047
5048 /* Move the rest of the structure list in the else branch
5049 * rather than leaving it after the selection construct. The
5050 * reason is that this is more conducive to further
5051 * optimization, because all the conditional `break's appear
5052 * as the last instruction of a branch of a cascade of
5053 * selection constructs at the end of the structure list we're
5054 * processing, instead of being buried in the middle of the
5055 * structure list itself. */
5056 if ((ret = vsir_cfg_structure_list_append_from_region(&new_selection.u.selection.else_body,
5057 &list->structures[i + 1], list->count - i - 1)) < 0)
5058 return ret;
5059
5060 *structure = new_selection;
5061 list->count = i + 1;
5062
5063 if ((ret = vsir_cfg_synthesize_selections(cfg, &structure->u.selection.else_body)) < 0)
5064 return ret;
5065
5067 return ret;
5068
5069 break;
5070 }
5071
5072 return VKD3D_OK;
5073}

Referenced by vsir_cfg_optimize_recurse(), and vsir_cfg_synthesize_selections().

◆ vsir_dst_param_init()

◆ vsir_instruction_init()

void vsir_instruction_init ( struct vkd3d_shader_instruction *  ins,
const struct vkd3d_shader_location *  location,
enum vkd3d_shader_opcode  opcode 
)

Definition at line 321 of file ir.c.

323{
324 memset(ins, 0, sizeof(*ins));
325 ins->location = *location;
326 ins->opcode = opcode;
327}
#define location(file, line)
Definition: kmtest.h:18

Referenced by cf_flattener_emit_branch(), cf_flattener_iterate_instruction_array(), control_point_normaliser_emit_hs_input(), instruction_init_with_resource(), shader_sm1_read_instruction(), shader_sm4_read_instruction(), sm6_parser_add_instruction(), sm6_parser_declare_indexable_temp(), sm6_parser_emit_atomicrmw(), sm6_parser_emit_binop(), sm6_parser_emit_cast(), sm6_parser_emit_cmp2(), sm6_parser_emit_cmpxchg(), sm6_parser_emit_dx_atomic_binop(), sm6_parser_emit_dx_barrier(), sm6_parser_emit_dx_binary(), sm6_parser_emit_dx_buffer_store(), sm6_parser_emit_dx_buffer_update_counter(), sm6_parser_emit_dx_calculate_lod(), sm6_parser_emit_dx_cbuffer_load(), sm6_parser_emit_dx_compute_builtin(), sm6_parser_emit_dx_discard(), sm6_parser_emit_dx_domain_location(), sm6_parser_emit_dx_dot(), sm6_parser_emit_dx_fabs(), sm6_parser_emit_dx_get_dimensions(), sm6_parser_emit_dx_get_sample_count(), sm6_parser_emit_dx_get_sample_pos(), sm6_parser_emit_dx_input_register_mov(), sm6_parser_emit_dx_load_input(), sm6_parser_emit_dx_ma(), sm6_parser_emit_dx_make_double(), sm6_parser_emit_dx_quad_op(), sm6_parser_emit_dx_raw_buffer_store(), sm6_parser_emit_dx_sample_index(), sm6_parser_emit_dx_saturate(), sm6_parser_emit_dx_sincos(), sm6_parser_emit_dx_split_double(), sm6_parser_emit_dx_store_output(), sm6_parser_emit_dx_stream(), sm6_parser_emit_dx_tertiary(), sm6_parser_emit_dx_texture_store(), sm6_parser_emit_dx_unary(), sm6_parser_emit_dx_void(), sm6_parser_emit_dx_wave_active_ballot(), sm6_parser_emit_dx_wave_active_bit(), sm6_parser_emit_dx_wave_op(), sm6_parser_emit_extractval(), sm6_parser_emit_load(), sm6_parser_emit_reg_composite_construct(), sm6_parser_emit_store(), sm6_parser_emit_vselect(), sm6_parser_resources_load_cbv(), sm6_parser_resources_load_sampler(), sm6_parser_resources_load_srv(), sm6_parser_resources_load_uav(), vkd3d_shader_instruction_make_nop(), vsir_cfg_structure_list_emit_loop(), vsir_cfg_structure_list_emit_selection(), vsir_instruction_init_label(), vsir_instruction_init_with_params(), vsir_program_ensure_ret(), and vsir_program_flatten_hull_shader_phases().

◆ vsir_instruction_init_label()

static bool vsir_instruction_init_label ( struct vkd3d_shader_instruction *  ins,
const struct vkd3d_shader_location *  location,
unsigned int  label_id,
struct vsir_program *  program 
)
static

Definition at line 354 of file ir.c.

356{
357 struct vkd3d_shader_src_param *src_param;
358
359 if (!(src_param = vsir_program_get_src_params(program, 1)))
360 return false;
361
362 vsir_src_param_init_label(src_param, label_id);
363
365 ins->src = src_param;
366 ins->src_count = 1;
367
368 return true;
369}

Referenced by cf_flattener_emit_label().

◆ vsir_instruction_init_with_params()

bool vsir_instruction_init_with_params ( struct vsir_program *  program,
struct vkd3d_shader_instruction *  ins,
const struct vkd3d_shader_location *  location,
enum vkd3d_shader_opcode  opcode,
unsigned int  dst_count,
unsigned int  src_count 
)

Definition at line 329 of file ir.c.

332{
333 vsir_instruction_init(ins, location, opcode);
334 ins->dst_count = dst_count;
335 ins->src_count = src_count;
336
338 {
339 ERR("Failed to allocate %u destination parameters.\n", dst_count);
340 return false;
341 }
342
344 {
345 ERR("Failed to allocate %u source parameters.\n", src_count);
346 return false;
347 }
348
349 memset(ins->dst, 0, sizeof(*ins->dst) * ins->dst_count);
350 memset(ins->src, 0, sizeof(*ins->src) * ins->src_count);
351 return true;
352}
static struct vkd3d_shader_dst_param * vsir_program_get_dst_params(struct vsir_program *program, unsigned int count)

Referenced by generate_vsir_add_program_instruction(), insert_alpha_test_before_ret(), insert_clip_planes_before_ret(), insert_point_size_before_ret(), sm1_generate_vsir_constant_defs(), sm1_generate_vsir_sampler_dcls(), vsir_cfg_structure_list_emit_jump(), vsir_cfg_structure_list_emit_loop(), vsir_cfg_structure_list_emit_selection(), vsir_program_ensure_diffuse(), vsir_program_insert_point_coord(), vsir_program_insert_point_size_clamp(), vsir_program_lower_ifc(), vsir_program_lower_precise_mad(), vsir_program_lower_sm1_sincos(), vsir_program_lower_switch_to_selection_ladder(), vsir_program_lower_texkill(), vsir_program_materialise_phi_ssas_to_temps(), and vsir_program_remap_output_signature().

◆ vsir_instruction_is_dcl()

◆ vsir_program_add_diffuse_output()

static enum vkd3d_result vsir_program_add_diffuse_output ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 850 of file ir.c.

852{
853 struct shader_signature *signature = &program->output_signature;
854 struct signature_element *new_elements, *e;
855
856 if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX)
857 return VKD3D_OK;
858
860 {
861 program->diffuse_written_mask = e->mask;
862 e->mask = VKD3DSP_WRITEMASK_ALL;
863
864 return VKD3D_OK;
865 }
866
867 if (!(new_elements = vkd3d_realloc(signature->elements,
868 (signature->element_count + 1) * sizeof(*signature->elements))))
870 signature->elements = new_elements;
871 e = &signature->elements[signature->element_count++];
872 memset(e, 0, sizeof(*e));
873 e->semantic_name = vkd3d_strdup("COLOR");
874 e->sysval_semantic = VKD3D_SHADER_SV_NONE;
875 e->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
876 e->register_count = 1;
877 e->mask = VKD3DSP_WRITEMASK_ALL;
878 e->used_mask = VKD3DSP_WRITEMASK_ALL;
879 e->register_index = SM1_COLOR_REGISTER_OFFSET;
880 e->target_location = SM1_COLOR_REGISTER_OFFSET;
881 e->interpolation_mode = VKD3DSIM_NONE;
882
883 return VKD3D_OK;
884}
static struct signature_element * vsir_signature_find_element_by_name(const struct shader_signature *signature, const char *semantic_name, unsigned int semantic_index)
Definition: ir.c:132
static char * vkd3d_strdup(const char *string)
Definition: vkd3d_memory.h:57
static void * vkd3d_realloc(void *ptr, size_t size)
Definition: vkd3d_memory.h:36
@ VKD3D_SHADER_COMPONENT_FLOAT
@ VKD3DSIM_NONE

Referenced by vsir_program_transform_early().

◆ vsir_program_apply_flat_interpolation()

static enum vkd3d_result vsir_program_apply_flat_interpolation ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 5877 of file ir.c.

5879{
5880 unsigned int i;
5881 bool flat;
5882
5883 if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL || program->shader_version.major >= 4)
5884 return VKD3D_OK;
5885
5886 if (!use_flat_interpolation(program, ctx->message_context, &flat))
5888
5889 if (!flat)
5890 return VKD3D_OK;
5891
5892 for (i = 0; i < program->input_signature.element_count; ++i)
5893 {
5894 struct signature_element *element = &program->input_signature.elements[i];
5895
5896 if (!ascii_strcasecmp(element->semantic_name, "COLOR"))
5897 element->interpolation_mode = VKD3DSIM_CONSTANT;
5898 }
5899
5900 return VKD3D_OK;
5901}
static bool use_flat_interpolation(const struct vsir_program *program, struct vkd3d_shader_message_context *message_context, bool *flat)
Definition: ir.c:5849
@ VKD3DSIM_CONSTANT

Referenced by vsir_program_transform().

◆ vsir_program_cleanup()

void vsir_program_cleanup ( struct vsir_program *  program)

Definition at line 105 of file ir.c.

106{
107 size_t i;
108
109 if (program->free_parameters)
110 vkd3d_free((void *)program->parameters);
111 for (i = 0; i < program->block_name_count; ++i)
112 vkd3d_free((void *)program->block_names[i]);
113 vkd3d_free(program->block_names);
115 shader_signature_cleanup(&program->input_signature);
116 shader_signature_cleanup(&program->output_signature);
117 shader_signature_cleanup(&program->patch_constant_signature);
118}
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions)
void shader_signature_cleanup(struct shader_signature *signature)

Referenced by d3dbc_parse(), hlsl_compile_shader(), hlsl_emit_bytecode(), sm6_parser_init(), tpf_parse(), vkd3d_shader_compile(), vkd3d_shader_scan(), and vsir_parse().

◆ vsir_program_create_outpointid_param()

struct vkd3d_shader_src_param * vsir_program_create_outpointid_param ( struct vsir_program *  program)

Definition at line 1336 of file ir.c.

1337{
1338 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
1339 struct vkd3d_shader_src_param *rel_addr;
1340
1341 if (instructions->outpointid_param)
1342 return instructions->outpointid_param;
1343
1344 if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1)))
1345 return NULL;
1346
1348 rel_addr->swizzle = 0;
1349 rel_addr->modifiers = 0;
1350
1351 instructions->outpointid_param = rel_addr;
1352 return rel_addr;
1353}
struct vkd3d_shader_src_param * outpointid_param
struct vkd3d_shader_param_allocator src_params
enum vkd3d_shader_src_modifier modifiers
@ VKD3DSPR_OUTPOINTID
static struct vkd3d_shader_src_param * shader_src_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count)

Referenced by instruction_array_normalise_hull_shader_control_point_io(), and sm6_parser_init_signature().

◆ vsir_program_ensure_diffuse()

static enum vkd3d_result vsir_program_ensure_diffuse ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 888 of file ir.c.

890{
891 static const struct vkd3d_shader_location no_loc;
892 struct vkd3d_shader_instruction *ins;
893 unsigned int i;
894
895 if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX
896 || program->diffuse_written_mask == VKD3DSP_WRITEMASK_ALL)
897 return VKD3D_OK;
898
899 /* Write the instruction after all LABEL, DCL, and NOP instructions.
900 * We need to skip NOP instructions because they might result from removed
901 * DCLs, and there could still be DCLs after NOPs. */
902 for (i = 0; i < program->instructions.count; ++i)
903 {
904 ins = &program->instructions.elements[i];
905
906 if (!vsir_instruction_is_dcl(ins) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP)
907 break;
908 }
909
910 if (!shader_instruction_array_insert_at(&program->instructions, i, 1))
912 ins = &program->instructions.elements[i];
915 ins->dst[0].reg.idx[0].offset = 0;
916 ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
917 ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask;
919 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
920 for (i = 0; i < 4; ++i)
921 ins->src[0].reg.u.immconst_f32[i] = 1.0f;
922 return VKD3D_OK;
923}

Referenced by vsir_program_transform().

◆ vsir_program_ensure_ret()

static enum vkd3d_result vsir_program_ensure_ret ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 836 of file ir.c.

838{
839 static const struct vkd3d_shader_location no_loc;
840 if (program->instructions.count
841 && program->instructions.elements[program->instructions.count - 1].opcode == VKD3DSIH_RET)
842 return VKD3D_OK;
843
844 if (!shader_instruction_array_insert_at(&program->instructions, program->instructions.count, 1))
846 vsir_instruction_init(&program->instructions.elements[program->instructions.count - 1], &no_loc, VKD3DSIH_RET);
847 return VKD3D_OK;
848}

Referenced by vsir_program_transform().

◆ vsir_program_flatten_control_flow_constructs()

static enum vkd3d_result vsir_program_flatten_control_flow_constructs ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 3129 of file ir.c.

3131{
3132 struct vkd3d_shader_message_context *message_context = ctx->message_context;
3133 struct cf_flattener flattener = {.program = program};
3134 enum vkd3d_result result;
3135
3137
3138 if ((result = cf_flattener_iterate_instruction_array(&flattener, message_context)) >= 0)
3139 {
3140 vkd3d_free(program->instructions.elements);
3141 program->instructions.elements = flattener.instructions;
3142 program->instructions.capacity = flattener.instruction_capacity;
3143 program->instructions.count = flattener.instruction_count;
3144 program->block_count = flattener.block_id;
3145 program->cf_type = VSIR_CF_BLOCKS;
3146 }
3147 else
3148 {
3149 vkd3d_free(flattener.instructions);
3150 }
3151
3152 vkd3d_free(flattener.control_flow_info);
3153 /* Simpler to always free these in vsir_program_cleanup(). */
3154 program->block_names = flattener.block_names;
3155 program->block_name_count = flattener.block_name_count;
3156
3157 return result;
3158}
GLuint64EXT * result
Definition: glext.h:11304
static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flattener *flattener, struct vkd3d_shader_message_context *message_context)
Definition: ir.c:2783
const char ** block_names
Definition: ir.c:2561
size_t block_name_count
Definition: ir.c:2563

Referenced by vsir_program_transform().

◆ vsir_program_flatten_hull_shader_phases()

static enum vkd3d_result vsir_program_flatten_hull_shader_phases ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 1295 of file ir.c.

1297{
1298 struct hull_flattener flattener = {program->instructions};
1299 struct vkd3d_shader_instruction_array *instructions;
1302 unsigned int i;
1303
1304 instructions = &flattener.instructions;
1305
1306 flattener.phase = VKD3DSIH_INVALID;
1307 for (i = 0, locations.count = 0; i < instructions->count; ++i)
1309
1310 if ((result = flattener_flatten_phases(&flattener, &locations)) < 0)
1311 return result;
1312
1313 if (flattener.phase != VKD3DSIH_INVALID)
1314 {
1315 if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1))
1317 vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET);
1318 }
1319
1320 program->instructions = flattener.instructions;
1321 return result;
1322}
static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser, struct shader_phase_location_array *locations)
Definition: ir.c:1245
static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index, struct shader_phase_location_array *locations)
Definition: ir.c:1190

Referenced by vsir_program_transform().

◆ vsir_program_get_parameter()

const struct vkd3d_shader_parameter1 * vsir_program_get_parameter ( const struct vsir_program *  program,
enum vkd3d_shader_parameter_name  name 
)

Definition at line 120 of file ir.c.

122{
123 for (unsigned int i = 0; i < program->parameter_count; ++i)
124 {
125 if (program->parameters[i].name == name)
126 return &program->parameters[i];
127 }
128
129 return NULL;
130}
Definition: name.c:39

Referenced by spirv_compiler_emit_shader_parameter(), use_flat_interpolation(), and vsir_program_insert_alpha_test().

◆ vsir_program_init()

bool vsir_program_init ( struct vsir_program *  program,
const struct vkd3d_shader_compile_info *  compile_info,
const struct vkd3d_shader_version *  version,
unsigned int  reserve,
enum vsir_control_flow_type  cf_type,
enum vsir_normalisation_level  normalisation_level 
)

Definition at line 76 of file ir.c.

79{
80 memset(program, 0, sizeof(*program));
81
82 if (compile_info)
83 {
84 const struct vkd3d_shader_parameter_info *parameter_info;
85
86 if ((parameter_info = vkd3d_find_struct(compile_info->next, PARAMETER_INFO)))
87 {
88 program->parameter_count = parameter_info->parameter_count;
89 program->parameters = parameter_info->parameters;
90 }
91 else
92 {
93 if (convert_parameter_info(compile_info, &program->parameter_count, &program->parameters) < 0)
94 return false;
95 program->free_parameters = true;
96 }
97 }
98
99 program->shader_version = *version;
100 program->cf_type = cf_type;
101 program->normalisation_level = normalisation_level;
102 return shader_instruction_array_init(&program->instructions, reserve);
103}
static BOOL reserve(struct dynamic_array *array, int count, int itemsize)
Definition: mesh.c:5499
static const WCHAR version[]
Definition: asmname.c:66
static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters)
Definition: ir.c:31
const struct vkd3d_shader_parameter1 * parameters
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve)

Referenced by shader_sm1_init(), shader_sm4_init(), sm1_generate_vsir(), sm4_generate_vsir(), and sm6_parser_init().

◆ vsir_program_insert_alpha_test()

static enum vkd3d_result vsir_program_insert_alpha_test ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 5999 of file ir.c.

6001{
6002 struct vkd3d_shader_message_context *message_context = ctx->message_context;
6003 const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL;
6004 uint32_t colour_signature_idx, colour_temp = ~0u;
6005 static const struct vkd3d_shader_location no_loc;
6006 enum vkd3d_shader_comparison_func compare_func;
6007 struct vkd3d_shader_instruction *ins;
6008 size_t new_pos;
6009 int ret;
6010
6011 if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
6012 return VKD3D_OK;
6013
6014 if (!vsir_signature_find_sysval(&program->output_signature, VKD3D_SHADER_SV_TARGET, 0, &colour_signature_idx)
6015 || !(program->output_signature.elements[colour_signature_idx].mask & VKD3DSP_WRITEMASK_3))
6016 return VKD3D_OK;
6017
6020 return VKD3D_OK;
6021
6023 {
6025 "Unsupported alpha test function parameter type %#x.", func->type);
6027 }
6029 {
6031 "Invalid alpha test function parameter data type %#x.", func->data_type);
6033 }
6034 compare_func = func->u.immediate_constant.u.u32;
6035
6036 if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_ALWAYS)
6037 return VKD3D_OK;
6038
6039 /* We're going to be reading from the output, so we need to go
6040 * through the whole shader and convert it to a temp. */
6041
6042 if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER)
6043 colour_temp = program->temp_count++;
6044
6045 for (size_t i = 0; i < program->instructions.count; ++i)
6046 {
6047 ins = &program->instructions.elements[i];
6048
6049 if (vsir_instruction_is_dcl(ins))
6050 continue;
6051
6052 if (ins->opcode == VKD3DSIH_RET)
6053 {
6054 if ((ret = insert_alpha_test_before_ret(program, ins, compare_func,
6055 ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0)
6056 return ret;
6057 i = new_pos;
6058 continue;
6059 }
6060
6061 /* No need to convert it if the comparison func is NEVER; we don't
6062 * read from the output in that case. */
6063 if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER)
6064 continue;
6065
6066 for (size_t j = 0; j < ins->dst_count; ++j)
6067 {
6068 struct vkd3d_shader_dst_param *dst = &ins->dst[j];
6069
6070 /* Note we run after I/O normalization. */
6071 if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx)
6072 {
6073 dst->reg.type = VKD3DSPR_TEMP;
6074 dst->reg.idx[0].offset = colour_temp;
6075 }
6076 }
6077 }
6078
6079 return VKD3D_OK;
6080}
GLenum func
Definition: glext.h:6028
bool vsir_signature_find_sysval(const struct shader_signature *signature, enum vkd3d_shader_sysval_semantic sysval, unsigned int semantic_index, unsigned int *element_index)
Definition: ir.c:145
static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program, const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func, const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx, uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context)
Definition: ir.c:5903
vkd3d_shader_comparison_func
@ VKD3D_SHADER_COMPARISON_FUNC_ALWAYS
@ VKD3D_SHADER_SV_TARGET
@ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC
Definition: vkd3d_shader.h:565
#define VKD3DSP_WRITEMASK_3

Referenced by vsir_program_transform().

◆ vsir_program_insert_clip_planes()

static enum vkd3d_result vsir_program_insert_clip_planes ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 6132 of file ir.c.

6134{
6135 struct shader_signature *signature = &program->output_signature;
6136 unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u;
6137 const struct vkd3d_shader_parameter1 *mask_parameter = NULL;
6138 struct signature_element *new_elements, *clip_element;
6139 uint32_t position_signature_idx, position_temp, mask;
6140 static const struct vkd3d_shader_location no_loc;
6141 struct vkd3d_shader_instruction *ins;
6142 unsigned int plane_count;
6143 size_t new_pos;
6144 int ret;
6145
6146 if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX)
6147 return VKD3D_OK;
6148
6149 for (unsigned int i = 0; i < program->parameter_count; ++i)
6150 {
6151 const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i];
6152
6154 mask_parameter = parameter;
6155 }
6156
6157 if (!mask_parameter)
6158 return VKD3D_OK;
6159
6161 {
6163 "Unsupported clip plane mask parameter type %#x.", mask_parameter->type);
6165 }
6167 {
6169 "Invalid clip plane mask parameter data type %#x.", mask_parameter->data_type);
6171 }
6172 mask = mask_parameter->u.immediate_constant.u.u32;
6173
6174 if (!mask)
6175 return VKD3D_OK;
6176
6177 for (unsigned int i = 0; i < signature->element_count; ++i)
6178 {
6179 if (signature->elements[i].sysval_semantic == VKD3D_SHADER_SV_CLIP_DISTANCE)
6180 {
6182 "Clip planes cannot be used if the shader writes clip distance.");
6184 }
6185 }
6186
6187 if (!vsir_signature_find_sysval(signature, VKD3D_SHADER_SV_POSITION, 0, &position_signature_idx))
6188 {
6190 "Shader does not write position.");
6192 }
6193
6194 /* Append the clip plane signature indices. */
6195
6196 plane_count = vkd3d_popcount(mask);
6197
6198 if (!(new_elements = vkd3d_realloc(signature->elements,
6199 (signature->element_count + 2) * sizeof(*signature->elements))))
6201 signature->elements = new_elements;
6202
6203 low_signature_idx = signature->element_count;
6204 clip_element = &signature->elements[signature->element_count++];
6205 memset(clip_element, 0, sizeof(*clip_element));
6208 clip_element->register_count = 1;
6209 clip_element->mask = vkd3d_write_mask_from_component_count(min(plane_count, 4));
6210 clip_element->used_mask = clip_element->mask;
6212
6213 if (plane_count > 4)
6214 {
6215 high_signature_idx = signature->element_count;
6216 clip_element = &signature->elements[signature->element_count++];
6217 memset(clip_element, 0, sizeof(*clip_element));
6219 clip_element->semantic_index = 1;
6221 clip_element->register_count = 1;
6222 clip_element->mask = vkd3d_write_mask_from_component_count(plane_count - 4);
6223 clip_element->used_mask = clip_element->mask;
6225 }
6226
6227 /* We're going to be reading from the output position, so we need to go
6228 * through the whole shader and convert it to a temp. */
6229
6230 position_temp = program->temp_count++;
6231
6232 for (size_t i = 0; i < program->instructions.count; ++i)
6233 {
6234 ins = &program->instructions.elements[i];
6235
6236 if (vsir_instruction_is_dcl(ins))
6237 continue;
6238
6239 if (ins->opcode == VKD3DSIH_RET)
6240 {
6241 if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx,
6242 position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0)
6243 return ret;
6244 i = new_pos;
6245 continue;
6246 }
6247
6248 for (size_t j = 0; j < ins->dst_count; ++j)
6249 {
6250 struct vkd3d_shader_dst_param *dst = &ins->dst[j];
6251
6252 /* Note we run after I/O normalization. */
6253 if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == position_signature_idx)
6254 {
6255 dst->reg.type = VKD3DSPR_TEMP;
6256 dst->reg.idx[0].offset = position_temp;
6257 }
6258 }
6259 }
6260
6261 return VKD3D_OK;
6262}
static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *program, const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx, uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos)
Definition: ir.c:6082
enum vkd3d_shader_minimum_precision min_precision
enum vkd3d_shader_component_type component_type
enum vkd3d_shader_sysval_semantic sysval_semantic
enum vkd3d_shader_parameter_name name
Definition: vkd3d_shader.h:873
@ VKD3D_SHADER_SV_CLIP_DISTANCE
@ VKD3D_SHADER_SV_POSITION
@ VKD3D_SHADER_MINIMUM_PRECISION_NONE
@ VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_MASK
Definition: vkd3d_shader.h:627
@ VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC
static unsigned int vkd3d_write_mask_from_component_count(unsigned int component_count)

Referenced by vsir_program_transform().

◆ vsir_program_insert_point_coord()

static enum vkd3d_result vsir_program_insert_point_coord ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 6519 of file ir.c.

6521{
6522 const struct vkd3d_shader_parameter1 *sprite_parameter = NULL;
6523 static const struct vkd3d_shader_location no_loc;
6524 struct vkd3d_shader_instruction *ins;
6525 bool used_texcoord = false;
6526 unsigned int coord_temp;
6527 size_t i, insert_pos;
6528
6529 if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
6530 return VKD3D_OK;
6531
6532 for (i = 0; i < program->parameter_count; ++i)
6533 {
6534 const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i];
6535
6537 sprite_parameter = parameter;
6538 }
6539
6540 if (!sprite_parameter)
6541 return VKD3D_OK;
6542
6544 {
6546 "Unsupported point sprite parameter type %#x.", sprite_parameter->type);
6548 }
6549 if (sprite_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32)
6550 {
6552 "Invalid point sprite parameter data type %#x.", sprite_parameter->data_type);
6554 }
6555 if (!sprite_parameter->u.immediate_constant.u.u32)
6556 return VKD3D_OK;
6557
6558 if (!has_texcoord_signature_element(&program->input_signature))
6559 return VKD3D_OK;
6560
6561 /* VKD3DSPR_POINTCOORD is a two-component value; fill the remaining two
6562 * components with zeroes. */
6563 coord_temp = program->temp_count++;
6564
6565 /* Construct the new temp after all LABEL, DCL, and NOP instructions.
6566 * We need to skip NOP instructions because they might result from removed
6567 * DCLs, and there could still be DCLs after NOPs. */
6568 for (i = 0; i < program->instructions.count; ++i)
6569 {
6570 ins = &program->instructions.elements[i];
6571
6572 if (!vsir_instruction_is_dcl(ins) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP)
6573 break;
6574 }
6575
6576 insert_pos = i;
6577
6578 /* Replace each texcoord read with a read from the point coord. */
6579 for (; i < program->instructions.count; ++i)
6580 {
6581 ins = &program->instructions.elements[i];
6582
6583 if (vsir_instruction_is_dcl(ins))
6584 continue;
6585
6586 for (unsigned int j = 0; j < ins->src_count; ++j)
6587 {
6588 used_texcoord |= replace_texcoord_with_point_coord(program, &ins->src[j], coord_temp);
6589
6590 for (unsigned int k = 0; k < ins->src[j].reg.idx_count; ++k)
6591 {
6592 if (ins->src[j].reg.idx[k].rel_addr)
6594 ins->src[j].reg.idx[k].rel_addr, coord_temp);
6595 }
6596 }
6597
6598 for (unsigned int j = 0; j < ins->dst_count; ++j)
6599 {
6600 for (unsigned int k = 0; k < ins->dst[j].reg.idx_count; ++k)
6601 {
6602 if (ins->dst[j].reg.idx[k].rel_addr)
6604 ins->dst[j].reg.idx[k].rel_addr, coord_temp);
6605 }
6606 }
6607 }
6608
6609 if (used_texcoord)
6610 {
6611 if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2))
6613
6614 ins = &program->instructions.elements[insert_pos];
6615
6617 dst_param_init_temp_float4(&ins->dst[0], coord_temp);
6618 ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1;
6620 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
6621 ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
6622 ++ins;
6623
6625 dst_param_init_temp_float4(&ins->dst[0], coord_temp);
6626 ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
6628 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
6629 ++ins;
6630
6631 program->has_point_coord = true;
6632 }
6633
6634 return VKD3D_OK;
6635}
static bool replace_texcoord_with_point_coord(struct vsir_program *program, struct vkd3d_shader_src_param *src, unsigned int coord_temp)
Definition: ir.c:6462
static void dst_param_init_temp_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx)
Definition: ir.c:299
static bool has_texcoord_signature_element(const struct shader_signature *signature)
Definition: ir.c:6451
@ VKD3D_SHADER_PARAMETER_NAME_POINT_SPRITE
Definition: vkd3d_shader.h:736
@ VKD3DSPR_POINT_COORD
#define VKD3DSP_WRITEMASK_1
#define VKD3DSP_WRITEMASK_2

Referenced by vsir_program_transform().

◆ vsir_program_insert_point_size()

static enum vkd3d_result vsir_program_insert_point_size ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 6293 of file ir.c.

6295{
6296 const struct vkd3d_shader_parameter1 *size_parameter = NULL;
6297 static const struct vkd3d_shader_location no_loc;
6298
6299 if (program->has_point_size)
6300 return VKD3D_OK;
6301
6302 if (!is_pre_rasterization_shader(program->shader_version.type))
6303 return VKD3D_OK;
6304
6305 for (unsigned int i = 0; i < program->parameter_count; ++i)
6306 {
6307 const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i];
6308
6310 size_parameter = parameter;
6311 }
6312
6313 if (!size_parameter)
6314 return VKD3D_OK;
6315
6317 {
6319 "Invalid point size parameter data type %#x.", size_parameter->data_type);
6321 }
6322
6323 program->has_point_size = true;
6324
6325 /* Append a point size write before each ret. */
6326 for (size_t i = 0; i < program->instructions.count; ++i)
6327 {
6328 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
6329
6330 if (ins->opcode == VKD3DSIH_RET)
6331 {
6332 size_t new_pos;
6333 int ret;
6334
6335 if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0)
6336 return ret;
6337 i = new_pos;
6338 }
6339 }
6340
6341 return VKD3D_OK;
6342}
static bool is_pre_rasterization_shader(enum vkd3d_shader_type type)
Definition: ir.c:6264
static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program, const struct vkd3d_shader_instruction *ret, size_t *ret_pos)
Definition: ir.c:6272

Referenced by vsir_program_transform().

◆ vsir_program_insert_point_size_clamp()

static enum vkd3d_result vsir_program_insert_point_size_clamp ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 6344 of file ir.c.

6346{
6347 const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL;
6348 static const struct vkd3d_shader_location no_loc;
6349
6350 if (!program->has_point_size)
6351 return VKD3D_OK;
6352
6353 if (!is_pre_rasterization_shader(program->shader_version.type))
6354 return VKD3D_OK;
6355
6356 for (unsigned int i = 0; i < program->parameter_count; ++i)
6357 {
6358 const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i];
6359
6361 min_parameter = parameter;
6362 else if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX)
6363 max_parameter = parameter;
6364 }
6365
6366 if (!min_parameter && !max_parameter)
6367 return VKD3D_OK;
6368
6369 if (min_parameter && min_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32)
6370 {
6372 "Invalid minimum point size parameter data type %#x.", min_parameter->data_type);
6374 }
6375
6376 if (max_parameter && max_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32)
6377 {
6379 "Invalid maximum point size parameter data type %#x.", max_parameter->data_type);
6381 }
6382
6383 /* Replace writes to the point size by inserting a clamp before each write. */
6384
6385 for (size_t i = 0; i < program->instructions.count; ++i)
6386 {
6387 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
6388 const struct vkd3d_shader_location *loc;
6389 unsigned int ssa_value;
6390 bool clamp = false;
6391
6392 if (vsir_instruction_is_dcl(ins))
6393 continue;
6394
6395 for (size_t j = 0; j < ins->dst_count; ++j)
6396 {
6397 struct vkd3d_shader_dst_param *dst = &ins->dst[j];
6398
6399 /* Note we run after I/O normalization. */
6400 if (dst->reg.type == VKD3DSPR_RASTOUT)
6401 {
6403 ssa_value = program->ssa_count++;
6404 clamp = true;
6405 }
6406 }
6407
6408 if (!clamp)
6409 continue;
6410
6411 if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter))
6413
6414 loc = &program->instructions.elements[i].location;
6415 ins = &program->instructions.elements[i + 1];
6416
6417 if (min_parameter)
6418 {
6420 src_param_init_ssa_float(&ins->src[0], ssa_value);
6422 if (max_parameter)
6423 {
6424 dst_param_init_ssa_float(&ins->dst[0], program->ssa_count);
6425 ssa_value = program->ssa_count++;
6426 }
6427 else
6428 {
6430 ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
6431 }
6432 ++ins;
6433 ++i;
6434 }
6435
6436 if (max_parameter)
6437 {
6439 src_param_init_ssa_float(&ins->src[0], ssa_value);
6442 ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
6443
6444 ++i;
6445 }
6446 }
6447
6448 return VKD3D_OK;
6449}
GLenum clamp
Definition: glext.h:6216
static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigned int idx)
Definition: ir.c:287
static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigned int idx)
Definition: ir.c:240
@ VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX
Definition: vkd3d_shader.h:703
@ VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN
Definition: vkd3d_shader.h:693
@ VKD3DSIH_MIN
@ VKD3DSIH_MAX

Referenced by vsir_program_transform().

◆ vsir_program_lower_ifc()

static enum vkd3d_result vsir_program_lower_ifc ( struct vsir_program *  program,
struct vkd3d_shader_instruction *  ifc,
unsigned int *  tmp_idx,
struct vkd3d_shader_message_context *  message_context 
)
static

Definition at line 431 of file ir.c.

434{
435 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
436 size_t pos = ifc - instructions->elements;
437 struct vkd3d_shader_instruction *ins;
439 bool swap;
440
441 if (!shader_instruction_array_insert_at(instructions, pos + 1, 2))
443
444 if (*tmp_idx == ~0u)
445 *tmp_idx = program->temp_count++;
446
447 /* Replace ifc comparison with actual comparison, saving the result in the tmp register. */
448 if (!(get_opcode_from_rel_op(ifc->flags, ifc->src[0].reg.data_type, &opcode, &swap)))
449 {
451 "Aborting due to not yet implemented feature: opcode for rel_op %u and data type %u.",
452 ifc->flags, ifc->src[0].reg.data_type);
454 }
455
456 ins = &instructions->elements[pos + 1];
459
461 ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
462 ins->dst[0].reg.idx[0].offset = *tmp_idx;
463 ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
464
465 ins->src[0] = ifc->src[swap];
466 ins->src[1] = ifc->src[!swap];
467
468 /* Create new if instruction using the previous result. */
469 ins = &instructions->elements[pos + 2];
473
475 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
476 ins->src[0].reg.idx[0].offset = *tmp_idx;
477 ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
478
479 /* Make the original instruction no-op */
481
482 return VKD3D_OK;
483}
static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap)
Definition: ir.c:385
@ VKD3D_SHADER_CONDITIONAL_OP_NZ

Referenced by vsir_program_lower_instructions().

◆ vsir_program_lower_instructions()

static enum vkd3d_result vsir_program_lower_instructions ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 712 of file ir.c.

714{
715 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
716 struct vkd3d_shader_message_context *message_context = ctx->message_context;
717 unsigned int tmp_idx = ~0u, i;
718 enum vkd3d_result ret;
719
720 for (i = 0; i < instructions->count; ++i)
721 {
722 struct vkd3d_shader_instruction *ins = &instructions->elements[i];
723
724 switch (ins->opcode)
725 {
726 case VKD3DSIH_IFC:
727 if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0)
728 return ret;
729 break;
730
731 case VKD3DSIH_TEXKILL:
732 if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0)
733 return ret;
734 break;
735
736 case VKD3DSIH_MAD:
737 if ((ret = vsir_program_lower_precise_mad(program, ins, &tmp_idx)) < 0)
738 return ret;
739 break;
740
741 case VKD3DSIH_DCL:
749 break;
750
751 case VKD3DSIH_SINCOS:
752 if ((ret = vsir_program_lower_sm1_sincos(program, ins)) < 0)
753 return ret;
754 break;
755
756 case VKD3DSIH_TEX:
757 if ((ret = vsir_program_lower_tex(program, ins)) < 0)
758 return ret;
759 break;
760
761 case VKD3DSIH_TEXLDD:
762 if ((ret = vsir_program_lower_texldd(program, ins)) < 0)
763 return ret;
764 break;
765
766 case VKD3DSIH_TEXBEM:
767 case VKD3DSIH_TEXBEML:
770 case VKD3DSIH_TEXDP3:
772 case VKD3DSIH_TEXLDL:
784 "Aborting due to unimplemented feature: Combined sampler instruction %#x.",
785 ins->opcode);
787
788 default:
789 break;
790 }
791 }
792
793 return VKD3D_OK;
794}
static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *program, struct vkd3d_shader_instruction *mad, unsigned int *tmp_idx)
Definition: ir.c:569
static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *tex)
Definition: ir.c:665
static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx, struct vkd3d_shader_message_context *message_context)
Definition: ir.c:431
static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, struct vkd3d_shader_instruction *sincos)
Definition: ir.c:613
static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program, struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx)
Definition: ir.c:485
static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, struct vkd3d_shader_instruction *texldd)
Definition: ir.c:687
@ VKD3DSIH_TEXM3x3SPEC
@ VKD3DSIH_TEXREG2RGB
@ VKD3DSIH_TEXDP3TEX
@ VKD3DSIH_TEX
@ VKD3DSIH_TEXM3x3PAD
@ VKD3DSIH_TEXDP3
@ VKD3DSIH_TEXREG2AR
@ VKD3DSIH_TEXM3x3DIFF
@ VKD3DSIH_TEXM3x2PAD
@ VKD3DSIH_TEXKILL
@ VKD3DSIH_TEXCOORD
@ VKD3DSIH_DCL_SAMPLER
@ VKD3DSIH_TEXREG2GB
@ VKD3DSIH_TEXBEM
@ VKD3DSIH_IFC
@ VKD3DSIH_DCL_GLOBAL_FLAGS
@ VKD3DSIH_TEXM3x2TEX
@ VKD3DSIH_DCL_TEMPS
@ VKD3DSIH_TEXLDD
@ VKD3DSIH_DCL_THREAD_GROUP
@ VKD3DSIH_TEXM3x3VSPEC
@ VKD3DSIH_MAD
@ VKD3DSIH_TEXDEPTH
@ VKD3DSIH_TEXBEML
@ VKD3DSIH_TEXLDL
@ VKD3DSIH_DCL_UAV_TYPED
@ VKD3DSIH_TEXM3x3TEX
@ VKD3DSIH_DCL_CONSTANT_BUFFER
@ VKD3DSIH_SINCOS

Referenced by vsir_program_transform().

◆ vsir_program_lower_precise_mad()

static enum vkd3d_result vsir_program_lower_precise_mad ( struct vsir_program *  program,
struct vkd3d_shader_instruction *  mad,
unsigned int *  tmp_idx 
)
static

Definition at line 569 of file ir.c.

571{
572 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
573 struct vkd3d_shader_instruction *mul_ins, *add_ins;
574 size_t pos = mad - instructions->elements;
575 struct vkd3d_shader_dst_param *mul_dst;
576
577 if (!(mad->flags & VKD3DSI_PRECISE_XYZW))
578 return VKD3D_OK;
579
580 if (!shader_instruction_array_insert_at(instructions, pos + 1, 1))
582
583 if (*tmp_idx == ~0u)
584 *tmp_idx = program->temp_count++;
585
586 mul_ins = &instructions->elements[pos];
587 add_ins = &instructions->elements[pos + 1];
588
589 mul_ins->opcode = VKD3DSIH_MUL;
590 mul_ins->src_count = 2;
591
592 if (!(vsir_instruction_init_with_params(program, add_ins, &mul_ins->location, VKD3DSIH_ADD, 1, 2)))
594
595 add_ins->flags = mul_ins->flags & VKD3DSI_PRECISE_XYZW;
596
597 mul_dst = mul_ins->dst;
598 *add_ins->dst = *mul_dst;
599
600 mul_dst->modifiers = 0;
601 vsir_register_init(&mul_dst->reg, VKD3DSPR_TEMP, mul_ins->src[0].reg.data_type, 1);
602 mul_dst->reg.dimension = add_ins->dst->reg.dimension;
603 mul_dst->reg.idx[0].offset = *tmp_idx;
604
605 add_ins->src[0].reg = mul_dst->reg;
606 add_ins->src[0].swizzle = vsir_swizzle_from_writemask(mul_dst->write_mask);
607 add_ins->src[0].modifiers = 0;
608 add_ins->src[1] = mul_ins->src[2];
609
610 return VKD3D_OK;
611}
#define VKD3DSI_PRECISE_XYZW
static uint32_t vsir_swizzle_from_writemask(unsigned int writemask)
@ VKD3DSIH_MUL
@ VKD3DSIH_ADD

Referenced by vsir_program_lower_instructions().

◆ vsir_program_lower_sm1_sincos()

static enum vkd3d_result vsir_program_lower_sm1_sincos ( struct vsir_program *  program,
struct vkd3d_shader_instruction *  sincos 
)
static

Definition at line 613 of file ir.c.

615{
616 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
617 size_t pos = sincos - instructions->elements;
618 struct vkd3d_shader_instruction *ins;
619 unsigned int s;
620
621 if (sincos->dst_count != 1)
622 return VKD3D_OK;
623
624 if (!shader_instruction_array_insert_at(instructions, pos + 1, 1))
626
627 ins = &instructions->elements[pos + 1];
628
629 if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VKD3DSIH_SINCOS, 2, 1)))
631
632 ins->flags = sincos->flags;
633
634 *ins->src = *sincos->src;
635 /* Set the source swizzle to replicate the first component. */
636 s = vsir_swizzle_get_component(sincos->src->swizzle, 0);
637 ins->src->swizzle = vkd3d_shader_create_swizzle(s, s, s, s);
638
639 if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_1)
640 {
641 ins->dst[0] = *sincos->dst;
642 ins->dst[0].write_mask = VKD3DSP_WRITEMASK_1;
643 }
644 else
645 {
647 }
648
649 if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0)
650 {
651 ins->dst[1] = *sincos->dst;
652 ins->dst[1].write_mask = VKD3DSP_WRITEMASK_0;
653 }
654 else
655 {
657 }
658
659 /* Make the original instruction no-op */
661
662 return VKD3D_OK;
663}
void sincos(double x, double *s, double *c)
Definition: sincos.c:30
static uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_component x, enum vkd3d_shader_swizzle_component y, enum vkd3d_shader_swizzle_component z, enum vkd3d_shader_swizzle_component w)

Referenced by vsir_program_lower_instructions().

◆ vsir_program_lower_switch_to_selection_ladder()

static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 3205 of file ir.c.

3207{
3208 unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label;
3209 size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0;
3210 struct vkd3d_shader_instruction *instructions = NULL;
3212
3213 VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
3214
3215 if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count))
3216 goto fail;
3217
3218 /* First subpass: convert SWITCH_MONOLITHIC instructions to
3219 * selection ladders, keeping a map between blocks before and
3220 * after the subpass. */
3221 for (i = 0; i < program->instructions.count; ++i)
3222 {
3223 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
3224 unsigned int case_count, j, default_label;
3225
3226 switch (ins->opcode)
3227 {
3228 case VKD3DSIH_LABEL:
3229 current_label = label_from_src_param(&ins->src[0]);
3230 if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
3231 goto fail;
3232 instructions[ins_count++] = *ins;
3233 continue;
3234
3236 break;
3237
3238 default:
3239 if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
3240 goto fail;
3241 instructions[ins_count++] = *ins;
3242 continue;
3243 }
3244
3245 case_count = (ins->src_count - 3) / 2;
3246 default_label = label_from_src_param(&ins->src[1]);
3247
3248 /* In principle we can have a switch with no cases, and we
3249 * just have to jump to the default label. */
3250 if (case_count == 0)
3251 {
3252 if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
3253 goto fail;
3254
3255 if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
3256 &ins->location, VKD3DSIH_BRANCH, 0, 1))
3257 goto fail;
3258 vsir_src_param_init_label(&instructions[ins_count].src[0], default_label);
3259 ++ins_count;
3260 }
3261
3262 if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3 * case_count - 1))
3263 goto fail;
3264
3265 if_label = current_label;
3266
3267 for (j = 0; j < case_count; ++j)
3268 {
3269 unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]);
3270
3272 &instructions[ins_count], &ins->location, VKD3DSIH_IEQ, 1, 2))
3273 goto fail;
3274 dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count);
3275 instructions[ins_count].src[0] = ins->src[0];
3276 instructions[ins_count].src[1] = ins->src[3 + 2 * j];
3277 ++ins_count;
3278
3279 /* For all cases except the last one we fall through to
3280 * the following case; the last one has to jump to the
3281 * default label. */
3282 if (j == case_count - 1)
3283 fallthrough_label = default_label;
3284 else
3285 fallthrough_label = block_count + 1;
3286
3287 if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
3288 &ins->location, VKD3DSIH_BRANCH, 0, 3))
3289 goto fail;
3290 src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count);
3291 vsir_src_param_init_label(&instructions[ins_count].src[1], case_label);
3292 vsir_src_param_init_label(&instructions[ins_count].src[2], fallthrough_label);
3293 ++ins_count;
3294
3295 ++ssa_count;
3296
3297 if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count,
3298 current_label, if_label, case_label))
3299 goto fail;
3300
3301 if (j == case_count - 1)
3302 {
3303 if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count,
3304 current_label, if_label, default_label))
3305 goto fail;
3306 }
3307 else
3308 {
3310 &instructions[ins_count], &ins->location, VKD3DSIH_LABEL, 0, 1))
3311 goto fail;
3312 vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count);
3313 ++ins_count;
3314
3315 if_label = block_count;
3316 }
3317 }
3318 }
3319
3320 vkd3d_free(program->instructions.elements);
3321 vkd3d_free(block_map);
3322 program->instructions.elements = instructions;
3323 program->instructions.capacity = ins_capacity;
3324 program->instructions.count = ins_count;
3325 program->block_count = block_count;
3326 program->ssa_count = ssa_count;
3327
3328 return VKD3D_OK;
3329
3330fail:
3331 vkd3d_free(instructions);
3332 vkd3d_free(block_map);
3333
3335}
static bool lower_switch_to_if_ladder_add_block_mapping(struct lower_switch_to_if_ladder_block_mapping **block_map, size_t *map_capacity, size_t *map_count, unsigned int switch_label, unsigned int if_label, unsigned int target_label)
Definition: ir.c:3187

Referenced by vsir_program_transform().

◆ vsir_program_lower_tex()

static enum vkd3d_result vsir_program_lower_tex ( struct vsir_program *  program,
struct vkd3d_shader_instruction *  tex 
)
static

Definition at line 665 of file ir.c.

666{
667 unsigned int idx = tex->src[1].reg.idx[0].offset;
668 struct vkd3d_shader_src_param *srcs;
669
670 VKD3D_ASSERT(tex->src[1].reg.idx_count == 1);
671 VKD3D_ASSERT(!tex->src[1].reg.idx[0].rel_addr);
672
673 if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3)))
675
676 srcs[0] = tex->src[0];
679
680 tex->opcode = VKD3DSIH_SAMPLE;
681 tex->src = srcs;
682 tex->src_count = 3;
683
684 return VKD3D_OK;
685}
static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
Definition: ir.c:226
static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
Definition: ir.c:217
@ VKD3DSIH_SAMPLE

Referenced by vsir_program_lower_instructions().

◆ vsir_program_lower_texkill()

static enum vkd3d_result vsir_program_lower_texkill ( struct vsir_program *  program,
struct vkd3d_shader_instruction *  texkill,
unsigned int *  tmp_idx 
)
static

Definition at line 485 of file ir.c.

487{
488 const unsigned int components_read = 3 + (program->shader_version.major >= 2);
489 struct vkd3d_shader_instruction_array *instructions = &program->instructions;
490 size_t pos = texkill - instructions->elements;
491 struct vkd3d_shader_instruction *ins;
492 unsigned int j;
493
494 if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1))
496
497 if (*tmp_idx == ~0u)
498 *tmp_idx = program->temp_count++;
499
500 /* tmp = ins->dst[0] < 0 */
501
502 ins = &instructions->elements[pos + 1];
505
507 ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
508 ins->dst[0].reg.idx[0].offset = *tmp_idx;
509 ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
510
511 ins->src[0].reg = texkill->dst[0].reg;
512 ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
514 ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
515 ins->src[1].reg.u.immconst_f32[0] = 0.0f;
516 ins->src[1].reg.u.immconst_f32[1] = 0.0f;
517 ins->src[1].reg.u.immconst_f32[2] = 0.0f;
518 ins->src[1].reg.u.immconst_f32[3] = 0.0f;
519
520 /* tmp.x = tmp.x || tmp.y */
521 /* tmp.x = tmp.x || tmp.z */
522 /* tmp.x = tmp.x || tmp.w, if sm >= 2.0 */
523
524 for (j = 1; j < components_read; ++j)
525 {
526 ins = &instructions->elements[pos + 1 + j];
527 if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_OR, 1, 2)))
529
531 ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
532 ins->dst[0].reg.idx[0].offset = *tmp_idx;
533 ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
534
536 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
537 ins->src[0].reg.idx[0].offset = *tmp_idx;
538 ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
540 ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
541 ins->src[1].reg.idx[0].offset = *tmp_idx;
542 ins->src[1].swizzle = vkd3d_shader_create_swizzle(j, j, j, j);
543 }
544
545 /* discard_nz tmp.x */
546
547 ins = &instructions->elements[pos + 1 + components_read];
551
553 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
554 ins->src[0].reg.idx[0].offset = *tmp_idx;
555 ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
556
557 /* Make the original instruction no-op */
559
560 return VKD3D_OK;
561}
@ VKD3DSIH_OR

Referenced by vsir_program_lower_instructions().

◆ vsir_program_lower_texldd()

static enum vkd3d_result vsir_program_lower_texldd ( struct vsir_program *  program,
struct vkd3d_shader_instruction *  texldd 
)
static

Definition at line 687 of file ir.c.

689{
690 unsigned int idx = texldd->src[1].reg.idx[0].offset;
691 struct vkd3d_shader_src_param *srcs;
692
693 VKD3D_ASSERT(texldd->src[1].reg.idx_count == 1);
694 VKD3D_ASSERT(!texldd->src[1].reg.idx[0].rel_addr);
695
696 if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 5)))
698
699 srcs[0] = texldd->src[0];
702 srcs[3] = texldd->src[2];
703 srcs[4] = texldd->src[3];
704
706 texldd->src = srcs;
707 texldd->src_count = 5;
708
709 return VKD3D_OK;
710}
@ VKD3DSIH_SAMPLE_GRAD

Referenced by vsir_program_lower_instructions().

◆ vsir_program_materialise_phi_ssas_to_temps()

static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 3398 of file ir.c.

3400{
3401 size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i;
3402 struct ssas_to_temps_block_info *info, *block_info = NULL;
3403 struct vkd3d_shader_instruction *instructions = NULL;
3404 struct ssas_to_temps_alloc alloc = {0};
3405 unsigned int current_label = 0;
3406
3407 VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
3408
3409 if (!(block_info = vkd3d_calloc(program->block_count, sizeof(*block_info))))
3410 {
3411 ERR("Failed to allocate block info array.\n");
3412 goto fail;
3413 }
3414
3415 if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count))
3416 goto fail;
3417
3418 for (i = 0, phi_count = 0, incoming_count = 0; i < program->instructions.count; ++i)
3419 {
3420 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
3421 unsigned int j, temp_idx;
3422
3423 /* Only phi src/dst SSA values need be converted here. Structurisation may
3424 * introduce new cases of undominated SSA use, which will be handled later. */
3425 if (ins->opcode != VKD3DSIH_PHI)
3426 continue;
3427 ++phi_count;
3428
3429 temp_idx = alloc.next_temp_idx++;
3430
3431 for (j = 0; j < ins->src_count; j += 2)
3432 {
3433 struct phi_incoming_to_temp *incoming;
3434 unsigned int label;
3435
3436 label = label_from_src_param(&ins->src[j + 1]);
3438
3439 info = &block_info[label - 1];
3440
3441 if (!(vkd3d_array_reserve((void **)&info->incomings, &info->incoming_capacity, info->incoming_count + 1,
3442 sizeof(*info->incomings))))
3443 goto fail;
3444
3445 incoming = &info->incomings[info->incoming_count++];
3446 incoming->src = &ins->src[j];
3447 incoming->dst = ins->dst;
3448
3449 alloc.table[ins->dst->reg.idx[0].offset] = temp_idx;
3450
3451 ++incoming_count;
3452 }
3453
3455 }
3456
3457 if (!phi_count)
3458 goto done;
3459
3460 if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count))
3461 goto fail;
3462
3463 for (i = 0; i < program->instructions.count; ++i)
3464 {
3465 struct vkd3d_shader_instruction *mov_ins, *ins = &program->instructions.elements[i];
3466 size_t j;
3467
3468 for (j = 0; j < ins->dst_count; ++j)
3470
3471 for (j = 0; j < ins->src_count; ++j)
3473
3474 switch (ins->opcode)
3475 {
3476 case VKD3DSIH_LABEL:
3477 current_label = label_from_src_param(&ins->src[0]);
3478 break;
3479
3480 case VKD3DSIH_BRANCH:
3482 info = &block_info[current_label - 1];
3483
3484 for (j = 0; j < info->incoming_count; ++j)
3485 {
3486 struct phi_incoming_to_temp *incoming = &info->incomings[j];
3487
3488 mov_ins = &instructions[ins_count++];
3490 goto fail;
3491 *mov_ins->dst = *incoming->dst;
3492 mov_ins->src = incoming->src;
3493 mov_ins->src_count = 1;
3494 }
3495 break;
3496
3497 case VKD3DSIH_PHI:
3498 continue;
3499
3500 default:
3501 break;
3502 }
3503
3504 instructions[ins_count++] = *ins;
3505 }
3506
3507 vkd3d_free(program->instructions.elements);
3508 program->instructions.elements = instructions;
3509 program->instructions.capacity = ins_capacity;
3510 program->instructions.count = ins_count;
3511 program->temp_count = alloc.next_temp_idx;
3512done:
3513 ssas_to_temps_block_info_cleanup(block_info, program->block_count);
3514 vkd3d_free(alloc.table);
3515
3516 return VKD3D_OK;
3517
3518fail:
3519 vkd3d_free(instructions);
3520 ssas_to_temps_block_info_cleanup(block_info, program->block_count);
3521 vkd3d_free(alloc.table);
3522
3524}
static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *block_info, size_t count)
Definition: ir.c:3387

Referenced by vsir_program_transform().

◆ vsir_program_materialize_undominated_ssas_to_temps()

static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 5805 of file ir.c.

5807{
5808 struct vkd3d_shader_message_context *message_context = ctx->message_context;
5809 enum vkd3d_result ret;
5810 size_t i;
5811
5812 VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
5813
5814 for (i = 0; i < program->instructions.count;)
5815 {
5816 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
5817
5818 switch (ins->opcode)
5819 {
5820 case VKD3DSIH_LABEL:
5821 VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL);
5822 TRACE("Materializing undominated SSAs in a non-hull shader.\n");
5824 program, message_context, &i)) < 0)
5825 return ret;
5826 VKD3D_ASSERT(i == program->instructions.count);
5827 break;
5828
5832 VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
5833 TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->opcode);
5834 ++i;
5836 program, message_context, &i)) < 0)
5837 return ret;
5838 break;
5839
5840 default:
5841 ++i;
5842 break;
5843 }
5844 }
5845
5846 return VKD3D_OK;
5847}
static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function(struct vsir_program *program, struct vkd3d_shader_message_context *message_context, size_t *pos)
Definition: ir.c:5786

Referenced by vsir_program_transform().

◆ vsir_program_materialize_undominated_ssas_to_temps_in_function()

static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function ( struct vsir_program *  program,
struct vkd3d_shader_message_context *  message_context,
size_t *  pos 
)
static

Definition at line 5786 of file ir.c.

5789{
5790 enum vkd3d_result ret;
5791 struct vsir_cfg cfg;
5792
5793 if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, pos)) < 0)
5794 return ret;
5795
5797
5799
5800 vsir_cfg_cleanup(&cfg);
5801
5802 return ret;
5803}
static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program *program, struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, size_t *pos)
Definition: ir.c:4017
static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct vsir_cfg *cfg)
Definition: ir.c:5710
static void vsir_cfg_compute_dominators(struct vsir_cfg *cfg)
Definition: ir.c:4162
Definition: ir.c:3769

Referenced by vsir_program_materialize_undominated_ssas_to_temps().

◆ vsir_program_normalise_flat_constants()

static enum vkd3d_result vsir_program_normalise_flat_constants ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 2365 of file ir.c.

2367{
2368 struct flat_constants_normaliser normaliser = {0};
2369 unsigned int i, j;
2370
2371 for (i = 0; i < program->instructions.count; ++i)
2372 {
2373 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
2374
2375 if (ins->opcode == VKD3DSIH_DEF || ins->opcode == VKD3DSIH_DEFI || ins->opcode == VKD3DSIH_DEFB)
2376 {
2377 struct flat_constant_def *def;
2378
2379 if (!vkd3d_array_reserve((void **)&normaliser.defs, &normaliser.defs_capacity,
2380 normaliser.def_count + 1, sizeof(*normaliser.defs)))
2381 {
2382 vkd3d_free(normaliser.defs);
2384 }
2385
2386 def = &normaliser.defs[normaliser.def_count++];
2387
2388 get_flat_constant_register_type((struct vkd3d_shader_register *)&ins->dst[0].reg, &def->set, &def->index);
2389 for (j = 0; j < 4; ++j)
2390 def->value[j] = ins->src[0].reg.u.immconst_u32[j];
2391
2393 }
2394 else
2395 {
2396 for (j = 0; j < ins->src_count; ++j)
2397 shader_register_normalise_flat_constants(&ins->src[j], &normaliser);
2398 }
2399 }
2400
2401 vkd3d_free(normaliser.defs);
2402 return VKD3D_OK;
2403}
static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_param *param, const struct flat_constants_normaliser *normaliser)
Definition: ir.c:2335
uint32_t value[4]
Definition: ir.c:2286
uint32_t index
Definition: ir.c:2285
enum vkd3d_shader_d3dbc_constant_register set
Definition: ir.c:2284
@ VKD3DSIH_DEFB
@ VKD3DSIH_DEF
@ VKD3DSIH_DEFI

Referenced by vsir_program_transform().

◆ vsir_program_normalise_io_registers()

static enum vkd3d_result vsir_program_normalise_io_registers ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 2225 of file ir.c.

2227{
2228 struct io_normaliser normaliser = {program->instructions};
2229 struct vkd3d_shader_instruction *ins;
2230 unsigned int i;
2231
2233
2234 normaliser.phase = VKD3DSIH_INVALID;
2235 normaliser.shader_type = program->shader_version.type;
2236 normaliser.major = program->shader_version.major;
2237 normaliser.input_signature = &program->input_signature;
2238 normaliser.output_signature = &program->output_signature;
2239 normaliser.patch_constant_signature = &program->patch_constant_signature;
2240
2241 for (i = 0; i < program->instructions.count; ++i)
2242 {
2243 ins = &program->instructions.elements[i];
2244
2245 switch (ins->opcode)
2246 {
2249 break;
2251 io_normaliser_add_index_range(&normaliser, ins);
2253 break;
2257 normaliser.phase = ins->opcode;
2258 break;
2259 default:
2260 break;
2261 }
2262 }
2263
2264 if (!shader_signature_merge(&program->input_signature, normaliser.input_range_map, false)
2265 || !shader_signature_merge(&program->output_signature, normaliser.output_range_map, false)
2266 || !shader_signature_merge(&program->patch_constant_signature, normaliser.pc_range_map, true))
2267 {
2268 program->instructions = normaliser.instructions;
2270 }
2271
2272 normaliser.phase = VKD3DSIH_INVALID;
2273 for (i = 0; i < normaliser.instructions.count; ++i)
2274 shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser);
2275
2276 program->instructions = normaliser.instructions;
2277 program->use_vocp = normaliser.use_vocp;
2278 program->normalisation_level = VSIR_FULLY_NORMALISED_IO;
2279 return VKD3D_OK;
2280}
static void shader_instruction_normalise_io_params(struct vkd3d_shader_instruction *ins, struct io_normaliser *normaliser)
Definition: ir.c:2169
static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map[][VKD3D_VEC4_SIZE], bool is_patch_constant)
Definition: ir.c:1812
static void io_normaliser_add_index_range(struct io_normaliser *normaliser, const struct vkd3d_shader_instruction *ins)
Definition: ir.c:1630
struct vkd3d_shader_instruction_array instructions
Definition: ir.c:1519
@ VSIR_FULLY_NORMALISED_IO
@ VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT
@ VKD3DSIH_DCL_INDEX_RANGE

Referenced by vsir_program_transform().

◆ vsir_program_remap_output_signature()

static enum vkd3d_result vsir_program_remap_output_signature ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 1007 of file ir.c.

1009{
1010 const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name};
1011 struct vkd3d_shader_message_context *message_context = ctx->message_context;
1012 const struct vkd3d_shader_compile_info *compile_info = ctx->compile_info;
1013 bool allows_subset_masks = target_allows_subset_masks(compile_info);
1014 struct shader_signature *signature = &program->output_signature;
1015 unsigned int orig_element_count = signature->element_count;
1017 struct signature_element *new_elements, *e;
1018 unsigned int uninit_varying_count = 0;
1019 unsigned int subset_varying_count = 0;
1020 unsigned int new_register_count = 0;
1021 unsigned int i;
1022
1023 if (!(varying_map = vkd3d_find_struct(compile_info->next, VARYING_MAP_INFO)))
1024 return VKD3D_OK;
1025
1026 for (i = 0; i < signature->element_count; ++i)
1027 {
1028 const struct vkd3d_shader_varying_map *map = find_varying_map(varying_map, i);
1029
1030 e = &signature->elements[i];
1031 if (map)
1032 {
1033 unsigned int input_mask = map->input_mask;
1034
1035 e->target_location = map->input_register_index;
1036
1037 if ((input_mask & e->mask) == input_mask)
1038 {
1039 ++subset_varying_count;
1040 if (!allows_subset_masks)
1041 {
1042 e->mask = input_mask;
1043 e->used_mask &= input_mask;
1044 }
1045 }
1046 else if (input_mask && input_mask != e->mask)
1047 {
1049 "Aborting due to not yet implemented feature: "
1050 "Input mask %#x reads components not written in output mask %#x.",
1051 input_mask, e->mask);
1053 }
1054 }
1055 else
1056 {
1057 e->target_location = SIGNATURE_TARGET_LOCATION_UNUSED;
1058 }
1059
1060 new_register_count = max(new_register_count, e->register_index + 1);
1061 }
1062
1063 /* Handle uninitialized varyings by writing them before every ret.
1064 *
1065 * As far as sm1-sm3 is concerned, drivers disagree on what uninitialized
1066 * varyings contain.
1067 *
1068 * - Diffuse (COLOR0) reliably contains (1, 1, 1, 1) in SM1/2.
1069 * In SM3 it may contain (0, 0, 0, 0), (0, 0, 0, 1), or (1, 1, 1, 1).
1070 *
1071 * - Specular (COLOR1) contains (0, 0, 0, 0) or (0, 0, 0, 1).
1072 * WARP writes (1, 1, 1, 1).
1073 *
1074 * - Anything else contains (0, 0, 0, 0) or (0, 0, 0, 1).
1075 *
1076 * We don't have enough knowledge to identify diffuse here. Instead we deal
1077 * with that in vsir_program_ensure_diffuse(), by always writing diffuse if
1078 * the shader doesn't.
1079 */
1080
1081 for (i = 0; i < varying_map->varying_count; ++i)
1082 {
1083 if (varying_map->varying_map[i].output_signature_index >= signature->element_count)
1084 ++uninit_varying_count;
1085 }
1086
1087 if (!(new_elements = vkd3d_realloc(signature->elements,
1088 (signature->element_count + uninit_varying_count) * sizeof(*signature->elements))))
1090 signature->elements = new_elements;
1091
1092 for (i = 0; i < varying_map->varying_count; ++i)
1093 {
1094 const struct vkd3d_shader_varying_map *map = &varying_map->varying_map[i];
1095
1096 if (map->output_signature_index < orig_element_count)
1097 continue;
1098
1099 TRACE("Synthesizing zero value for uninitialized output %u (mask %u).\n",
1100 map->input_register_index, map->input_mask);
1101 e = &signature->elements[signature->element_count++];
1102 memset(e, 0, sizeof(*e));
1103 e->sysval_semantic = VKD3D_SHADER_SV_NONE;
1104 e->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
1105 e->register_count = 1;
1106 e->mask = map->input_mask;
1107 e->used_mask = map->input_mask;
1108 e->register_index = new_register_count++;
1109 e->target_location = map->input_register_index;
1110 e->interpolation_mode = VKD3DSIM_LINEAR;
1111 }
1112
1113 /* Write each uninitialized varying before each ret. */
1114 for (i = 0; i < program->instructions.count; ++i)
1115 {
1116 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
1117 struct vkd3d_shader_location loc;
1118
1119 if (ins->opcode != VKD3DSIH_RET)
1120 continue;
1121
1122 loc = ins->location;
1123 if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count))
1125
1126 ins = &program->instructions.elements[i];
1127
1128 for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j)
1129 {
1130 e = &signature->elements[j];
1131
1133 dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, e->register_index, e->mask);
1135 ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
1136 ++ins;
1137 }
1138
1139 i += uninit_varying_count;
1140 }
1141
1142 /* Vulkan (without KHR_maintenance4) disallows any mismatching masks,
1143 * including when the input mask is a proper subset of the output mask.
1144 * Resolve this by rewriting the shader to remove unread components from
1145 * any writes to the output variable. */
1146
1147 if (!subset_varying_count || allows_subset_masks)
1148 return VKD3D_OK;
1149
1150 for (i = 0; i < program->instructions.count; ++i)
1151 {
1152 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
1153
1154 for (unsigned int j = 0; j < ins->dst_count; ++j)
1156 }
1157
1158 return VKD3D_OK;
1159}
Definition: _map.h:48
static bool target_allows_subset_masks(const struct vkd3d_shader_compile_info *info)
Definition: ir.c:939
static const struct vkd3d_shader_varying_map * find_varying_map(const struct vkd3d_shader_varying_map_info *varying_map, unsigned int signature_idx)
Definition: ir.c:925
static void remove_unread_output_components(const struct shader_signature *signature, struct vkd3d_shader_instruction *ins, struct vkd3d_shader_dst_param *dst)
Definition: ir.c:970
static void dst_param_init_output(struct vkd3d_shader_dst_param *dst, enum vkd3d_data_type data_type, uint32_t idx, uint32_t write_mask)
Definition: ir.c:312
@ VKD3DSIM_LINEAR
#define SIGNATURE_TARGET_LOCATION_UNUSED

Referenced by vsir_program_transform().

◆ vsir_program_remove_dead_code()

static enum vkd3d_result vsir_program_remove_dead_code ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 2405 of file ir.c.

2407{
2408 size_t i, depth = 0;
2409 bool dead = false;
2410
2411 for (i = 0; i < program->instructions.count; ++i)
2412 {
2413 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
2414
2415 switch (ins->opcode)
2416 {
2417 case VKD3DSIH_IF:
2418 case VKD3DSIH_LOOP:
2419 case VKD3DSIH_SWITCH:
2420 if (dead)
2421 {
2423 ++depth;
2424 }
2425 break;
2426
2427 case VKD3DSIH_ENDIF:
2428 case VKD3DSIH_ENDLOOP:
2429 case VKD3DSIH_ENDSWITCH:
2430 case VKD3DSIH_ELSE:
2431 if (dead)
2432 {
2433 if (depth > 0)
2434 {
2435 if (ins->opcode != VKD3DSIH_ELSE)
2436 --depth;
2438 }
2439 else
2440 {
2441 dead = false;
2442 }
2443 }
2444 break;
2445
2446 /* `depth' is counted with respect to where the dead code
2447 * segment began. So it starts at zero and it signals the
2448 * termination of the dead code segment when it would
2449 * become negative. */
2450 case VKD3DSIH_BREAK:
2451 case VKD3DSIH_RET:
2452 case VKD3DSIH_CONTINUE:
2453 if (dead)
2454 {
2456 }
2457 else
2458 {
2459 dead = true;
2460 depth = 0;
2461 }
2462 break;
2463
2464 /* If `case' or `default' appears at zero depth, it means
2465 * that they are a possible target for the corresponding
2466 * switch, so the code is live again. */
2467 case VKD3DSIH_CASE:
2468 case VKD3DSIH_DEFAULT:
2469 if (dead)
2470 {
2471 if (depth == 0)
2472 dead = false;
2473 else
2475 }
2476 break;
2477
2478 /* Phase instructions can only appear in hull shaders and
2479 * outside of any block. When a phase returns, control is
2480 * moved to the following phase, so they make code live
2481 * again. */
2485 dead = false;
2486 break;
2487
2488 default:
2489 if (dead)
2491 break;
2492 }
2493 }
2494
2495 return VKD3D_OK;
2496}

Referenced by vsir_program_transform().

◆ vsir_program_structurize()

static enum vkd3d_result vsir_program_structurize ( struct vsir_program *  program,
struct vsir_transformation_context *  ctx 
)
static

Definition at line 5621 of file ir.c.

5623{
5624 struct vkd3d_shader_message_context *message_context = ctx->message_context;
5625 struct vsir_cfg_emit_target target = {0};
5626 enum vkd3d_result ret;
5627 size_t i;
5628
5629 VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
5630
5631 target.jump_target_temp_idx = program->temp_count;
5632 target.temp_count = program->temp_count + 1;
5633
5634 if (!reserve_instructions(&target.instructions, &target.ins_capacity, program->instructions.count))
5636
5637 for (i = 0; i < program->instructions.count;)
5638 {
5639 struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
5640
5641 switch (ins->opcode)
5642 {
5643 case VKD3DSIH_LABEL:
5644 VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL);
5645 TRACE("Structurizing a non-hull shader.\n");
5646 if ((ret = vsir_program_structurize_function(program, message_context,
5647 &target, &i)) < 0)
5648 goto fail;
5649 VKD3D_ASSERT(i == program->instructions.count);
5650 break;
5651
5655 VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
5656 TRACE("Structurizing phase %u of a hull shader.\n", ins->opcode);
5657 target.instructions[target.ins_count++] = *ins;
5658 ++i;
5659 if ((ret = vsir_program_structurize_function(program, message_context,
5660 &target, &i)) < 0)
5661 goto fail;
5662 break;
5663
5664 default:
5665 if (!reserve_instructions(&target.instructions, &target.ins_capacity, target.ins_count + 1))
5667 target.instructions[target.ins_count++] = *ins;
5668 ++i;
5669 break;
5670 }
5671 }
5672
5673 vkd3d_free(program->instructions.elements);
5674 program->instructions.elements = target.instructions;
5675 program->instructions.capacity = target.ins_capacity;
5676 program->instructions.count = target.ins_count;
5677 program->temp_count = target.temp_count;
5678 program->cf_type = VSIR_CF_STRUCTURED;
5679
5680 return VKD3D_OK;
5681
5682fail:
5683 vkd3d_free(target.instructions);
5684
5685 return ret;
5686}
static enum vkd3d_result vsir_program_structurize_function(struct vsir_program *program, struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, size_t *pos)
Definition: ir.c:5586

Referenced by vsir_program_transform().

◆ vsir_program_structurize_function()

static enum vkd3d_result vsir_program_structurize_function ( struct vsir_program *  program,
struct vkd3d_shader_message_context *  message_context,
struct vsir_cfg_emit_target *  target,
size_t *  pos 
)
static

Definition at line 5586 of file ir.c.

5589{
5590 enum vkd3d_result ret;
5591 struct vsir_cfg cfg;
5592
5593 if ((ret = vsir_cfg_init(&cfg, program, message_context, target, pos)) < 0)
5594 return ret;
5595
5597
5598 if ((ret = vsir_cfg_compute_loops(&cfg)) < 0)
5599 goto out;
5600
5601 if ((ret = vsir_cfg_sort_nodes(&cfg)) < 0)
5602 goto out;
5603
5605 goto out;
5606
5607 if ((ret = vsir_cfg_build_structured_program(&cfg)) < 0)
5608 goto out;
5609
5610 if ((ret = vsir_cfg_optimize(&cfg)) < 0)
5611 goto out;
5612
5614
5615out:
5616 vsir_cfg_cleanup(&cfg);
5617
5618 return ret;
5619}
static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
Definition: ir.c:4352
static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg)
Definition: ir.c:4242
static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg)
Definition: ir.c:5581
static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_cfg *cfg)
Definition: ir.c:4553
static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
Definition: ir.c:4740
static enum vkd3d_result vsir_cfg_optimize(struct vsir_cfg *cfg)
Definition: ir.c:5311

Referenced by vsir_program_structurize().

◆ vsir_program_transform()

enum vkd3d_result vsir_program_transform ( struct vsir_program *  program,
uint64_t  config_flags,
const struct vkd3d_shader_compile_info *  compile_info,
struct vkd3d_shader_message_context *  message_context 
)

Definition at line 8324 of file ir.c.

8326{
8328 {
8329 .result = VKD3D_OK,
8330 .program = program,
8331 .config_flags = config_flags,
8332 .compile_info = compile_info,
8333 .message_context = message_context,
8334 };
8335
8337
8338 if (program->shader_version.major >= 6)
8339 {
8345 }
8346 else
8347 {
8349
8350 if (program->shader_version.major <= 2)
8352
8353 if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
8355
8356 if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
8358
8363
8364 if (compile_info->target_type != VKD3D_SHADER_TARGET_GLSL
8365 && compile_info->target_type != VKD3D_SHADER_TARGET_MSL)
8367 }
8368
8375
8376 if (TRACE_ON())
8378
8379 return ctx.result;
8380}
void vsir_program_trace(const struct vsir_program *program)
Definition: d3d_asm.c:2550
static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:5805
static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:1434
static enum vkd3d_result vsir_program_apply_flat_interpolation(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:5877
static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:6344
static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:3398
static enum vkd3d_result vsir_program_flatten_control_flow_constructs(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:3129
static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:836
static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:5999
static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:888
static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:6519
static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:712
static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:2365
static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:1007
#define vsir_transform(ctx, step)
Definition: ir.c:8277
static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:3205
static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:6293
static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:2405
static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:5621
static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:2225
static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:1295
static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:6132
struct vkd3d_shader_message_context * message_context
Definition: ir.c:28
uint64_t config_flags
Definition: ir.c:26
const struct vkd3d_shader_compile_info * compile_info
Definition: ir.c:27
@ VKD3D_SHADER_TARGET_GLSL
@ VKD3D_SHADER_TARGET_MSL

Referenced by glsl_compile(), msl_compile(), and spirv_compiler_generate_spirv().

◆ vsir_program_transform_early()

enum vkd3d_result vsir_program_transform_early ( struct vsir_program *  program,
uint64_t  config_flags,
const struct vkd3d_shader_compile_info *  compile_info,
struct vkd3d_shader_message_context *  message_context 
)

Definition at line 8305 of file ir.c.

8307{
8309 {
8310 .result = VKD3D_OK,
8311 .program = program,
8312 .config_flags = config_flags,
8313 .compile_info = compile_info,
8314 .message_context = message_context,
8315 };
8316
8317 /* For vsir_program_ensure_diffuse(). */
8318 if (program->shader_version.major <= 2)
8320
8321 return ctx.result;
8322}
static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program, struct vsir_transformation_context *ctx)
Definition: ir.c:850

Referenced by vsir_parse().

◆ vsir_program_validate()

enum vkd3d_result vsir_program_validate ( struct vsir_program *  program,
uint64_t  config_flags,
const char *  source_name,
struct vkd3d_shader_message_context *  message_context 
)

Definition at line 8169 of file ir.c.

8171{
8172 struct validation_context ctx =
8173 {
8174 .message_context = message_context,
8175 .program = program,
8176 .null_location = {.source_name = source_name},
8177 .status = VKD3D_OK,
8178 .phase = VKD3DSIH_INVALID,
8179 .invalid_instruction_idx = true,
8180 };
8181 unsigned int i;
8182
8183 if (!(config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION))
8184 return VKD3D_OK;
8185
8186 switch (program->shader_version.type)
8187 {
8190 break;
8191
8192 default:
8193 if (program->patch_constant_signature.element_count != 0)
8195 "Patch constant signature is only valid for hull and domain shaders.");
8196 }
8197
8198 switch (program->shader_version.type)
8199 {
8201 break;
8202
8205 if (program->input_control_point_count == 0)
8207 "Invalid zero input control point count.");
8208 break;
8209
8210 default:
8211 if (program->input_control_point_count != 0)
8213 "Invalid input control point count %u.",
8214 program->input_control_point_count);
8215 }
8216
8217 switch (program->shader_version.type)
8218 {
8220 break;
8221
8222 default:
8223 if (program->output_control_point_count != 0)
8225 "Invalid output control point count %u.",
8226 program->output_control_point_count);
8227 }
8228
8232
8233 if (!(ctx.temps = vkd3d_calloc(ctx.program->temp_count, sizeof(*ctx.temps))))
8234 goto fail;
8235
8236 if (!(ctx.ssas = vkd3d_calloc(ctx.program->ssa_count, sizeof(*ctx.ssas))))
8237 goto fail;
8238
8239 ctx.invalid_instruction_idx = false;
8240
8241 for (ctx.instruction_idx = 0; ctx.instruction_idx < program->instructions.count
8242 && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ctx.instruction_idx)
8244
8245 ctx.invalid_instruction_idx = true;
8246
8247 if (ctx.depth != 0)
8248 validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "%zu nested blocks were not closed.", ctx.depth);
8249
8250 if (ctx.inside_block)
8251 validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "Last block was not closed.");
8252
8253 for (i = 0; i < ctx.program->ssa_count; ++i)
8254 {
8255 struct validation_context_ssa_data *data = &ctx.ssas[i];
8256
8257 if ((data->write_mask | data->read_mask) != data->write_mask)
8259 "SSA register %u has invalid read mask %#x, which is not a subset of the write mask %#x "
8260 "at the point of definition.", i, data->read_mask, data->write_mask);
8261 }
8262
8263 vkd3d_free(ctx.blocks);
8264 vkd3d_free(ctx.temps);
8265 vkd3d_free(ctx.ssas);
8266
8267 return ctx.status;
8268
8269fail:
8270 vkd3d_free(ctx.blocks);
8271 vkd3d_free(ctx.temps);
8272 vkd3d_free(ctx.ssas);
8273
8275}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static void vsir_validate_signature(struct validation_context *ctx, const struct shader_signature *signature, enum vsir_signature_type signature_type)
Definition: ir.c:7634
static void vsir_validate_instruction(struct validation_context *ctx)
Definition: ir.c:8091
struct vkd3d_shader_message_context * message_context
Definition: ir.c:6639
@ VKD3D_SHADER_ERROR_VSIR_INVALID_SSA_USAGE
@ VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE
@ VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION

Referenced by vsir_parse(), and vsir_transform_().

◆ vsir_register_init()

void vsir_register_init ( struct vkd3d_shader_register *  reg,
enum vkd3d_shader_register_type  reg_type,
enum vkd3d_data_type  data_type,
unsigned int  idx_count 
)

Definition at line 164 of file ir.c.

166{
167 reg->type = reg_type;
169 reg->non_uniform = false;
170 reg->data_type = data_type;
171 reg->idx[0].offset = ~0u;
172 reg->idx[0].rel_addr = NULL;
173 reg->idx[0].is_in_bounds = false;
174 reg->idx[1].offset = ~0u;
175 reg->idx[1].rel_addr = NULL;
176 reg->idx[1].is_in_bounds = false;
177 reg->idx[2].offset = ~0u;
178 reg->idx[2].rel_addr = NULL;
179 reg->idx[2].is_in_bounds = false;
180 reg->idx_count = idx_count;
181 reg->dimension = VSIR_DIMENSION_SCALAR;
182 reg->alignment = 0;
183}
@ VSIR_DIMENSION_SCALAR
@ VKD3D_SHADER_REGISTER_PRECISION_DEFAULT

Referenced by dst_param_io_init(), generate_vsir_instr_swizzle(), init_resource_declaration(), register_init_with_id(), register_make_constant_uint(), shader_dst_param_io_init(), shader_instruction_eliminate_phase_instance_id(), shader_sm1_parse_dst_param(), shader_sm1_parse_src_param(), shader_sm4_read_param(), sm1_generate_vsir_constant_defs(), sm1_generate_vsir_init_dst_param_from_deref(), sm1_generate_vsir_init_src_param_from_deref(), sm1_generate_vsir_instr_constant(), sm1_generate_vsir_instr_expr_per_component_instr_op(), sm1_generate_vsir_instr_expr_sincos(), sm1_generate_vsir_instr_jump(), sm1_generate_vsir_instr_load(), sm1_generate_vsir_instr_resource_load(), sm1_generate_vsir_sampler_dcls(), sm4_generate_vsir_instr_dcl_semantic(), sm6_parser_constants_init(), sm6_parser_dcl_register_builtin(), sm6_parser_emit_binop(), sm6_parser_emit_dx_compute_builtin(), sm6_parser_emit_dx_create_handle(), sm6_parser_emit_dx_domain_location(), sm6_parser_emit_dx_get_sample_count(), sm6_parser_emit_dx_get_sample_pos(), sm6_parser_emit_dx_input_register_mov(), sm6_parser_emit_dx_sincos(), sm6_parser_emit_reg_composite_construct(), sm6_parser_emit_unhandled(), sm6_parser_resources_load_cbv(), sm6_parser_resources_load_sampler(), spirv_compiler_emit_cbv_declaration(), spirv_compiler_emit_dcl_immediate_constant_buffer(), spirv_compiler_emit_dcl_indexable_temp(), spirv_compiler_emit_default_control_point_phase(), spirv_compiler_emit_hull_shader_builtins(), spirv_compiler_emit_input(), spirv_compiler_emit_resource_declaration(), spirv_compiler_emit_sampler_declaration(), spirv_compiler_get_invocation_id(), vsir_dst_param_init(), vsir_program_create_outpointid_param(), vsir_program_lower_ifc(), vsir_program_lower_precise_mad(), vsir_program_lower_texkill(), vsir_src_from_hlsl_node(), and vsir_src_param_init().

◆ vsir_signature_find_element_by_name()

static struct signature_element * vsir_signature_find_element_by_name ( const struct shader_signature *  signature,
const char *  semantic_name,
unsigned int  semantic_index 
)
static

Definition at line 132 of file ir.c.

134{
135 for (unsigned int i = 0; i < signature->element_count; ++i)
136 {
137 if (!ascii_strcasecmp(signature->elements[i].semantic_name, semantic_name)
138 && signature->elements[i].semantic_index == semantic_index)
139 return &signature->elements[i];
140 }
141
142 return NULL;
143}

Referenced by vsir_program_add_diffuse_output().

◆ vsir_signature_find_element_for_reg()

struct signature_element * vsir_signature_find_element_for_reg ( const struct shader_signature *  signature,
unsigned int  reg_idx,
unsigned int  write_mask 
)

Definition at line 1573 of file ir.c.

1575{
1576 unsigned int element_idx;
1577
1578 if (shader_signature_find_element_for_reg(signature, reg_idx, write_mask, &element_idx))
1579 return &signature->elements[element_idx];
1580
1581 return NULL;
1582}

Referenced by io_normaliser_add_index_range(), remove_unread_output_components(), shader_sm4_read_dcl_index_range(), shader_sm4_read_dcl_input_ps(), and shader_sm4_read_dcl_input_ps_siv().

◆ vsir_signature_find_sysval()

bool vsir_signature_find_sysval ( const struct shader_signature *  signature,
enum vkd3d_shader_sysval_semantic  sysval,
unsigned int  semantic_index,
unsigned int *  element_index 
)

Definition at line 145 of file ir.c.

147{
148 const struct signature_element *e;
149 unsigned int i;
150
151 for (i = 0; i < signature->element_count; ++i)
152 {
153 e = &signature->elements[i];
154 if (e->sysval_semantic == sysval && e->semantic_index == semantic_index)
155 {
156 *element_index = i;
157 return true;
158 }
159 }
160
161 return false;
162}
enum vkd3d_shader_sysval_semantic sysval
Definition: spirv.c:4839

Referenced by sm6_parser_emit_dx_sample_index(), vsir_program_insert_alpha_test(), and vsir_program_insert_clip_planes().

◆ vsir_src_param_init()

◆ vsir_src_param_init_label()

◆ vsir_src_param_init_resource()

static void vsir_src_param_init_resource ( struct vkd3d_shader_src_param *  src,
unsigned int  id,
unsigned int  idx 
)
static

Definition at line 217 of file ir.c.

218{
220 src->reg.idx[0].offset = id;
221 src->reg.idx[1].offset = idx;
222 src->reg.dimension = VSIR_DIMENSION_VEC4;
223 src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
224}
GLuint id
Definition: glext.h:5910
@ VKD3DSPR_RESOURCE

Referenced by vsir_program_lower_tex(), and vsir_program_lower_texldd().

◆ vsir_src_param_init_sampler()

static void vsir_src_param_init_sampler ( struct vkd3d_shader_src_param *  src,
unsigned int  id,
unsigned int  idx 
)
static

Definition at line 226 of file ir.c.

227{
229 src->reg.idx[0].offset = id;
230 src->reg.idx[1].offset = idx;
231 src->reg.dimension = VSIR_DIMENSION_NONE;
232}
@ VKD3DSPR_SAMPLER

Referenced by vsir_program_lower_tex(), and vsir_program_lower_texldd().

◆ vsir_transform_()

static void vsir_transform_ ( struct vsir_transformation_context *  ctx,
const char *  step_name,
enum vkd3d_result(*)(struct vsir_program *program, struct vsir_transformation_context *ctx)  step 
)
static

Definition at line 8278 of file ir.c.

8281{
8282 if (ctx->result < 0)
8283 return;
8284
8285 if ((ctx->result = step(ctx->program, ctx)) < 0)
8286 {
8287 WARN("Transformation \"%s\" failed with result %d.\n", step_name, ctx->result);
8288 return;
8289 }
8290
8291 if ((ctx->result = vsir_program_validate(ctx->program, ctx->config_flags,
8292 ctx->compile_info->source_name, ctx->message_context)) < 0)
8293 {
8294 WARN("Validation failed with result %d after transformation \"%s\".\n", ctx->result, step_name);
8295 return;
8296 }
8297}
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags, const char *source_name, struct vkd3d_shader_message_context *message_context)
Definition: ir.c:8169

◆ vsir_validate_branch()

static void vsir_validate_branch ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7694 of file ir.c.

7695{
7696 size_t i;
7697
7700
7702 return;
7703
7705 {
7706 /* Unconditional branch: parameters are jump label,
7707 * optional merge label, optional continue label. */
7709
7710 for (i = 0; i < instruction->src_count; ++i)
7711 {
7714 "Invalid register of type %#x in unconditional BRANCH instruction, expected LABEL.",
7715 instruction->src[i].reg.type);
7716 }
7717 }
7718 else
7719 {
7720 /* Conditional branch: parameters are condition, true
7721 * jump label, false jump label, optional merge label,
7722 * optional continue label. */
7725
7726 for (i = 1; i < instruction->src_count; ++i)
7727 {
7730 "Invalid register of type %#x in conditional BRANCH instruction, expected LABEL.",
7731 instruction->src[i].reg.type);
7732 }
7733 }
7734
7735 ctx->inside_block = false;
7736}
static void vsir_validate_cf_type(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, enum vsir_control_flow_type expected_type)
Definition: ir.c:7661
static void vsir_validate_dst_count(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
Definition: ir.c:7377
static bool vsir_validate_src_max_count(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
Definition: ir.c:7409
static bool vsir_validate_src_min_count(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
Definition: ir.c:7395
@ VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE

◆ vsir_validate_cf_type()

static void vsir_validate_cf_type ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction,
enum vsir_control_flow_type  expected_type 
)
static

Definition at line 7661 of file ir.c.

7663{
7664 if (ctx->program->cf_type != expected_type)
7665 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "Invalid instruction %#x in %s shader.",
7666 instruction->opcode, name_from_cf_type(ctx->program->cf_type));
7667}
static const char * name_from_cf_type(enum vsir_control_flow_type type)
Definition: ir.c:7648

Referenced by vsir_validate_branch(), vsir_validate_else(), vsir_validate_endif(), vsir_validate_endloop(), vsir_validate_endrep(), vsir_validate_endswitch(), vsir_validate_if(), vsir_validate_ifc(), vsir_validate_label(), vsir_validate_loop(), vsir_validate_phi(), vsir_validate_rep(), vsir_validate_switch(), and vsir_validate_switch_monolithic().

◆ vsir_validate_dcl_gs_instances()

static void vsir_validate_dcl_gs_instances ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7738 of file ir.c.

7740{
7741 if (!instruction->declaration.count || instruction->declaration.count > 32)
7742 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS instance count %u is invalid.",
7743 instruction->declaration.count);
7744}
@ VKD3D_SHADER_ERROR_VSIR_INVALID_GS

◆ vsir_validate_dcl_hs_max_tessfactor()

static void vsir_validate_dcl_hs_max_tessfactor ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7746 of file ir.c.

7748{
7749 /* Exclude non-finite values. */
7750 if (!(instruction->declaration.max_tessellation_factor >= 1.0f
7751 && instruction->declaration.max_tessellation_factor <= 64.0f))
7753 "Max tessellation factor %f is invalid.",
7754 instruction->declaration.max_tessellation_factor);
7755}
@ VKD3D_SHADER_ERROR_VSIR_INVALID_TESSELLATION

◆ vsir_validate_dcl_input_primitive()

static void vsir_validate_dcl_input_primitive ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7757 of file ir.c.

7759{
7760 if (instruction->declaration.primitive_type.type == VKD3D_PT_UNDEFINED
7761 || instruction->declaration.primitive_type.type >= VKD3D_PT_COUNT)
7762 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS input primitive %u is invalid.",
7763 instruction->declaration.primitive_type.type);
7764}
@ VKD3D_PT_COUNT
@ VKD3D_PT_UNDEFINED

◆ vsir_validate_dcl_output_control_point_count()

static void vsir_validate_dcl_output_control_point_count ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7766 of file ir.c.

7768{
7769 if (!instruction->declaration.count || instruction->declaration.count > 32)
7771 "Output control point count %u is invalid.",
7772 instruction->declaration.count);
7773}

◆ vsir_validate_dcl_output_topology()

static void vsir_validate_dcl_output_topology ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7775 of file ir.c.

7777{
7778 if (instruction->declaration.primitive_type.type == VKD3D_PT_UNDEFINED
7779 || instruction->declaration.primitive_type.type >= VKD3D_PT_COUNT)
7780 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS output primitive %u is invalid.",
7781 instruction->declaration.primitive_type.type);
7782}

◆ vsir_validate_dcl_temps()

static void vsir_validate_dcl_temps ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7784 of file ir.c.

7786{
7787 if (ctx->dcl_temps_found)
7789 "Duplicate DCL_TEMPS instruction.");
7790 if (instruction->declaration.count > ctx->program->temp_count)
7792 "Invalid DCL_TEMPS count %u, expected at most %u.",
7793 instruction->declaration.count, ctx->program->temp_count);
7794 ctx->dcl_temps_found = true;
7795}
@ VKD3D_SHADER_ERROR_VSIR_INVALID_DCL_TEMPS
@ VKD3D_SHADER_ERROR_VSIR_DUPLICATE_DCL_TEMPS

◆ vsir_validate_dcl_tessellator_domain()

static void vsir_validate_dcl_tessellator_domain ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7797 of file ir.c.

7799{
7800 if (instruction->declaration.tessellator_domain == VKD3D_TESSELLATOR_DOMAIN_INVALID
7801 || instruction->declaration.tessellator_domain >= VKD3D_TESSELLATOR_DOMAIN_COUNT)
7803 "Tessellator domain %#x is invalid.", instruction->declaration.tessellator_domain);
7804}
@ VKD3D_TESSELLATOR_DOMAIN_INVALID
@ VKD3D_TESSELLATOR_DOMAIN_COUNT

◆ vsir_validate_dcl_tessellator_output_primitive()

static void vsir_validate_dcl_tessellator_output_primitive ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7806 of file ir.c.

7808{
7809 if (!instruction->declaration.tessellator_output_primitive
7810 || instruction->declaration.tessellator_output_primitive
7813 "Tessellator output primitive %#x is invalid.",
7814 instruction->declaration.tessellator_output_primitive);
7815}
@ VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW

◆ vsir_validate_dcl_tessellator_partitioning()

static void vsir_validate_dcl_tessellator_partitioning ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7817 of file ir.c.

7819{
7820 if (!instruction->declaration.tessellator_partitioning
7821 || instruction->declaration.tessellator_partitioning
7824 "Tessellator partitioning %#x is invalid.",
7825 instruction->declaration.tessellator_partitioning);
7826}
@ VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN

◆ vsir_validate_dcl_vertices_out()

static void vsir_validate_dcl_vertices_out ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7828 of file ir.c.

7830{
7831 if (instruction->declaration.count > 1024)
7832 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS output vertex count %u is invalid.",
7833 instruction->declaration.count);
7834}

◆ vsir_validate_dst_count()

static void vsir_validate_dst_count ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction,
unsigned int  count 
)
static

Definition at line 7377 of file ir.c.

7379{
7380 if (instruction->dst_count != count)
7382 "Invalid destination count %u for an instruction of type %#x, expected %u.",
7383 instruction->dst_count, instruction->opcode, count);
7384}
@ VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT

Referenced by vsir_validate_branch(), and vsir_validate_instruction().

◆ vsir_validate_dst_param()

static void vsir_validate_dst_param ( struct validation_context *  ctx,
const struct vkd3d_shader_dst_param *  dst 
)
static

Definition at line 7233 of file ir.c.

7235{
7237
7238 if (dst->write_mask & ~VKD3DSP_WRITEMASK_ALL)
7239 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Destination has invalid write mask %#x.",
7240 dst->write_mask);
7241
7242 switch (dst->reg.dimension)
7243 {
7245 if (dst->write_mask != VKD3DSP_WRITEMASK_0)
7246 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Scalar destination has invalid write mask %#x.",
7247 dst->write_mask);
7248 break;
7249
7251 if (dst->write_mask == 0)
7252 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Vec4 destination has empty write mask.");
7253 break;
7254
7255 default:
7256 if (dst->write_mask != 0)
7257 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Destination of dimension %u has invalid write mask %#x.",
7258 dst->reg.dimension, dst->write_mask);
7259 break;
7260 }
7261
7262 if (dst->modifiers & ~VKD3DSPDM_MASK)
7263 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.",
7264 dst->modifiers);
7265
7266 switch (dst->shift)
7267 {
7268 case 0:
7269 case 1:
7270 case 2:
7271 case 3:
7272 case 13:
7273 case 14:
7274 case 15:
7275 break;
7276
7277 default:
7278 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT, "Destination has invalid shift %#x.",
7279 dst->shift);
7280 }
7281
7282 switch (dst->reg.type)
7283 {
7284 case VKD3DSPR_SSA:
7285 if (dst->reg.idx[0].offset < ctx->program->ssa_count)
7286 {
7287 struct validation_context_ssa_data *data = &ctx->ssas[dst->reg.idx[0].offset];
7288
7289 if (data->write_mask == 0)
7290 {
7291 data->write_mask = dst->write_mask;
7292 data->first_assigned = ctx->instruction_idx;
7293 }
7294 else
7295 {
7297 "SSA register is already assigned at instruction %zu.",
7298 data->first_assigned);
7299 }
7300 }
7301 break;
7302
7303 case VKD3DSPR_IMMCONST:
7305 case VKD3DSPR_SAMPLER:
7306 case VKD3DSPR_RESOURCE:
7307 case VKD3DSPR_INPUT:
7309 "Invalid %#x register used as destination parameter.", dst->reg.type);
7310 break;
7311
7313 if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
7315 "PATCHCONST register used as destination parameters are only allowed in Hull Shaders.");
7316 break;
7317
7318 default:
7319 break;
7320 }
7321}
static void vsir_validate_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:7118
@ VKD3DSPR_IMMCONST64
@ VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK
@ VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS
@ VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT
@ VKD3DSPDM_MASK

Referenced by vsir_validate_instruction().

◆ vsir_validate_else()

static void vsir_validate_else ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7836 of file ir.c.

7837{
7839 if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF)
7841 "ELSE instruction doesn't terminate IF block.");
7842 else
7843 ctx->blocks[ctx->depth - 1] = VKD3DSIH_ELSE;
7844}

◆ vsir_validate_endif()

static void vsir_validate_endif ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7846 of file ir.c.

7847{
7849 if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF
7850 && ctx->blocks[ctx->depth - 1] != VKD3DSIH_ELSE))
7852 "ENDIF instruction doesn't terminate IF/ELSE block.");
7853 else
7854 --ctx->depth;
7855}

◆ vsir_validate_endloop()

static void vsir_validate_endloop ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7857 of file ir.c.

7858{
7860 if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_LOOP)
7862 "ENDLOOP instruction doesn't terminate LOOP block.");
7863 else
7864 --ctx->depth;
7865}

◆ vsir_validate_endrep()

static void vsir_validate_endrep ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7867 of file ir.c.

7868{
7870 if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_REP)
7872 "ENDREP instruction doesn't terminate REP block.");
7873 else
7874 --ctx->depth;
7875}
@ VKD3DSIH_REP

◆ vsir_validate_endswitch()

static void vsir_validate_endswitch ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7877 of file ir.c.

7878{
7880 if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_SWITCH)
7882 "ENDSWITCH instruction doesn't terminate SWITCH block.");
7883 else
7884 --ctx->depth;
7885}

◆ vsir_validate_hull_shader_phase()

static void vsir_validate_hull_shader_phase ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7679 of file ir.c.

7681{
7682 if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
7684 "Phase instruction %#x is only valid in a hull shader.",
7686 if (ctx->depth != 0)
7688 "Phase instruction %#x must appear to top level.",
7690 ctx->phase = instruction->opcode;
7691 ctx->dcl_temps_found = false;
7692}
@ VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER

◆ vsir_validate_if()

static void vsir_validate_if ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7887 of file ir.c.

7888{
7891}
static void vsir_validator_push_block(struct validation_context *ctx, enum vkd3d_shader_opcode opcode)
Definition: ir.c:7669

◆ vsir_validate_ifc()

static void vsir_validate_ifc ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7893 of file ir.c.

◆ vsir_validate_instruction()

static void vsir_validate_instruction ( struct validation_context *  ctx)
static

Definition at line 8091 of file ir.c.

8092{
8093 const struct vkd3d_shader_version *version = &ctx->program->shader_version;
8095 size_t i;
8096
8097 instruction = &ctx->program->instructions.elements[ctx->instruction_idx];
8098
8099 for (i = 0; i < instruction->dst_count; ++i)
8101
8102 for (i = 0; i < instruction->src_count; ++i)
8104
8106 {
8107 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.",
8109 }
8110
8111 if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VKD3DSIH_INVALID)
8112 {
8113 switch (instruction->opcode)
8114 {
8115 case VKD3DSIH_NOP:
8116 case VKD3DSIH_HS_DECLS:
8120 break;
8121
8122 default:
8125 "Instruction %#x appear before any phase instruction in a hull shader.",
8127 break;
8128 }
8129 }
8130
8131 if (ctx->program->cf_type == VSIR_CF_BLOCKS && !ctx->inside_block)
8132 {
8133 switch (instruction->opcode)
8134 {
8135 case VKD3DSIH_NOP:
8136 case VKD3DSIH_LABEL:
8137 case VKD3DSIH_HS_DECLS:
8141 break;
8142
8143 default:
8146 "Invalid instruction %#x outside any block.",
8148 break;
8149 }
8150 }
8151
8153 {
8155
8157
8158 if (desc->validate)
8159 {
8160 if (desc->dst_param_count != ~0u)
8161 vsir_validate_dst_count(ctx, instruction, desc->dst_param_count);
8162 if (desc->src_param_count != ~0u)
8163 vsir_validate_src_count(ctx, instruction, desc->src_param_count);
8164 desc->validate(ctx, instruction);
8165 }
8166 }
8167}
static const struct vsir_validator_instruction_desc vsir_validator_instructions[]
Definition: ir.c:8057
static void vsir_validate_src_count(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, unsigned int count)
Definition: ir.c:7386
static void vsir_validate_src_param(struct validation_context *ctx, const struct vkd3d_shader_src_param *src)
Definition: ir.c:7323
static void vsir_validate_dst_param(struct validation_context *ctx, const struct vkd3d_shader_dst_param *dst)
Definition: ir.c:7233
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
struct shader_reg dst

Referenced by vsir_program_validate().

◆ vsir_validate_io_register()

static void vsir_validate_io_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6710 of file ir.c.

6712{
6713 const struct shader_signature *signature;
6714 bool has_control_point = false;
6715
6716 switch (reg->type)
6717 {
6718 case VKD3DSPR_INPUT:
6719 signature = &ctx->program->input_signature;
6720
6721 switch (ctx->program->shader_version.type)
6722 {
6726 has_control_point = true;
6727 break;
6728
6729 default:
6730 break;
6731 }
6732 break;
6733
6734 case VKD3DSPR_OUTPUT:
6735 switch (ctx->program->shader_version.type)
6736 {
6739 || ctx->program->normalisation_level >= VSIR_FULLY_NORMALISED_IO)
6740 {
6741 signature = &ctx->program->output_signature;
6742 has_control_point = ctx->program->normalisation_level >= VSIR_NORMALISED_HULL_CONTROL_POINT_IO;
6743 }
6744 else
6745 {
6746 signature = &ctx->program->patch_constant_signature;
6747 }
6748 break;
6749
6750 default:
6751 signature = &ctx->program->output_signature;
6752 break;
6753 }
6754 break;
6755
6757 signature = &ctx->program->input_signature;
6758 has_control_point = true;
6759 break;
6760
6762 signature = &ctx->program->output_signature;
6763 has_control_point = true;
6764 break;
6765
6767 signature = &ctx->program->patch_constant_signature;
6768 break;
6769
6770 default:
6772 }
6773
6774 if (ctx->program->normalisation_level < VSIR_FULLY_NORMALISED_IO)
6775 {
6776 /* Indices are [register] or [control point, register]. Both are
6777 * allowed to have a relative address. */
6778 unsigned int expected_idx_count = 1 + !!has_control_point;
6779
6780 if (reg->idx_count != expected_idx_count)
6781 {
6783 "Invalid index count %u for a register of type %#x.",
6784 reg->idx_count, reg->type);
6785 return;
6786 }
6787 }
6788 else
6789 {
6790 struct signature_element *element;
6791 unsigned int expected_idx_count;
6792 unsigned int signature_idx;
6793 bool is_array = false;
6794
6795 /* If the signature element is not an array, indices are
6796 * [signature] or [control point, signature]. If the signature
6797 * element is an array, indices are [array, signature] or
6798 * [control point, array, signature]. In any case `signature' is
6799 * not allowed to have a relative address, while the others are.
6800 */
6801 if (reg->idx_count < 1)
6802 {
6804 "Invalid index count %u for a register of type %#x.",
6805 reg->idx_count, reg->type);
6806 return;
6807 }
6808
6809 if (reg->idx[reg->idx_count - 1].rel_addr)
6810 {
6812 "Non-NULL relative address for the signature index of a register of type %#x.",
6813 reg->type);
6814 return;
6815 }
6816
6817 signature_idx = reg->idx[reg->idx_count - 1].offset;
6818
6819 if (signature_idx >= signature->element_count)
6820 {
6822 "Signature index %u exceeds the signature size %u in a register of type %#x.",
6823 signature_idx, signature->element_count, reg->type);
6824 return;
6825 }
6826
6827 element = &signature->elements[signature_idx];
6828 if (element->register_count > 1 || vsir_sysval_semantic_is_tess_factor(element->sysval_semantic))
6829 is_array = true;
6830
6831 expected_idx_count = 1 + !!has_control_point + !!is_array;
6832
6833 if (reg->idx_count != expected_idx_count)
6834 {
6836 "Invalid index count %u for a register of type %#x.",
6837 reg->idx_count, reg->type);
6838 return;
6839 }
6840 }
6841}
static int is_array(const type_t *t)
Definition: header.h:60
@ VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT
@ VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX

Referenced by vsir_validate_register().

◆ vsir_validate_label()

static void vsir_validate_label ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7899 of file ir.c.

7900{
7902 if (instruction->src_count >= 1 && !vsir_register_is_label(&instruction->src[0].reg))
7904 "Invalid register of type %#x in a LABEL instruction, expected LABEL.",
7905 instruction->src[0].reg.type);
7906
7907 if (ctx->inside_block)
7909 "Invalid LABEL instruction inside a block.");
7910 ctx->inside_block = true;
7911}

◆ vsir_validate_label_register()

static void vsir_validate_label_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6934 of file ir.c.

6936{
6939 "Invalid precision %#x for a LABEL register.", reg->precision);
6940
6941 if (reg->data_type != VKD3D_DATA_UNUSED)
6943 "Invalid data type %#x for a LABEL register.", reg->data_type);
6944
6945 if (reg->dimension != VSIR_DIMENSION_NONE)
6947 "Invalid dimension %#x for a LABEL register.", reg->dimension);
6948
6949 if (reg->idx_count != 1)
6950 {
6952 "Invalid index count %u for a LABEL register.", reg->idx_count);
6953 return;
6954 }
6955
6956 if (reg->idx[0].rel_addr)
6958 "Non-NULL relative address for a LABEL register.");
6959
6960 /* Index == 0 is invalid, but it is temporarily allowed
6961 * for intermediate stages. Once we support validation
6962 * dialects we can selectively check for that. */
6963 if (reg->idx[0].offset > ctx->program->block_count)
6965 "LABEL register index %u exceeds the maximum count %u.",
6966 reg->idx[0].offset, ctx->program->block_count);
6967}
@ VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION
@ VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION

Referenced by vsir_validate_register().

◆ vsir_validate_loop()

static void vsir_validate_loop ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7913 of file ir.c.

7914{
7916 vsir_validate_src_count(ctx, instruction, ctx->program->shader_version.major <= 3 ? 2 : 0);
7918}

◆ vsir_validate_misctype_register()

static void vsir_validate_misctype_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6914 of file ir.c.

6916{
6917 if (reg->idx_count != 1)
6918 {
6920 "Invalid index count %u for a MISCTYPE register.",
6921 reg->idx_count);
6922 return;
6923 }
6924
6925 if (reg->idx[0].rel_addr)
6927 "Non-NULL relative address for a MISCTYPE register.");
6928
6929 if (reg->idx[0].offset >= 2)
6931 "Invalid offset for a MISCTYPE register.");
6932}

Referenced by vsir_validate_register().

◆ vsir_validate_nop()

static void vsir_validate_nop ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7920 of file ir.c.

7921{
7922}

◆ vsir_validate_phi()

static void vsir_validate_phi ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7924 of file ir.c.

7925{
7926 unsigned int i, incoming_count;
7927
7929
7931
7932 if (instruction->src_count % 2 != 0)
7934 "Invalid source count %u for a PHI instruction, it must be an even number.",
7935 instruction->src_count);
7936 incoming_count = instruction->src_count / 2;
7937
7938 for (i = 0; i < incoming_count; ++i)
7939 {
7940 unsigned int value_idx = 2 * i;
7941 unsigned int label_idx = 2 * i + 1;
7942
7943 if (!register_is_constant_or_undef(&instruction->src[value_idx].reg)
7944 && !register_is_ssa(&instruction->src[value_idx].reg))
7946 "Invalid value register for incoming %u of type %#x in PHI instruction, "
7947 "expected SSA, IMMCONST or IMMCONST64.", i, instruction->src[value_idx].reg.type);
7948
7949 if (instruction->src[value_idx].reg.dimension != VSIR_DIMENSION_SCALAR)
7951 "Invalid value dimension %#x for incoming %u in PHI instruction, expected scalar.",
7952 instruction->src[value_idx].reg.dimension, i);
7953
7954 if (!vsir_register_is_label(&instruction->src[label_idx].reg))
7956 "Invalid label register for case %u of type %#x in PHI instruction, "
7957 "expected LABEL.", i, instruction->src[value_idx].reg.type);
7958 }
7959
7960 if (instruction->dst_count < 1)
7961 return;
7962
7963 if (!register_is_ssa(&instruction->dst[0].reg))
7965 "Invalid destination of type %#x in PHI instruction, expected SSA.",
7966 instruction->dst[0].reg.type);
7967
7968 if (instruction->dst[0].reg.dimension != VSIR_DIMENSION_SCALAR)
7970 "Invalid destination dimension %#x in PHI instruction, expected scalar.",
7971 instruction->dst[0].reg.dimension);
7972
7973 if (instruction->dst[0].modifiers != VKD3DSPDM_NONE)
7975 "Invalid modifiers %#x for the destination of a PHI instruction, expected none.",
7976 instruction->dst[0].modifiers);
7977
7978 if (instruction->dst[0].shift != 0)
7980 "Invalid shift %#x for the destination of a PHI instruction, expected none.",
7981 instruction->dst[0].shift);
7982}
@ VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT
static bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg)

◆ vsir_validate_rastout_register()

static void vsir_validate_rastout_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6894 of file ir.c.

6896{
6897 if (reg->idx_count != 1)
6898 {
6900 "Invalid index count %u for a RASTOUT register.",
6901 reg->idx_count);
6902 return;
6903 }
6904
6905 if (reg->idx[0].rel_addr)
6907 "Non-NULL relative address for a RASTOUT register.");
6908
6909 if (reg->idx[0].offset >= 3)
6911 "Invalid offset for a RASTOUT register.");
6912}

Referenced by vsir_validate_register().

◆ vsir_validate_register()

static void vsir_validate_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 7118 of file ir.c.

7120{
7121 unsigned int i;
7122
7123 if (reg->type >= VKD3DSPR_COUNT)
7124 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.",
7125 reg->type);
7126
7128 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.",
7129 reg->precision);
7130
7131 if (reg->data_type >= VKD3D_DATA_COUNT)
7132 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.",
7133 reg->data_type);
7134
7135 if (reg->dimension >= VSIR_DIMENSION_COUNT)
7136 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid register dimension %#x.",
7137 reg->dimension);
7138
7139 if (reg->idx_count > ARRAY_SIZE(reg->idx))
7140 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid register index count %u.",
7141 reg->idx_count);
7142
7143 for (i = 0; i < min(reg->idx_count, ARRAY_SIZE(reg->idx)); ++i)
7144 {
7145 const struct vkd3d_shader_src_param *param = reg->idx[i].rel_addr;
7146 if (reg->idx[i].rel_addr)
7148 }
7149
7150 switch (reg->type)
7151 {
7152 case VKD3DSPR_TEMP:
7154 break;
7155
7156 case VKD3DSPR_INPUT:
7158 break;
7159
7160 case VKD3DSPR_RASTOUT:
7162 break;
7163
7164 case VKD3DSPR_OUTPUT:
7166 break;
7167
7168 case VKD3DSPR_DEPTHOUT:
7170 break;
7171
7172 case VKD3DSPR_MISCTYPE:
7174 break;
7175
7176 case VKD3DSPR_LABEL:
7178 break;
7179
7180 case VKD3DSPR_IMMCONST:
7182 break;
7183
7186 break;
7187
7188 case VKD3DSPR_NULL:
7190 break;
7191
7192 case VKD3DSPR_SAMPLER:
7194 break;
7195
7196 case VKD3DSPR_RESOURCE:
7198 break;
7199
7200 case VKD3DSPR_UAV:
7202 break;
7203
7206 break;
7207
7210 break;
7211
7214 break;
7215
7218 break;
7219
7222 break;
7223
7224 case VKD3DSPR_SSA:
7226 break;
7227
7228 default:
7229 break;
7230 }
7231}
static void vsir_validate_resource_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6997
static void vsir_validate_label_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6934
static void vsir_validate_register_without_indices(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6701
static void vsir_validate_uav_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:7024
static void vsir_validate_misctype_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6914
static void vsir_validate_temp_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6843
static void vsir_validate_ssa_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:7056
static void vsir_validate_rastout_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6894
static void vsir_validate_sampler_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6969
static void vsir_validate_io_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg)
Definition: ir.c:6710
@ VKD3DSPR_DEPTHOUTGE
@ VKD3DSPR_COUNT
@ VKD3DSPR_MISCTYPE
@ VKD3DSPR_DEPTHOUT
@ VKD3DSPR_DEPTHOUTLE
@ VKD3DSPR_UAV
@ VSIR_DIMENSION_COUNT
@ VKD3D_DATA_COUNT
@ VKD3D_SHADER_REGISTER_PRECISION_COUNT

Referenced by vsir_validate_dst_param(), and vsir_validate_src_param().

◆ vsir_validate_register_without_indices()

static void vsir_validate_register_without_indices ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6701 of file ir.c.

6703{
6704 if (reg->idx_count != 0)
6706 "Invalid index count %u for a register of type %#x.",
6707 reg->idx_count, reg->type);
6708}

Referenced by vsir_validate_register().

◆ vsir_validate_rep()

static void vsir_validate_rep ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

◆ vsir_validate_resource_register()

static void vsir_validate_resource_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6997 of file ir.c.

6999{
7002 "Invalid precision %#x for a RESOURCE register.", reg->precision);
7003
7004 if (reg->data_type != VKD3D_DATA_UNUSED)
7006 "Invalid data type %#x for a RESOURCE register.", reg->data_type);
7007
7008 if (reg->dimension != VSIR_DIMENSION_VEC4)
7010 "Invalid dimension %#x for a RESOURCE register.", reg->dimension);
7011
7012 if (reg->idx_count != 2)
7013 {
7015 "Invalid index count %u for a RESOURCE register.", reg->idx_count);
7016 return;
7017 }
7018
7019 if (reg->idx[0].rel_addr)
7021 "Non-NULL relative address for the descriptor index of a RESOURCE register.");
7022}

Referenced by vsir_validate_register().

◆ vsir_validate_ret()

static void vsir_validate_ret ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 7990 of file ir.c.

7991{
7992 ctx->inside_block = false;
7993}

◆ vsir_validate_sampler_register()

static void vsir_validate_sampler_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6969 of file ir.c.

6971{
6974 "Invalid precision %#x for a SAMPLER register.", reg->precision);
6975
6976 if (reg->data_type != VKD3D_DATA_UNUSED)
6978 "Invalid data type %#x for a SAMPLER register.", reg->data_type);
6979
6980 /* VEC4 is allowed in gather operations. */
6981 if (reg->dimension == VSIR_DIMENSION_SCALAR)
6983 "Invalid dimension SCALAR for a SAMPLER register.");
6984
6985 if (reg->idx_count != 2)
6986 {
6988 "Invalid index count %u for a SAMPLER register.", reg->idx_count);
6989 return;
6990 }
6991
6992 if (reg->idx[0].rel_addr)
6994 "Non-NULL relative address for the descriptor index of a SAMPLER register.");
6995}

Referenced by vsir_validate_register().

◆ vsir_validate_signature()

static void vsir_validate_signature ( struct validation_context *  ctx,
const struct shader_signature *  signature,
enum vsir_signature_type  signature_type 
)
static

Definition at line 7634 of file ir.c.

7636{
7637 unsigned int i;
7638
7639 if (signature->element_count != 0 && !(allowed_signature_phases[signature_type]
7640 & (1u << ctx->program->shader_version.type)))
7642 "Unexpected %s signature.", signature_type_names[signature_type]);
7643
7644 for (i = 0; i < signature->element_count; ++i)
7646}
static void vsir_validate_signature_element(struct validation_context *ctx, const struct shader_signature *signature, enum vsir_signature_type signature_type, unsigned int idx)
Definition: ir.c:7468
static const unsigned int allowed_signature_phases[]
Definition: ir.c:7627
static const char *const signature_type_names[]
Definition: ir.c:7430

Referenced by vsir_program_validate().

◆ vsir_validate_signature_element()

static void vsir_validate_signature_element ( struct validation_context *  ctx,
const struct shader_signature *  signature,
enum vsir_signature_type  signature_type,
unsigned int  idx 
)
static

Definition at line 7468 of file ir.c.

7471{
7472 const char *signature_type_name = signature_type_names[signature_type];
7473 const struct signature_element *element = &signature->elements[idx];
7474 bool integer_type = false;
7475
7476 if (element->register_count == 0)
7478 "element %u of %s signature: Invalid zero register count.", idx, signature_type_name);
7479
7480 if (element->mask == 0 || (element->mask & ~0xf))
7482 "element %u of %s signature: Invalid mask %#x.", idx, signature_type_name, element->mask);
7483
7486 "element %u of %s signature: Non-contiguous mask %#x.",
7487 idx, signature_type_name, element->mask);
7488
7489 /* Here we'd likely want to validate that the usage mask is a subset of the
7490 * signature mask. Unfortunately the D3DBC parser sometimes violates this.
7491 * For example I've seen a shader like this:
7492 * ps_3_0
7493 * [...]
7494 * dcl_texcoord0 v0
7495 * [...]
7496 * texld r2.xyzw, v0.xyzw, s1.xyzw
7497 * [...]
7498 *
7499 * The dcl_textcoord0 instruction secretly has a .xy mask, which is used to
7500 * compute the signature mask, but the texld instruction apparently uses all
7501 * the components. Of course the last two components are ignored, but
7502 * formally they seem to be used. So we end up with a signature element with
7503 * mask .xy and usage mask .xyzw.
7504 *
7505 * The correct fix would probably be to make the D3DBC parser aware of which
7506 * components are really used for each instruction, but that would take some
7507 * time. */
7508 if (element->used_mask & ~0xf)
7510 "element %u of %s signature: Invalid usage mask %#x.",
7511 idx, signature_type_name, element->used_mask);
7512
7513 switch (element->sysval_semantic)
7514 {
7538 break;
7539
7540 default:
7542 "element %u of %s signature: Invalid system value semantic %#x.",
7543 idx, signature_type_name, element->sysval_semantic);
7544 break;
7545 }
7546
7547 if (element->sysval_semantic < ARRAY_SIZE(sysval_validation_data))
7548 {
7549 const struct sysval_validation_data_element *data = &sysval_validation_data[element->sysval_semantic];
7550
7551 if (data->input || data->output || data->patch_constant)
7552 {
7553 unsigned int mask;
7554
7555 switch (signature_type)
7556 {
7558 mask = data->input;
7559 break;
7560
7562 mask = data->output;
7563 break;
7564
7566 mask = data->patch_constant;
7567 break;
7568
7569 default:
7571 }
7572
7573 if (!(mask & (1u << ctx->program->shader_version.type)))
7575 "element %u of %s signature: Invalid system value semantic %#x.",
7576 idx, signature_type_name, element->sysval_semantic);
7577 }
7578
7579 if (data->component_count != 0)
7580 {
7581 if (element->component_type != data->data_type)
7583 "element %u of %s signature: Invalid data type %#x for system value semantic %#x.",
7584 idx, signature_type_name, element->component_type, element->sysval_semantic);
7585
7586 if (vsir_write_mask_component_count(element->mask) > data->component_count)
7588 "element %u of %s signature: Invalid mask %#x for system value semantic %#x.",
7589 idx, signature_type_name, element->mask, element->sysval_semantic);
7590 }
7591 }
7592
7593 switch (element->component_type)
7594 {
7597 integer_type = true;
7598 break;
7599
7601 break;
7602
7603 default:
7605 "element %u of %s signature: Invalid component type %#x.",
7606 idx, signature_type_name, element->component_type);
7607 break;
7608 }
7609
7610 if (element->min_precision >= VKD3D_SHADER_MINIMUM_PRECISION_COUNT)
7612 "element %u of %s signature: Invalid minimum precision %#x.",
7613 idx, signature_type_name, element->min_precision);
7614
7615 if (element->interpolation_mode >= VKD3DSIM_COUNT)
7617 "element %u of %s signature: Invalid interpolation mode %#x.",
7618 idx, signature_type_name, element->interpolation_mode);
7619
7620 if (integer_type && element->interpolation_mode != VKD3DSIM_NONE
7621 && element->interpolation_mode != VKD3DSIM_CONSTANT)
7623 "element %u of %s signature: Invalid interpolation mode %#x for integer component type.",
7624 idx, signature_type_name, element->interpolation_mode);
7625}
static const struct sysval_validation_data_element sysval_validation_data[]
static bool vkd3d_bitmask_is_contiguous(unsigned int mask)
Definition: vkd3d_common.h:293
@ VKD3D_SHADER_SV_VERTEX_ID
@ VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX
@ VKD3D_SHADER_SV_DEPTH_LESS_EQUAL
@ VKD3D_SHADER_SV_PRIMITIVE_ID
@ VKD3D_SHADER_SV_COVERAGE
@ VKD3D_SHADER_SV_CULL_DISTANCE
@ VKD3D_SHADER_SV_DEPTH
@ VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE
@ VKD3D_SHADER_SV_IS_FRONT_FACE
@ VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX
@ VKD3D_SHADER_SV_TESS_FACTOR_QUADINT
@ VKD3D_SHADER_SV_TESS_FACTOR_TRIINT
@ VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL
@ VKD3D_SHADER_SV_INSTANCE_ID
@ VKD3D_SHADER_SV_SAMPLE_INDEX
@ VKD3D_SHADER_SV_STENCIL_REF
@ VKD3D_SHADER_COMPONENT_INT
@ VKD3D_SHADER_COMPONENT_UINT
@ VKD3DSIM_COUNT
#define VKD3D_SHADER_MINIMUM_PRECISION_COUNT

Referenced by vsir_validate_signature().

◆ vsir_validate_src_count()

static void vsir_validate_src_count ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction,
unsigned int  count 
)
static

Definition at line 7386 of file ir.c.

7388{
7389 if (instruction->src_count != count)
7391 "Invalid source count %u for an instruction of type %#x, expected %u.",
7392 instruction->src_count, instruction->opcode, count);
7393}

Referenced by vsir_validate_instruction(), and vsir_validate_loop().

◆ vsir_validate_src_max_count()

static bool vsir_validate_src_max_count ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction,
unsigned int  count 
)
static

Definition at line 7409 of file ir.c.

7411{
7412 if (instruction->src_count > count)
7413 {
7415 "Invalid source count %u for an instruction of type %#x, expected at most %u.",
7416 instruction->src_count, instruction->opcode, count);
7417 return false;
7418 }
7419
7420 return true;
7421}

Referenced by vsir_validate_branch().

◆ vsir_validate_src_min_count()

static bool vsir_validate_src_min_count ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction,
unsigned int  count 
)
static

Definition at line 7395 of file ir.c.

7397{
7398 if (instruction->src_count < count)
7399 {
7401 "Invalid source count %u for an instruction of type %#x, expected at least %u.",
7402 instruction->src_count, instruction->opcode, count);
7403 return false;
7404 }
7405
7406 return true;
7407}

Referenced by vsir_validate_branch(), vsir_validate_phi(), and vsir_validate_switch_monolithic().

◆ vsir_validate_src_param()

static void vsir_validate_src_param ( struct validation_context *  ctx,
const struct vkd3d_shader_src_param *  src 
)
static

Definition at line 7323 of file ir.c.

7325{
7327
7328 if (src->swizzle & ~0x03030303u)
7329 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source has invalid swizzle %#x.",
7330 src->swizzle);
7331
7332 if (src->reg.dimension != VSIR_DIMENSION_VEC4 && src->swizzle != 0)
7333 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source of dimension %u has invalid swizzle %#x.",
7334 src->reg.dimension, src->swizzle);
7335
7336 if (src->modifiers >= VKD3DSPSM_COUNT)
7337 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.",
7338 src->modifiers);
7339
7340 switch (src->reg.type)
7341 {
7342 case VKD3DSPR_SSA:
7343 if (src->reg.idx[0].offset < ctx->program->ssa_count)
7344 {
7345 struct validation_context_ssa_data *data = &ctx->ssas[src->reg.idx[0].offset];
7346 unsigned int i;
7347
7348 for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
7349 data->read_mask |= (1u << vsir_swizzle_get_component(src->swizzle, i));
7350 }
7351 break;
7352
7353 case VKD3DSPR_NULL:
7355 "Invalid NULL register used as source parameter.");
7356 break;
7357
7358 case VKD3DSPR_OUTPUT:
7359 if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL
7360 || (ctx->phase != VKD3DSIH_HS_FORK_PHASE && ctx->phase != VKD3DSIH_HS_JOIN_PHASE))
7362 "Invalid OUTPUT register used as source parameter.");
7363 break;
7364
7366 if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_DOMAIN
7367 && ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
7369 "PATCHCONST register used as source parameters are only allowed in Hull and Domain Shaders.");
7370 break;
7371
7372 default:
7373 break;
7374 }
7375}
@ VKD3DSPSM_COUNT

Referenced by vsir_validate_instruction(), and vsir_validate_register().

◆ vsir_validate_ssa_register()

static void vsir_validate_ssa_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 7056 of file ir.c.

7058{
7059 struct validation_context_ssa_data *data;
7060
7061 if (reg->idx_count != 1)
7062 {
7064 "Invalid index count %u for a SSA register.",
7065 reg->idx_count);
7066 return;
7067 }
7068
7069 if (reg->idx[0].rel_addr)
7071 "Non-NULL relative address for a SSA register.");
7072
7073 if (reg->idx[0].offset >= ctx->program->ssa_count)
7074 {
7076 "SSA register index %u exceeds the maximum count %u.",
7077 reg->idx[0].offset, ctx->program->ssa_count);
7078 return;
7079 }
7080
7081 data = &ctx->ssas[reg->idx[0].offset];
7082
7083 if (reg->dimension == VSIR_DIMENSION_NONE)
7084 {
7086 "Invalid dimension NONE for a SSA register.");
7087 return;
7088 }
7089
7090 /* SSA registers can be scalar or vec4, provided that each
7091 * individual register always appears with the same
7092 * dimension. */
7093 if (data->dimension == VSIR_DIMENSION_NONE)
7094 {
7095 data->dimension = reg->dimension;
7096 data->data_type = reg->data_type;
7097 data->first_seen = ctx->instruction_idx;
7098 }
7099 else
7100 {
7101 if (data->dimension != reg->dimension)
7103 "Invalid dimension %#x for a SSA register: "
7104 "it has already been seen with dimension %#x at instruction %zu.",
7105 reg->dimension, data->dimension, data->first_seen);
7106
7107 if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type))
7109 "Invalid data type %#x for a SSA register: "
7110 "it has already been seen with data type %#x at instruction %zu.",
7111 reg->data_type, data->data_type, data->first_seen);
7112 }
7113}
static bool data_type_is_64_bit(enum vkd3d_data_type data_type)

Referenced by vsir_validate_register().

◆ vsir_validate_switch()

static void vsir_validate_switch ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

◆ vsir_validate_switch_monolithic()

static void vsir_validate_switch_monolithic ( struct validation_context *  ctx,
const struct vkd3d_shader_instruction *  instruction 
)
static

Definition at line 8001 of file ir.c.

8003{
8004 unsigned int i, case_count;
8005
8007
8008 /* Parameters are source, default label, merge label and
8009 * then pairs of constant value and case label. */
8010
8012 return;
8013
8014 if (instruction->src_count % 2 != 1)
8016 "Invalid source count %u for a monolithic SWITCH instruction, it must be an odd number.",
8017 instruction->src_count);
8018
8019 if (!vsir_register_is_label(&instruction->src[1].reg))
8021 "Invalid default label register of type %#x in monolithic SWITCH instruction, expected LABEL.",
8022 instruction->src[1].reg.type);
8023
8024 if (!vsir_register_is_label(&instruction->src[2].reg))
8026 "Invalid merge label register of type %#x in monolithic SWITCH instruction, expected LABEL.",
8027 instruction->src[2].reg.type);
8028
8029 case_count = (instruction->src_count - 3) / 2;
8030
8031 for (i = 0; i < case_count; ++i)
8032 {
8033 unsigned int value_idx = 3 + 2 * i;
8034 unsigned int label_idx = 3 + 2 * i + 1;
8035
8036 if (!register_is_constant(&instruction->src[value_idx].reg))
8038 "Invalid value register for case %u of type %#x in monolithic SWITCH instruction, "
8039 "expected IMMCONST or IMMCONST64.", i, instruction->src[value_idx].reg.type);
8040
8041 if (!vsir_register_is_label(&instruction->src[label_idx].reg))
8043 "Invalid label register for case %u of type %#x in monolithic SWITCH instruction, "
8044 "expected LABEL.", i, instruction->src[value_idx].reg.type);
8045 }
8046
8047 ctx->inside_block = false;
8048}
static bool register_is_constant(const struct vkd3d_shader_register *reg)

◆ vsir_validate_temp_register()

static void vsir_validate_temp_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 6843 of file ir.c.

6845{
6846 struct validation_context_temp_data *data;
6847
6848 if (reg->idx_count != 1)
6849 {
6851 "Invalid index count %u for a TEMP register.",
6852 reg->idx_count);
6853 return;
6854 }
6855
6856 if (reg->idx[0].rel_addr)
6858 "Non-NULL relative address for a TEMP register.");
6859
6860 if (reg->idx[0].offset >= ctx->program->temp_count)
6861 {
6863 "TEMP register index %u exceeds the maximum count %u.",
6864 reg->idx[0].offset, ctx->program->temp_count);
6865 return;
6866 }
6867
6868 data = &ctx->temps[reg->idx[0].offset];
6869
6870 if (reg->dimension == VSIR_DIMENSION_NONE)
6871 {
6873 "Invalid dimension NONE for a TEMP register.");
6874 return;
6875 }
6876
6877 /* TEMP registers can be scalar or vec4, provided that
6878 * each individual register always appears with the same
6879 * dimension. */
6880 if (data->dimension == VSIR_DIMENSION_NONE)
6881 {
6882 data->dimension = reg->dimension;
6883 data->first_seen = ctx->instruction_idx;
6884 }
6885 else if (data->dimension != reg->dimension)
6886 {
6888 "Invalid dimension %#x for a TEMP register: "
6889 "it has already been seen with dimension %#x at instruction %zu.",
6890 reg->dimension, data->dimension, data->first_seen);
6891 }
6892}

Referenced by vsir_validate_register().

◆ vsir_validate_uav_register()

static void vsir_validate_uav_register ( struct validation_context *  ctx,
const struct vkd3d_shader_register *  reg 
)
static

Definition at line 7024 of file ir.c.

7026{
7029 "Invalid precision %#x for a UAV register.",
7030 reg->precision);
7031
7032 if (reg->data_type != VKD3D_DATA_UNUSED)
7034 "Invalid data type %#x for a UAV register.",
7035 reg->data_type);
7036
7037 /* NONE is allowed in counter operations. */
7038 if (reg->dimension == VSIR_DIMENSION_SCALAR)
7040 "Invalid dimension %#x for a UAV register.",
7041 reg->dimension);
7042
7043 if (reg->idx_count != 2)
7044 {
7046 "Invalid index count %u for a UAV register.",
7047 reg->idx_count);
7048 return;
7049 }
7050
7051 if (reg->idx[0].rel_addr)
7053 "Non-NULL relative address for the descriptor index of a UAV register.");
7054}

Referenced by vsir_validate_register().

◆ vsir_validator_push_block()

static void vsir_validator_push_block ( struct validation_context *  ctx,
enum vkd3d_shader_opcode  opcode 
)
static

Definition at line 7669 of file ir.c.

7670{
7671 if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks)))
7672 {
7674 return;
7675 }
7676 ctx->blocks[ctx->depth++] = opcode;
7677}

Referenced by vsir_validate_if(), vsir_validate_ifc(), vsir_validate_loop(), vsir_validate_rep(), and vsir_validate_switch().

Variable Documentation

◆ allowed_signature_phases

const unsigned int allowed_signature_phases[]
static
Initial value:
=
{
}
#define VS_BIT
Definition: ir.c:7438
#define DS_BIT
Definition: ir.c:7441
#define PS_BIT
Definition: ir.c:7437
#define HS_BIT
Definition: ir.c:7440
#define GS_BIT
Definition: ir.c:7439

Definition at line 7627 of file ir.c.

Referenced by vsir_validate_signature().

◆ signature_type_names

const char* const signature_type_names[]
static
Initial value:
=
{
[SIGNATURE_TYPE_INPUT] = "input",
[SIGNATURE_TYPE_OUTPUT] = "output",
[SIGNATURE_TYPE_PATCH_CONSTANT] = "patch constant",
}

Definition at line 7430 of file ir.c.

Referenced by vsir_validate_signature(), and vsir_validate_signature_element().

◆ sysval_validation_data

◆ vsir_validator_instructions

const struct vsir_validator_instruction_desc vsir_validator_instructions[]
static

Definition at line 8057 of file ir.c.

Referenced by vsir_validate_instruction().