Updated spirv-tools.
This commit is contained in:
parent
971f86f370
commit
1e978cc3db
@ -1 +1 @@
|
||||
"v2022.2-dev", "SPIRV-Tools v2022.2-dev 8f96b8ade7aed1a3448c9cd0294449e7a41b91f7"
|
||||
"v2022.2-dev", "SPIRV-Tools v2022.2-dev da9e2f0400ece7d68b44d7c7126cac808dfcf5c3"
|
||||
|
@ -56,6 +56,7 @@ static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader};
|
||||
static const SpvCapability pygen_variable_caps_ShaderBitInstructions[] = {SpvCapabilityShader, SpvCapabilityBitInstructions};
|
||||
static const SpvCapability pygen_variable_caps_ShaderClockKHR[] = {SpvCapabilityShaderClockKHR};
|
||||
static const SpvCapability pygen_variable_caps_SparseResidency[] = {SpvCapabilitySparseResidency};
|
||||
static const SpvCapability pygen_variable_caps_SplitBarrierINTEL[] = {SpvCapabilitySplitBarrierINTEL};
|
||||
static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL};
|
||||
static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL};
|
||||
static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL};
|
||||
@ -509,7 +510,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
|
||||
{"BeginInvocationInterlockEXT", SpvOpBeginInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu},
|
||||
{"EndInvocationInterlockEXT", SpvOpEndInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu},
|
||||
{"DemoteToHelperInvocation", SpvOpDemoteToHelperInvocation, 1, pygen_variable_caps_DemoteToHelperInvocation, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu},
|
||||
{"DemoteToHelperInvocationEXT", SpvOpDemoteToHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocation, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu},
|
||||
{"DemoteToHelperInvocationEXT", SpvOpDemoteToHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu},
|
||||
{"IsHelperInvocationEXT", SpvOpIsHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, 0xffffffffu, 0xffffffffu},
|
||||
{"ConvertUToImageNV", SpvOpConvertUToImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"ConvertUToSamplerNV", SpvOpConvertUToSamplerNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
@ -758,5 +759,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
|
||||
{"TypeBufferSurfaceINTEL", SpvOpTypeBufferSurfaceINTEL, 1, pygen_variable_caps_VectorComputeINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"TypeStructContinuedINTEL", SpvOpTypeStructContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"ConstantCompositeContinuedINTEL", SpvOpConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"SpecConstantCompositeContinuedINTEL", SpvOpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}
|
||||
{"SpecConstantCompositeContinuedINTEL", SpvOpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"ControlBarrierArriveINTEL", SpvOpControlBarrierArriveINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"ControlBarrierWaitINTEL", SpvOpControlBarrierWaitINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}
|
||||
};
|
@ -98,6 +98,8 @@ const char* ExtensionToString(Extension extension) {
|
||||
return "SPV_INTEL_optnone";
|
||||
case Extension::kSPV_INTEL_shader_integer_functions2:
|
||||
return "SPV_INTEL_shader_integer_functions2";
|
||||
case Extension::kSPV_INTEL_split_barrier:
|
||||
return "SPV_INTEL_split_barrier";
|
||||
case Extension::kSPV_INTEL_subgroups:
|
||||
return "SPV_INTEL_subgroups";
|
||||
case Extension::kSPV_INTEL_unstructured_loop_controls:
|
||||
@ -205,8 +207,8 @@ const char* ExtensionToString(Extension extension) {
|
||||
|
||||
|
||||
bool GetExtensionFromString(const char* str, Extension* extension) {
|
||||
static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
|
||||
static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
|
||||
static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
|
||||
static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
|
||||
const auto b = std::begin(known_ext_strs);
|
||||
const auto e = std::end(known_ext_strs);
|
||||
const auto found = std::equal_range(
|
||||
@ -612,6 +614,8 @@ const char* CapabilityToString(SpvCapability capability) {
|
||||
return "AtomicFloat16AddEXT";
|
||||
case SpvCapabilityDebugInfoModuleINTEL:
|
||||
return "DebugInfoModuleINTEL";
|
||||
case SpvCapabilitySplitBarrierINTEL:
|
||||
return "SplitBarrierINTEL";
|
||||
case SpvCapabilityMax:
|
||||
assert(0 && "Attempting to convert SpvCapabilityMax to string");
|
||||
return "";
|
||||
|
@ -47,6 +47,7 @@ kSPV_INTEL_media_block_io,
|
||||
kSPV_INTEL_memory_access_aliasing,
|
||||
kSPV_INTEL_optnone,
|
||||
kSPV_INTEL_shader_integer_functions2,
|
||||
kSPV_INTEL_split_barrier,
|
||||
kSPV_INTEL_subgroups,
|
||||
kSPV_INTEL_unstructured_loop_controls,
|
||||
kSPV_INTEL_usm_storage_classes,
|
||||
|
@ -164,6 +164,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_INTEL_media_block_io[]
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_memory_access_aliasing[] = {spvtools::Extension::kSPV_INTEL_memory_access_aliasing};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_optnone[] = {spvtools::Extension::kSPV_INTEL_optnone};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_shader_integer_functions2[] = {spvtools::Extension::kSPV_INTEL_shader_integer_functions2};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_split_barrier[] = {spvtools::Extension::kSPV_INTEL_split_barrier};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_subgroups[] = {spvtools::Extension::kSPV_INTEL_subgroups};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_usm_storage_classes[] = {spvtools::Extension::kSPV_INTEL_usm_storage_classes};
|
||||
@ -1155,7 +1156,8 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
|
||||
{"LongConstantCompositeINTEL", 6089, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_long_constant_composite, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OptNoneINTEL", 6094, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_optnone, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"AtomicFloat16AddEXT", 6095, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float16_add, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"DebugInfoModuleINTEL", 6114, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_debug_module, {}, 0xffffffffu, 0xffffffffu}
|
||||
{"DebugInfoModuleINTEL", 6114, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_debug_module, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SplitBarrierINTEL", 6141, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_split_barrier, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_RayQueryIntersectionEntries[] = {
|
||||
|
204
3rdparty/spirv-tools/source/opt/def_use_manager.cpp
vendored
204
3rdparty/spirv-tools/source/opt/def_use_manager.cpp
vendored
@ -13,11 +13,23 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/opt/def_use_manager.h"
|
||||
#include "source/util/make_unique.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
namespace analysis {
|
||||
|
||||
// Don't compact before we have a reasonable number of ids allocated (~32kb).
|
||||
static const size_t kCompactThresholdMinTotalIds = (8 * 1024);
|
||||
// Compact when fewer than this fraction of the storage is used (should be 2^n
|
||||
// for performance).
|
||||
static const size_t kCompactThresholdFractionFreeIds = 8;
|
||||
|
||||
DefUseManager::DefUseManager() {
|
||||
use_pool_ = MakeUnique<UseListPool>();
|
||||
used_id_pool_ = MakeUnique<UsedIdListPool>();
|
||||
}
|
||||
|
||||
void DefUseManager::AnalyzeInstDef(Instruction* inst) {
|
||||
const uint32_t def_id = inst->result_id();
|
||||
if (def_id != 0) {
|
||||
@ -34,15 +46,15 @@ void DefUseManager::AnalyzeInstDef(Instruction* inst) {
|
||||
}
|
||||
|
||||
void DefUseManager::AnalyzeInstUse(Instruction* inst) {
|
||||
// It might have existed before.
|
||||
EraseUseRecordsOfOperandIds(inst);
|
||||
|
||||
// Create entry for the given instruction. Note that the instruction may
|
||||
// not have any in-operands. In such cases, we still need a entry for those
|
||||
// instructions so this manager knows it has seen the instruction later.
|
||||
auto* used_ids = &inst_to_used_ids_[inst];
|
||||
if (used_ids->size()) {
|
||||
EraseUseRecordsOfOperandIds(inst);
|
||||
used_ids = &inst_to_used_ids_[inst];
|
||||
}
|
||||
used_ids->clear(); // It might have existed before.
|
||||
UsedIdList& used_ids =
|
||||
inst_to_used_id_.insert({inst, UsedIdList(used_id_pool_.get())})
|
||||
.first->second;
|
||||
|
||||
for (uint32_t i = 0; i < inst->NumOperands(); ++i) {
|
||||
switch (inst->GetOperand(i).type) {
|
||||
@ -54,8 +66,17 @@ void DefUseManager::AnalyzeInstUse(Instruction* inst) {
|
||||
uint32_t use_id = inst->GetSingleWordOperand(i);
|
||||
Instruction* def = GetDef(use_id);
|
||||
assert(def && "Definition is not registered.");
|
||||
id_to_users_.insert(UserEntry{def, inst});
|
||||
used_ids->push_back(use_id);
|
||||
|
||||
// Add to inst's use records
|
||||
used_ids.push_back(use_id);
|
||||
|
||||
// Add to the users, taking care to avoid adding duplicates. We know
|
||||
// the duplicate for this instruction will always be at the tail.
|
||||
UseList& list = inst_to_users_.insert({def, UseList(use_pool_.get())})
|
||||
.first->second;
|
||||
if (list.empty() || list.back() != inst) {
|
||||
list.push_back(inst);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
@ -94,23 +115,6 @@ const Instruction* DefUseManager::GetDef(uint32_t id) const {
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
DefUseManager::IdToUsersMap::const_iterator DefUseManager::UsersBegin(
|
||||
const Instruction* def) const {
|
||||
return id_to_users_.lower_bound(
|
||||
UserEntry{const_cast<Instruction*>(def), nullptr});
|
||||
}
|
||||
|
||||
bool DefUseManager::UsersNotEnd(const IdToUsersMap::const_iterator& iter,
|
||||
const IdToUsersMap::const_iterator& cached_end,
|
||||
const Instruction* inst) const {
|
||||
return (iter != cached_end && iter->def == inst);
|
||||
}
|
||||
|
||||
bool DefUseManager::UsersNotEnd(const IdToUsersMap::const_iterator& iter,
|
||||
const Instruction* inst) const {
|
||||
return UsersNotEnd(iter, id_to_users_.end(), inst);
|
||||
}
|
||||
|
||||
bool DefUseManager::WhileEachUser(
|
||||
const Instruction* def, const std::function<bool(Instruction*)>& f) const {
|
||||
// Ensure that |def| has been registered.
|
||||
@ -118,9 +122,11 @@ bool DefUseManager::WhileEachUser(
|
||||
"Definition is not registered.");
|
||||
if (!def->HasResultId()) return true;
|
||||
|
||||
auto end = id_to_users_.end();
|
||||
for (auto iter = UsersBegin(def); UsersNotEnd(iter, end, def); ++iter) {
|
||||
if (!f(iter->user)) return false;
|
||||
auto iter = inst_to_users_.find(def);
|
||||
if (iter != inst_to_users_.end()) {
|
||||
for (Instruction* user : iter->second) {
|
||||
if (!f(user)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -151,14 +157,15 @@ bool DefUseManager::WhileEachUse(
|
||||
"Definition is not registered.");
|
||||
if (!def->HasResultId()) return true;
|
||||
|
||||
auto end = id_to_users_.end();
|
||||
for (auto iter = UsersBegin(def); UsersNotEnd(iter, end, def); ++iter) {
|
||||
Instruction* user = iter->user;
|
||||
for (uint32_t idx = 0; idx != user->NumOperands(); ++idx) {
|
||||
const Operand& op = user->GetOperand(idx);
|
||||
if (op.type != SPV_OPERAND_TYPE_RESULT_ID && spvIsIdType(op.type)) {
|
||||
if (def->result_id() == op.words[0]) {
|
||||
if (!f(user, idx)) return false;
|
||||
auto iter = inst_to_users_.find(def);
|
||||
if (iter != inst_to_users_.end()) {
|
||||
for (Instruction* user : iter->second) {
|
||||
for (uint32_t idx = 0; idx != user->NumOperands(); ++idx) {
|
||||
const Operand& op = user->GetOperand(idx);
|
||||
if (op.type != SPV_OPERAND_TYPE_RESULT_ID && spvIsIdType(op.type)) {
|
||||
if (def->result_id() == op.words[0]) {
|
||||
if (!f(user, idx)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,17 +237,18 @@ void DefUseManager::AnalyzeDefUse(Module* module) {
|
||||
}
|
||||
|
||||
void DefUseManager::ClearInst(Instruction* inst) {
|
||||
auto iter = inst_to_used_ids_.find(inst);
|
||||
if (iter != inst_to_used_ids_.end()) {
|
||||
if (inst_to_used_id_.find(inst) != inst_to_used_id_.end()) {
|
||||
EraseUseRecordsOfOperandIds(inst);
|
||||
if (inst->result_id() != 0) {
|
||||
// Remove all uses of this inst.
|
||||
auto users_begin = UsersBegin(inst);
|
||||
auto end = id_to_users_.end();
|
||||
auto new_end = users_begin;
|
||||
for (; UsersNotEnd(new_end, end, inst); ++new_end) {
|
||||
uint32_t const result_id = inst->result_id();
|
||||
if (result_id != 0) {
|
||||
// For each using instruction, remove result_id from their used ids.
|
||||
auto iter = inst_to_users_.find(inst);
|
||||
if (iter != inst_to_users_.end()) {
|
||||
for (Instruction* use : iter->second) {
|
||||
inst_to_used_id_.at(use).remove_first(result_id);
|
||||
}
|
||||
inst_to_users_.erase(iter);
|
||||
}
|
||||
id_to_users_.erase(users_begin, new_end);
|
||||
id_to_def_.erase(inst->result_id());
|
||||
}
|
||||
}
|
||||
@ -249,16 +257,48 @@ void DefUseManager::ClearInst(Instruction* inst) {
|
||||
void DefUseManager::EraseUseRecordsOfOperandIds(const Instruction* inst) {
|
||||
// Go through all ids used by this instruction, remove this instruction's
|
||||
// uses of them.
|
||||
auto iter = inst_to_used_ids_.find(inst);
|
||||
if (iter != inst_to_used_ids_.end()) {
|
||||
for (auto use_id : iter->second) {
|
||||
id_to_users_.erase(
|
||||
UserEntry{GetDef(use_id), const_cast<Instruction*>(inst)});
|
||||
auto iter = inst_to_used_id_.find(inst);
|
||||
if (iter != inst_to_used_id_.end()) {
|
||||
const UsedIdList& used_ids = iter->second;
|
||||
for (uint32_t def_id : used_ids) {
|
||||
auto def_iter = inst_to_users_.find(GetDef(def_id));
|
||||
if (def_iter != inst_to_users_.end()) {
|
||||
def_iter->second.remove_first(const_cast<Instruction*>(inst));
|
||||
}
|
||||
}
|
||||
inst_to_used_id_.erase(inst);
|
||||
|
||||
// If we're using only a fraction of the space in used_ids_, compact storage
|
||||
// to prevent memory usage from being unbounded.
|
||||
if (used_id_pool_->total_nodes() > kCompactThresholdMinTotalIds &&
|
||||
used_id_pool_->used_nodes() <
|
||||
used_id_pool_->total_nodes() / kCompactThresholdFractionFreeIds) {
|
||||
CompactStorage();
|
||||
}
|
||||
inst_to_used_ids_.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void DefUseManager::CompactStorage() {
|
||||
CompactUseRecords();
|
||||
CompactUsedIds();
|
||||
}
|
||||
|
||||
void DefUseManager::CompactUseRecords() {
|
||||
std::unique_ptr<UseListPool> new_pool = MakeUnique<UseListPool>();
|
||||
for (auto& iter : inst_to_users_) {
|
||||
iter.second.move_nodes(new_pool.get());
|
||||
}
|
||||
use_pool_ = std::move(new_pool);
|
||||
}
|
||||
|
||||
void DefUseManager::CompactUsedIds() {
|
||||
std::unique_ptr<UsedIdListPool> new_pool = MakeUnique<UsedIdListPool>();
|
||||
for (auto& iter : inst_to_used_id_) {
|
||||
iter.second.move_nodes(new_pool.get());
|
||||
}
|
||||
used_id_pool_ = std::move(new_pool);
|
||||
}
|
||||
|
||||
bool CompareAndPrintDifferences(const DefUseManager& lhs,
|
||||
const DefUseManager& rhs) {
|
||||
bool same = true;
|
||||
@ -277,34 +317,52 @@ bool CompareAndPrintDifferences(const DefUseManager& lhs,
|
||||
same = false;
|
||||
}
|
||||
|
||||
if (lhs.id_to_users_ != rhs.id_to_users_) {
|
||||
for (auto p : lhs.id_to_users_) {
|
||||
if (rhs.id_to_users_.count(p) == 0) {
|
||||
printf("Diff in id_to_users: missing value in rhs\n");
|
||||
}
|
||||
for (const auto& l : lhs.inst_to_used_id_) {
|
||||
std::set<uint32_t> ul, ur;
|
||||
lhs.ForEachUse(l.first,
|
||||
[&ul](Instruction*, uint32_t id) { ul.insert(id); });
|
||||
rhs.ForEachUse(l.first,
|
||||
[&ur](Instruction*, uint32_t id) { ur.insert(id); });
|
||||
if (ul.size() != ur.size()) {
|
||||
printf(
|
||||
"Diff in inst_to_used_id_: different number of used ids (%zu != %zu)",
|
||||
ul.size(), ur.size());
|
||||
same = false;
|
||||
} else if (ul != ur) {
|
||||
printf("Diff in inst_to_used_id_: different used ids\n");
|
||||
same = false;
|
||||
}
|
||||
for (auto p : rhs.id_to_users_) {
|
||||
if (lhs.id_to_users_.count(p) == 0) {
|
||||
printf("Diff in id_to_users: missing value in lhs\n");
|
||||
}
|
||||
}
|
||||
for (const auto& r : rhs.inst_to_used_id_) {
|
||||
auto iter_l = lhs.inst_to_used_id_.find(r.first);
|
||||
if (r.second.empty() &&
|
||||
!(iter_l == lhs.inst_to_used_id_.end() || iter_l->second.empty())) {
|
||||
printf("Diff in inst_to_used_id_: unexpected instr in rhs\n");
|
||||
same = false;
|
||||
}
|
||||
same = false;
|
||||
}
|
||||
|
||||
if (lhs.inst_to_used_ids_ != rhs.inst_to_used_ids_) {
|
||||
for (auto p : lhs.inst_to_used_ids_) {
|
||||
if (rhs.inst_to_used_ids_.count(p.first) == 0) {
|
||||
printf("Diff in inst_to_used_ids: missing value in rhs\n");
|
||||
}
|
||||
for (const auto& l : lhs.inst_to_users_) {
|
||||
std::set<Instruction*> ul, ur;
|
||||
lhs.ForEachUser(l.first, [&ul](Instruction* use) { ul.insert(use); });
|
||||
rhs.ForEachUser(l.first, [&ur](Instruction* use) { ur.insert(use); });
|
||||
if (ul.size() != ur.size()) {
|
||||
printf("Diff in inst_to_users_: different number of users (%zu != %zu)",
|
||||
ul.size(), ur.size());
|
||||
same = false;
|
||||
} else if (ul != ur) {
|
||||
printf("Diff in inst_to_users_: different users\n");
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
for (const auto& r : rhs.inst_to_users_) {
|
||||
auto iter_l = lhs.inst_to_users_.find(r.first);
|
||||
if (r.second.empty() &&
|
||||
!(iter_l == lhs.inst_to_users_.end() || iter_l->second.empty())) {
|
||||
printf("Diff in inst_to_users_: unexpected instr in rhs\n");
|
||||
same = false;
|
||||
}
|
||||
for (auto p : rhs.inst_to_used_ids_) {
|
||||
if (lhs.inst_to_used_ids_.count(p.first) == 0) {
|
||||
printf("Diff in inst_to_used_ids: missing value in lhs\n");
|
||||
}
|
||||
}
|
||||
same = false;
|
||||
}
|
||||
|
||||
return same;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "source/opt/instruction.h"
|
||||
#include "source/opt/module.h"
|
||||
#include "source/util/pooled_linked_list.h"
|
||||
#include "spirv-tools/libspirv.hpp"
|
||||
|
||||
namespace spvtools {
|
||||
@ -49,50 +50,6 @@ inline bool operator<(const Use& lhs, const Use& rhs) {
|
||||
return lhs.operand_index < rhs.operand_index;
|
||||
}
|
||||
|
||||
// Definition should never be null. User can be null, however, such an entry
|
||||
// should be used only for searching (e.g. all users of a particular definition)
|
||||
// and never stored in a container.
|
||||
struct UserEntry {
|
||||
Instruction* def;
|
||||
Instruction* user;
|
||||
};
|
||||
|
||||
inline bool operator==(const UserEntry& lhs, const UserEntry& rhs) {
|
||||
return lhs.def == rhs.def && lhs.user == rhs.user;
|
||||
}
|
||||
|
||||
// Orders UserEntry for use in associative containers (i.e. less than ordering).
|
||||
//
|
||||
// The definition of an UserEntry is treated as the major key and the users as
|
||||
// the minor key so that all the users of a particular definition are
|
||||
// consecutive in a container.
|
||||
//
|
||||
// A null user always compares less than a real user. This is done to provide
|
||||
// easy values to search for the beginning of the users of a particular
|
||||
// definition (i.e. using {def, nullptr}).
|
||||
struct UserEntryLess {
|
||||
bool operator()(const UserEntry& lhs, const UserEntry& rhs) const {
|
||||
// If lhs.def and rhs.def are both null, fall through to checking the
|
||||
// second entries.
|
||||
if (!lhs.def && rhs.def) return true;
|
||||
if (lhs.def && !rhs.def) return false;
|
||||
|
||||
// If neither definition is null, then compare unique ids.
|
||||
if (lhs.def && rhs.def) {
|
||||
if (lhs.def->unique_id() < rhs.def->unique_id()) return true;
|
||||
if (rhs.def->unique_id() < lhs.def->unique_id()) return false;
|
||||
}
|
||||
|
||||
// Return false on equality.
|
||||
if (!lhs.user && !rhs.user) return false;
|
||||
if (!lhs.user) return true;
|
||||
if (!rhs.user) return false;
|
||||
|
||||
// If neither user is null then compare unique ids.
|
||||
return lhs.user->unique_id() < rhs.user->unique_id();
|
||||
}
|
||||
};
|
||||
|
||||
// A class for analyzing and managing defs and uses in an Module.
|
||||
class DefUseManager {
|
||||
public:
|
||||
@ -102,7 +59,7 @@ class DefUseManager {
|
||||
// will be communicated to the outside via the given message |consumer|. This
|
||||
// instance only keeps a reference to the |consumer|, so the |consumer| should
|
||||
// outlive this instance.
|
||||
DefUseManager(Module* module) { AnalyzeDefUse(module); }
|
||||
DefUseManager(Module* module) : DefUseManager() { AnalyzeDefUse(module); }
|
||||
|
||||
DefUseManager(const DefUseManager&) = delete;
|
||||
DefUseManager(DefUseManager&&) = delete;
|
||||
@ -214,35 +171,36 @@ class DefUseManager {
|
||||
// uses.
|
||||
void UpdateDefUse(Instruction* inst);
|
||||
|
||||
// Compacts any internal storage to save memory.
|
||||
void CompactStorage();
|
||||
|
||||
private:
|
||||
using IdToUsersMap = std::set<UserEntry, UserEntryLess>;
|
||||
using InstToUsedIdsMap =
|
||||
std::unordered_map<const Instruction*, std::vector<uint32_t>>;
|
||||
using UseList = spvtools::utils::PooledLinkedList<Instruction*>;
|
||||
using UseListPool = spvtools::utils::PooledLinkedListNodes<Instruction*>;
|
||||
// Stores linked lists of Instructions using a def.
|
||||
using InstToUsersMap = std::unordered_map<const Instruction*, UseList>;
|
||||
|
||||
// Returns the first location that {|def|, nullptr} could be inserted into the
|
||||
// users map without violating ordering.
|
||||
IdToUsersMap::const_iterator UsersBegin(const Instruction* def) const;
|
||||
using UsedIdList = spvtools::utils::PooledLinkedList<uint32_t>;
|
||||
using UsedIdListPool = spvtools::utils::PooledLinkedListNodes<uint32_t>;
|
||||
// Stores mapping from instruction to their UsedIdRange.
|
||||
using InstToUsedIdMap = std::unordered_map<const Instruction*, UsedIdList>;
|
||||
|
||||
// Returns true if |iter| has not reached the end of |def|'s users.
|
||||
//
|
||||
// In the first version |iter| is compared against the end of the map for
|
||||
// validity before other checks. In the second version, |iter| is compared
|
||||
// against |cached_end| for validity before other checks. This allows caching
|
||||
// the map's end which is a performance improvement on some platforms.
|
||||
bool UsersNotEnd(const IdToUsersMap::const_iterator& iter,
|
||||
const Instruction* def) const;
|
||||
bool UsersNotEnd(const IdToUsersMap::const_iterator& iter,
|
||||
const IdToUsersMap::const_iterator& cached_end,
|
||||
const Instruction* def) const;
|
||||
DefUseManager();
|
||||
|
||||
// Analyzes the defs and uses in the given |module| and populates data
|
||||
// structures in this class. Does nothing if |module| is nullptr.
|
||||
void AnalyzeDefUse(Module* module);
|
||||
|
||||
IdToDefMap id_to_def_; // Mapping from ids to their definitions
|
||||
IdToUsersMap id_to_users_; // Mapping from ids to their users
|
||||
// Mapping from instructions to the ids used in the instruction.
|
||||
InstToUsedIdsMap inst_to_used_ids_;
|
||||
// Removes unused entries in used_records_ and used_ids_.
|
||||
void CompactUseRecords();
|
||||
void CompactUsedIds();
|
||||
|
||||
IdToDefMap id_to_def_; // Mapping from ids to their definitions
|
||||
InstToUsersMap inst_to_users_; // Map from def to uses.
|
||||
std::unique_ptr<UseListPool> use_pool_;
|
||||
|
||||
std::unique_ptr<UsedIdListPool> used_id_pool_;
|
||||
InstToUsedIdMap inst_to_used_id_; // Map from instruction to used ids.
|
||||
};
|
||||
|
||||
} // namespace analysis
|
||||
|
@ -41,6 +41,8 @@ namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) {
|
||||
set = Analysis(set & ~valid_analyses_);
|
||||
|
||||
if (set & kAnalysisDefUse) {
|
||||
BuildDefUseManager();
|
||||
}
|
||||
|
3
3rdparty/spirv-tools/source/opt/ir_context.h
vendored
3
3rdparty/spirv-tools/source/opt/ir_context.h
vendored
@ -867,8 +867,7 @@ inline IRContext::Analysis operator|(IRContext::Analysis lhs,
|
||||
|
||||
inline IRContext::Analysis& operator|=(IRContext::Analysis& lhs,
|
||||
IRContext::Analysis rhs) {
|
||||
lhs = static_cast<IRContext::Analysis>(static_cast<int>(lhs) |
|
||||
static_cast<int>(rhs));
|
||||
lhs = lhs | rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,8 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
module_->SetMemoryModel(std::move(spv_inst));
|
||||
} else if (opcode == SpvOpEntryPoint) {
|
||||
module_->AddEntryPoint(std::move(spv_inst));
|
||||
} else if (opcode == SpvOpExecutionMode) {
|
||||
} else if (opcode == SpvOpExecutionMode ||
|
||||
opcode == SpvOpExecutionModeId) {
|
||||
module_->AddExecutionMode(std::move(spv_inst));
|
||||
} else if (IsDebug1Inst(opcode)) {
|
||||
module_->AddDebug1Inst(std::move(spv_inst));
|
||||
|
@ -431,6 +431,7 @@ bool MergeReturnPass::BreakFromConstruct(
|
||||
std::list<BasicBlock*>* order, Instruction* break_merge_inst) {
|
||||
// Make sure the CFG is build here. If we don't then it becomes very hard
|
||||
// to know which new blocks need to be updated.
|
||||
context()->InvalidateAnalyses(IRContext::kAnalysisCFG);
|
||||
context()->BuildInvalidAnalyses(IRContext::kAnalysisCFG);
|
||||
|
||||
// When predicating, be aware of whether this block is a header block, a
|
||||
|
158
3rdparty/spirv-tools/source/opt/types.cpp
vendored
158
3rdparty/spirv-tools/source/opt/types.cpp
vendored
@ -21,6 +21,7 @@
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "source/util/hash_combine.h"
|
||||
#include "source/util/make_unique.h"
|
||||
#include "spirv/unified1/spirv.h"
|
||||
|
||||
@ -28,6 +29,7 @@ namespace spvtools {
|
||||
namespace opt {
|
||||
namespace analysis {
|
||||
|
||||
using spvtools::utils::hash_combine;
|
||||
using U32VecVec = std::vector<std::vector<uint32_t>>;
|
||||
|
||||
namespace {
|
||||
@ -182,23 +184,26 @@ bool Type::operator==(const Type& other) const {
|
||||
}
|
||||
}
|
||||
|
||||
void Type::GetHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
if (!seen->insert(this).second) {
|
||||
return;
|
||||
size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const {
|
||||
// Linear search through a dense, cache coherent vector is faster than O(log
|
||||
// n) search in a complex data structure (eg std::set) for the generally small
|
||||
// number of nodes. It also skips the overhead of an new/delete per Type
|
||||
// (when inserting/removing from a set).
|
||||
if (std::find(seen->begin(), seen->end(), this) != seen->end()) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
words->push_back(kind_);
|
||||
seen->push_back(this);
|
||||
|
||||
hash = hash_combine(hash, uint32_t(kind_));
|
||||
for (const auto& d : decorations_) {
|
||||
for (auto w : d) {
|
||||
words->push_back(w);
|
||||
}
|
||||
hash = hash_combine(hash, d);
|
||||
}
|
||||
|
||||
switch (kind_) {
|
||||
#define DeclareKindCase(type) \
|
||||
case k##type: \
|
||||
As##type()->GetExtraHashWords(words, seen); \
|
||||
#define DeclareKindCase(type) \
|
||||
case k##type: \
|
||||
hash = As##type()->ComputeExtraStateHash(hash, seen); \
|
||||
break
|
||||
DeclareKindCase(Void);
|
||||
DeclareKindCase(Bool);
|
||||
@ -232,18 +237,13 @@ void Type::GetHashWords(std::vector<uint32_t>* words,
|
||||
break;
|
||||
}
|
||||
|
||||
seen->erase(this);
|
||||
seen->pop_back();
|
||||
return hash;
|
||||
}
|
||||
|
||||
size_t Type::HashValue() const {
|
||||
std::u32string h;
|
||||
std::vector<uint32_t> words;
|
||||
GetHashWords(&words);
|
||||
for (auto w : words) {
|
||||
h.push_back(w);
|
||||
}
|
||||
|
||||
return std::hash<std::u32string>()(h);
|
||||
SeenTypes seen;
|
||||
return ComputeHashValue(0, &seen);
|
||||
}
|
||||
|
||||
bool Integer::IsSameImpl(const Type* that, IsSameCache*) const {
|
||||
@ -258,10 +258,8 @@ std::string Integer::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Integer::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>*) const {
|
||||
words->push_back(width_);
|
||||
words->push_back(signed_);
|
||||
size_t Integer::ComputeExtraStateHash(size_t hash, SeenTypes*) const {
|
||||
return hash_combine(hash, width_, signed_);
|
||||
}
|
||||
|
||||
bool Float::IsSameImpl(const Type* that, IsSameCache*) const {
|
||||
@ -275,9 +273,8 @@ std::string Float::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Float::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>*) const {
|
||||
words->push_back(width_);
|
||||
size_t Float::ComputeExtraStateHash(size_t hash, SeenTypes*) const {
|
||||
return hash_combine(hash, width_);
|
||||
}
|
||||
|
||||
Vector::Vector(const Type* type, uint32_t count)
|
||||
@ -299,10 +296,11 @@ std::string Vector::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Vector::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
element_type_->GetHashWords(words, seen);
|
||||
words->push_back(count_);
|
||||
size_t Vector::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
// prefer form that doesn't require push/pop from stack: add state and
|
||||
// make tail call.
|
||||
hash = hash_combine(hash, count_);
|
||||
return element_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
Matrix::Matrix(const Type* type, uint32_t count)
|
||||
@ -324,10 +322,9 @@ std::string Matrix::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Matrix::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
element_type_->GetHashWords(words, seen);
|
||||
words->push_back(count_);
|
||||
size_t Matrix::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
hash = hash_combine(hash, count_);
|
||||
return element_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
Image::Image(Type* type, SpvDim dimen, uint32_t d, bool array, bool multisample,
|
||||
@ -362,16 +359,10 @@ std::string Image::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Image::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
sampled_type_->GetHashWords(words, seen);
|
||||
words->push_back(dim_);
|
||||
words->push_back(depth_);
|
||||
words->push_back(arrayed_);
|
||||
words->push_back(ms_);
|
||||
words->push_back(sampled_);
|
||||
words->push_back(format_);
|
||||
words->push_back(access_qualifier_);
|
||||
size_t Image::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
hash = hash_combine(hash, uint32_t(dim_), depth_, arrayed_, ms_, sampled_,
|
||||
uint32_t(format_), uint32_t(access_qualifier_));
|
||||
return sampled_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
bool SampledImage::IsSameImpl(const Type* that, IsSameCache* seen) const {
|
||||
@ -387,9 +378,8 @@ std::string SampledImage::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void SampledImage::GetExtraHashWords(
|
||||
std::vector<uint32_t>* words, std::unordered_set<const Type*>* seen) const {
|
||||
image_type_->GetHashWords(words, seen);
|
||||
size_t SampledImage::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
return image_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
Array::Array(const Type* type, const Array::LengthInfo& length_info_arg)
|
||||
@ -422,11 +412,9 @@ std::string Array::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Array::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
element_type_->GetHashWords(words, seen);
|
||||
words->insert(words->end(), length_info_.words.begin(),
|
||||
length_info_.words.end());
|
||||
size_t Array::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
hash = hash_combine(hash, length_info_.words);
|
||||
return element_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
void Array::ReplaceElementType(const Type* type) { element_type_ = type; }
|
||||
@ -449,9 +437,8 @@ std::string RuntimeArray::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void RuntimeArray::GetExtraHashWords(
|
||||
std::vector<uint32_t>* words, std::unordered_set<const Type*>* seen) const {
|
||||
element_type_->GetHashWords(words, seen);
|
||||
size_t RuntimeArray::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
return element_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
void RuntimeArray::ReplaceElementType(const Type* type) {
|
||||
@ -508,19 +495,14 @@ std::string Struct::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Struct::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
size_t Struct::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
for (auto* t : element_types_) {
|
||||
t->GetHashWords(words, seen);
|
||||
hash = t->ComputeHashValue(hash, seen);
|
||||
}
|
||||
for (const auto& pair : element_decorations_) {
|
||||
words->push_back(pair.first);
|
||||
for (const auto& d : pair.second) {
|
||||
for (auto w : d) {
|
||||
words->push_back(w);
|
||||
}
|
||||
}
|
||||
hash = hash_combine(hash, pair.first, pair.second);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
bool Opaque::IsSameImpl(const Type* that, IsSameCache*) const {
|
||||
@ -535,11 +517,8 @@ std::string Opaque::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Opaque::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>*) const {
|
||||
for (auto c : name_) {
|
||||
words->push_back(static_cast<char32_t>(c));
|
||||
}
|
||||
size_t Opaque::ComputeExtraStateHash(size_t hash, SeenTypes*) const {
|
||||
return hash_combine(hash, name_);
|
||||
}
|
||||
|
||||
Pointer::Pointer(const Type* type, SpvStorageClass sc)
|
||||
@ -568,10 +547,9 @@ std::string Pointer::str() const {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void Pointer::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
pointee_type_->GetHashWords(words, seen);
|
||||
words->push_back(storage_class_);
|
||||
size_t Pointer::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
hash = hash_combine(hash, uint32_t(storage_class_));
|
||||
return pointee_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
void Pointer::SetPointeeType(const Type* type) { pointee_type_ = type; }
|
||||
@ -605,12 +583,11 @@ std::string Function::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Function::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const {
|
||||
return_type_->GetHashWords(words, seen);
|
||||
size_t Function::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
|
||||
for (const auto* t : param_types_) {
|
||||
t->GetHashWords(words, seen);
|
||||
hash = t->ComputeHashValue(hash, seen);
|
||||
}
|
||||
return return_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
void Function::SetReturnType(const Type* type) { return_type_ = type; }
|
||||
@ -627,9 +604,8 @@ std::string Pipe::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void Pipe::GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>*) const {
|
||||
words->push_back(access_qualifier_);
|
||||
size_t Pipe::ComputeExtraStateHash(size_t hash, SeenTypes*) const {
|
||||
return hash_combine(hash, uint32_t(access_qualifier_));
|
||||
}
|
||||
|
||||
bool ForwardPointer::IsSameImpl(const Type* that, IsSameCache*) const {
|
||||
@ -652,11 +628,11 @@ std::string ForwardPointer::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void ForwardPointer::GetExtraHashWords(
|
||||
std::vector<uint32_t>* words, std::unordered_set<const Type*>* seen) const {
|
||||
words->push_back(target_id_);
|
||||
words->push_back(storage_class_);
|
||||
if (pointer_) pointer_->GetHashWords(words, seen);
|
||||
size_t ForwardPointer::ComputeExtraStateHash(size_t hash,
|
||||
SeenTypes* seen) const {
|
||||
hash = hash_combine(hash, target_id_, uint32_t(storage_class_));
|
||||
if (pointer_) hash = pointer_->ComputeHashValue(hash, seen);
|
||||
return hash;
|
||||
}
|
||||
|
||||
CooperativeMatrixNV::CooperativeMatrixNV(const Type* type, const uint32_t scope,
|
||||
@ -680,12 +656,10 @@ std::string CooperativeMatrixNV::str() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void CooperativeMatrixNV::GetExtraHashWords(
|
||||
std::vector<uint32_t>* words, std::unordered_set<const Type*>* pSet) const {
|
||||
component_type_->GetHashWords(words, pSet);
|
||||
words->push_back(scope_id_);
|
||||
words->push_back(rows_id_);
|
||||
words->push_back(columns_id_);
|
||||
size_t CooperativeMatrixNV::ComputeExtraStateHash(size_t hash,
|
||||
SeenTypes* seen) const {
|
||||
hash = hash_combine(hash, scope_id_, rows_id_, columns_id_);
|
||||
return component_type_->ComputeHashValue(hash, seen);
|
||||
}
|
||||
|
||||
bool CooperativeMatrixNV::IsSameImpl(const Type* that,
|
||||
|
105
3rdparty/spirv-tools/source/opt/types.h
vendored
105
3rdparty/spirv-tools/source/opt/types.h
vendored
@ -28,6 +28,7 @@
|
||||
|
||||
#include "source/latest_version_spirv_header.h"
|
||||
#include "source/opt/instruction.h"
|
||||
#include "source/util/small_vector.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
namespace spvtools {
|
||||
@ -67,6 +68,8 @@ class Type {
|
||||
public:
|
||||
typedef std::set<std::pair<const Pointer*, const Pointer*>> IsSameCache;
|
||||
|
||||
using SeenTypes = spvtools::utils::SmallVector<const Type*, 8>;
|
||||
|
||||
// Available subtypes.
|
||||
//
|
||||
// When adding a new derived class of Type, please add an entry to the enum.
|
||||
@ -155,21 +158,7 @@ class Type {
|
||||
// Returns the hash value of this type.
|
||||
size_t HashValue() const;
|
||||
|
||||
// Adds the necessary words to compute a hash value of this type to |words|.
|
||||
void GetHashWords(std::vector<uint32_t>* words) const {
|
||||
std::unordered_set<const Type*> seen;
|
||||
GetHashWords(words, &seen);
|
||||
}
|
||||
|
||||
// Adds the necessary words to compute a hash value of this type to |words|.
|
||||
void GetHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* seen) const;
|
||||
|
||||
// Adds necessary extra words for a subtype to calculate a hash value into
|
||||
// |words|.
|
||||
virtual void GetExtraHashWords(
|
||||
std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const = 0;
|
||||
size_t ComputeHashValue(size_t hash, SeenTypes* seen) const;
|
||||
|
||||
// A bunch of methods for casting this type to a given type. Returns this if the
|
||||
// cast can be done, nullptr otherwise.
|
||||
@ -205,6 +194,10 @@ class Type {
|
||||
DeclareCastMethod(RayQueryKHR)
|
||||
#undef DeclareCastMethod
|
||||
|
||||
protected:
|
||||
// Add any type-specific state to |hash| and returns new hash.
|
||||
virtual size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const = 0;
|
||||
|
||||
protected:
|
||||
// Decorations attached to this type. Each decoration is encoded as a vector
|
||||
// of uint32_t numbers. The first uint32_t number is the decoration value,
|
||||
@ -233,8 +226,7 @@ class Integer : public Type {
|
||||
uint32_t width() const { return width_; }
|
||||
bool IsSigned() const { return signed_; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -254,8 +246,7 @@ class Float : public Type {
|
||||
const Float* AsFloat() const override { return this; }
|
||||
uint32_t width() const { return width_; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -275,8 +266,7 @@ class Vector : public Type {
|
||||
Vector* AsVector() override { return this; }
|
||||
const Vector* AsVector() const override { return this; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -297,8 +287,7 @@ class Matrix : public Type {
|
||||
Matrix* AsMatrix() override { return this; }
|
||||
const Matrix* AsMatrix() const override { return this; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -328,8 +317,7 @@ class Image : public Type {
|
||||
SpvImageFormat format() const { return format_; }
|
||||
SpvAccessQualifier access_qualifier() const { return access_qualifier_; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -356,8 +344,7 @@ class SampledImage : public Type {
|
||||
|
||||
const Type* image_type() const { return image_type_; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -400,8 +387,7 @@ class Array : public Type {
|
||||
Array* AsArray() override { return this; }
|
||||
const Array* AsArray() const override { return this; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
void ReplaceElementType(const Type* element_type);
|
||||
|
||||
@ -423,8 +409,7 @@ class RuntimeArray : public Type {
|
||||
RuntimeArray* AsRuntimeArray() override { return this; }
|
||||
const RuntimeArray* AsRuntimeArray() const override { return this; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
void ReplaceElementType(const Type* element_type);
|
||||
|
||||
@ -460,8 +445,7 @@ class Struct : public Type {
|
||||
Struct* AsStruct() override { return this; }
|
||||
const Struct* AsStruct() const override { return this; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -492,8 +476,7 @@ class Opaque : public Type {
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -513,8 +496,7 @@ class Pointer : public Type {
|
||||
Pointer* AsPointer() override { return this; }
|
||||
const Pointer* AsPointer() const override { return this; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
void SetPointeeType(const Type* type);
|
||||
|
||||
@ -540,8 +522,7 @@ class Function : public Type {
|
||||
const std::vector<const Type*>& param_types() const { return param_types_; }
|
||||
std::vector<const Type*>& param_types() { return param_types_; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>*) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
void SetReturnType(const Type* type);
|
||||
|
||||
@ -565,8 +546,7 @@ class Pipe : public Type {
|
||||
|
||||
SpvAccessQualifier access_qualifier() const { return access_qualifier_; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -593,8 +573,7 @@ class ForwardPointer : public Type {
|
||||
ForwardPointer* AsForwardPointer() override { return this; }
|
||||
const ForwardPointer* AsForwardPointer() const override { return this; }
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>* words,
|
||||
std::unordered_set<const Type*>* pSet) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
private:
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override;
|
||||
@ -617,8 +596,7 @@ class CooperativeMatrixNV : public Type {
|
||||
return this;
|
||||
}
|
||||
|
||||
void GetExtraHashWords(std::vector<uint32_t>*,
|
||||
std::unordered_set<const Type*>*) const override;
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
|
||||
|
||||
const Type* component_type() const { return component_type_; }
|
||||
uint32_t scope_id() const { return scope_id_; }
|
||||
@ -634,24 +612,25 @@ class CooperativeMatrixNV : public Type {
|
||||
const uint32_t columns_id_;
|
||||
};
|
||||
|
||||
#define DefineParameterlessType(type, name) \
|
||||
class type : public Type { \
|
||||
public: \
|
||||
type() : Type(k##type) {} \
|
||||
type(const type&) = default; \
|
||||
\
|
||||
std::string str() const override { return #name; } \
|
||||
\
|
||||
type* As##type() override { return this; } \
|
||||
const type* As##type() const override { return this; } \
|
||||
\
|
||||
void GetExtraHashWords(std::vector<uint32_t>*, \
|
||||
std::unordered_set<const Type*>*) const override {} \
|
||||
\
|
||||
private: \
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override { \
|
||||
return that->As##type() && HasSameDecorations(that); \
|
||||
} \
|
||||
#define DefineParameterlessType(type, name) \
|
||||
class type : public Type { \
|
||||
public: \
|
||||
type() : Type(k##type) {} \
|
||||
type(const type&) = default; \
|
||||
\
|
||||
std::string str() const override { return #name; } \
|
||||
\
|
||||
type* As##type() override { return this; } \
|
||||
const type* As##type() const override { return this; } \
|
||||
\
|
||||
size_t ComputeExtraStateHash(size_t hash, SeenTypes*) const override { \
|
||||
return hash; \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
bool IsSameImpl(const Type* that, IsSameCache*) const override { \
|
||||
return that->As##type() && HasSameDecorations(that); \
|
||||
} \
|
||||
}
|
||||
DefineParameterlessType(Void, void);
|
||||
DefineParameterlessType(Bool, bool);
|
||||
|
53
3rdparty/spirv-tools/source/util/hash_combine.h
vendored
Normal file
53
3rdparty/spirv-tools/source/util/hash_combine.h
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2022 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SOURCE_UTIL_HASH_COMBINE_H_
|
||||
#define SOURCE_UTIL_HASH_COMBINE_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace spvtools {
|
||||
namespace utils {
|
||||
|
||||
// Helpers for incrementally computing hashes.
|
||||
// For reference, see
|
||||
// http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3876.pdf
|
||||
|
||||
template <typename T>
|
||||
inline size_t hash_combine(std::size_t seed, const T& val) {
|
||||
return seed ^ (std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline size_t hash_combine(std::size_t hash, const std::vector<T>& vals) {
|
||||
for (const T& val : vals) {
|
||||
hash = hash_combine(hash, val);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline size_t hash_combine(std::size_t hash) { return hash; }
|
||||
|
||||
template <typename T, typename... Types>
|
||||
inline size_t hash_combine(std::size_t hash, const T& val,
|
||||
const Types&... args) {
|
||||
return hash_combine(hash_combine(hash, val), args...);
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_UTIL_HASH_COMBINE_H_
|
236
3rdparty/spirv-tools/source/util/pooled_linked_list.h
vendored
Normal file
236
3rdparty/spirv-tools/source/util/pooled_linked_list.h
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
// Copyright (c) 2021 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SOURCE_UTIL_POOLED_LINKED_LIST_H_
|
||||
#define SOURCE_UTIL_POOLED_LINKED_LIST_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace spvtools {
|
||||
namespace utils {
|
||||
|
||||
// Shared storage of nodes for PooledLinkedList.
|
||||
template <typename T>
|
||||
class PooledLinkedListNodes {
|
||||
public:
|
||||
struct Node {
|
||||
Node(T e, int32_t n = -1) : element(e), next(n) {}
|
||||
|
||||
T element = {};
|
||||
int32_t next = -1;
|
||||
};
|
||||
|
||||
PooledLinkedListNodes() = default;
|
||||
PooledLinkedListNodes(const PooledLinkedListNodes&) = delete;
|
||||
PooledLinkedListNodes& operator=(const PooledLinkedListNodes&) = delete;
|
||||
|
||||
PooledLinkedListNodes(PooledLinkedListNodes&& that) {
|
||||
*this = std::move(that);
|
||||
}
|
||||
|
||||
PooledLinkedListNodes& operator=(PooledLinkedListNodes&& that) {
|
||||
vec_ = std::move(that.vec_);
|
||||
free_nodes_ = that.free_nodes_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t total_nodes() { return vec_.size(); }
|
||||
size_t free_nodes() { return free_nodes_; }
|
||||
size_t used_nodes() { return total_nodes() - free_nodes(); }
|
||||
|
||||
private:
|
||||
template <typename ListT>
|
||||
friend class PooledLinkedList;
|
||||
|
||||
Node& at(int32_t index) { return vec_[index]; }
|
||||
const Node& at(int32_t index) const { return vec_[index]; }
|
||||
|
||||
int32_t insert(T element) {
|
||||
int32_t index = int32_t(vec_.size());
|
||||
vec_.emplace_back(element);
|
||||
return index;
|
||||
}
|
||||
|
||||
std::vector<Node> vec_;
|
||||
size_t free_nodes_ = 0;
|
||||
};
|
||||
|
||||
// Implements a linked-list where list nodes come from a shared pool. This is
|
||||
// meant to be used in scenarios where it is desirable to avoid many small
|
||||
// allocations.
|
||||
//
|
||||
// Instead of pointers, the list uses indices to allow the underlying storage
|
||||
// to be modified without needing to modify the list. When removing elements
|
||||
// from the list, nodes are not deleted or recycled: to reclaim unused space,
|
||||
// perform a sequence of |move_nodes| operations into a temporary pool, which
|
||||
// then is moved into the old pool.
|
||||
//
|
||||
// This does *not* attempt to implement a full stl-compatible interface.
|
||||
template <typename T>
|
||||
class PooledLinkedList {
|
||||
public:
|
||||
using NodePool = PooledLinkedListNodes<T>;
|
||||
using Node = typename NodePool::Node;
|
||||
|
||||
PooledLinkedList() = delete;
|
||||
PooledLinkedList(NodePool* nodes) : nodes_(nodes) {}
|
||||
|
||||
// Shared iterator implementation (for iterator and const_iterator).
|
||||
template <typename ElementT, typename PoolT>
|
||||
class iterator_base {
|
||||
public:
|
||||
iterator_base(const iterator_base& i)
|
||||
: nodes_(i.nodes_), index_(i.index_) {}
|
||||
|
||||
iterator_base& operator++() {
|
||||
index_ = nodes_->at(index_).next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator_base& operator=(const iterator_base& i) {
|
||||
nodes_ = i.nodes_;
|
||||
index_ = i.index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ElementT& operator*() const { return nodes_->at(index_).element; }
|
||||
ElementT* operator->() const { return &nodes_->at(index_).element; }
|
||||
|
||||
friend inline bool operator==(const iterator_base& lhs,
|
||||
const iterator_base& rhs) {
|
||||
return lhs.nodes_ == rhs.nodes_ && lhs.index_ == rhs.index_;
|
||||
}
|
||||
friend inline bool operator!=(const iterator_base& lhs,
|
||||
const iterator_base& rhs) {
|
||||
return lhs.nodes_ != rhs.nodes_ || lhs.index_ != rhs.index_;
|
||||
}
|
||||
|
||||
// Define standard iterator types needs so this class can be
|
||||
// used with <algorithms>.
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = ElementT;
|
||||
using pointer = ElementT*;
|
||||
using const_pointer = const ElementT*;
|
||||
using reference = ElementT&;
|
||||
using const_reference = const ElementT&;
|
||||
using size_type = size_t;
|
||||
|
||||
private:
|
||||
friend PooledLinkedList;
|
||||
|
||||
iterator_base(PoolT* pool, int32_t index) : nodes_(pool), index_(index) {}
|
||||
|
||||
PoolT* nodes_;
|
||||
int32_t index_ = -1;
|
||||
};
|
||||
|
||||
using iterator = iterator_base<T, std::vector<Node>>;
|
||||
using const_iterator = iterator_base<const T, const std::vector<Node>>;
|
||||
|
||||
bool empty() const { return head_ == -1; }
|
||||
|
||||
T& front() { return nodes_->at(head_).element; }
|
||||
T& back() { return nodes_->at(tail_).element; }
|
||||
const T& front() const { return nodes_->at(head_).element; }
|
||||
const T& back() const { return nodes_->at(tail_).element; }
|
||||
|
||||
iterator begin() { return iterator(&nodes_->vec_, head_); }
|
||||
iterator end() { return iterator(&nodes_->vec_, -1); }
|
||||
const_iterator begin() const { return const_iterator(&nodes_->vec_, head_); }
|
||||
const_iterator end() const { return const_iterator(&nodes_->vec_, -1); }
|
||||
|
||||
// Inserts |element| at the back of the list.
|
||||
void push_back(T element) {
|
||||
int32_t new_tail = nodes_->insert(element);
|
||||
if (head_ == -1) {
|
||||
head_ = new_tail;
|
||||
tail_ = new_tail;
|
||||
} else {
|
||||
nodes_->at(tail_).next = new_tail;
|
||||
tail_ = new_tail;
|
||||
}
|
||||
}
|
||||
|
||||
// Removes the first occurrence of |element| from the list.
|
||||
// Returns if |element| was removed.
|
||||
bool remove_first(T element) {
|
||||
int32_t* prev_next = &head_;
|
||||
for (int32_t prev_index = -1, index = head_; index != -1; /**/) {
|
||||
auto& node = nodes_->at(index);
|
||||
if (node.element == element) {
|
||||
// Snip from of the list, optionally fixing up tail pointer.
|
||||
if (tail_ == index) {
|
||||
assert(node.next == -1);
|
||||
tail_ = prev_index;
|
||||
}
|
||||
*prev_next = node.next;
|
||||
nodes_->free_nodes_++;
|
||||
return true;
|
||||
} else {
|
||||
prev_next = &node.next;
|
||||
}
|
||||
prev_index = index;
|
||||
index = node.next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the PooledLinkedListNodes that owns this list's nodes.
|
||||
NodePool* pool() { return nodes_; }
|
||||
|
||||
// Moves the nodes in this list into |new_pool|, providing a way to compact
|
||||
// storage and reclaim unused space.
|
||||
//
|
||||
// Upon completing a sequence of |move_nodes| calls, you must ensure you
|
||||
// retain ownership of the new storage your lists point to. Example usage:
|
||||
//
|
||||
// unique_ptr<NodePool> new_pool = ...;
|
||||
// for (PooledLinkedList& list : lists) {
|
||||
// list.move_to(new_pool);
|
||||
// }
|
||||
// my_pool_ = std::move(new_pool);
|
||||
void move_nodes(NodePool* new_pool) {
|
||||
// Be sure to construct the list in the same order, instead of simply
|
||||
// doing a sequence of push_backs.
|
||||
int32_t prev_entry = -1;
|
||||
int32_t nodes_freed = 0;
|
||||
for (int32_t index = head_; index != -1; nodes_freed++) {
|
||||
const auto& node = nodes_->at(index);
|
||||
int32_t this_entry = new_pool->insert(node.element);
|
||||
index = node.next;
|
||||
if (prev_entry == -1) {
|
||||
head_ = this_entry;
|
||||
} else {
|
||||
new_pool->at(prev_entry).next = this_entry;
|
||||
}
|
||||
prev_entry = this_entry;
|
||||
}
|
||||
tail_ = prev_entry;
|
||||
// Update our old pool's free count, now we're a member of the new pool.
|
||||
nodes_->free_nodes_ += nodes_freed;
|
||||
nodes_ = new_pool;
|
||||
}
|
||||
|
||||
private:
|
||||
NodePool* nodes_;
|
||||
int32_t head_ = -1;
|
||||
int32_t tail_ = -1;
|
||||
};
|
||||
|
||||
} // namespace utils
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_UTIL_POOLED_LINKED_LIST_H_
|
@ -333,6 +333,15 @@ class SmallVector {
|
||||
++size_;
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
if (large_data_) {
|
||||
large_data_->pop_back();
|
||||
} else {
|
||||
--size_;
|
||||
small_data_[size_].~T();
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIt>
|
||||
iterator insert(iterator pos, InputIt first, InputIt last) {
|
||||
size_t element_idx = (pos - begin());
|
||||
|
@ -147,6 +147,24 @@ bool DoesDebugInfoOperandMatchExpectation(
|
||||
return true;
|
||||
}
|
||||
|
||||
// Overload for NonSemanticShaderDebugInfo100Instructions.
|
||||
bool DoesDebugInfoOperandMatchExpectation(
|
||||
const ValidationState_t& _,
|
||||
const std::function<bool(NonSemanticShaderDebugInfo100Instructions)>&
|
||||
expectation,
|
||||
const Instruction* inst, uint32_t word_index) {
|
||||
if (inst->words().size() <= word_index) return false;
|
||||
auto* debug_inst = _.FindDef(inst->word(word_index));
|
||||
if (debug_inst->opcode() != SpvOpExtInst ||
|
||||
(debug_inst->ext_inst_type() !=
|
||||
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
|
||||
!expectation(
|
||||
NonSemanticShaderDebugInfo100Instructions(debug_inst->word(4)))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check that the operand of a debug info instruction |inst| at |word_index|
|
||||
// is a result id of an debug info instruction whose debug instruction type
|
||||
// is |expected_debug_inst|.
|
||||
@ -223,6 +241,18 @@ spv_result_t ValidateOperandDebugType(
|
||||
const Instruction* inst, uint32_t word_index,
|
||||
const std::function<std::string()>& ext_inst_name,
|
||||
bool allow_template_param) {
|
||||
// Check for NonSemanticShaderDebugInfo100 specific types.
|
||||
if (inst->ext_inst_type() ==
|
||||
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
|
||||
std::function<bool(NonSemanticShaderDebugInfo100Instructions)> expectation =
|
||||
[](NonSemanticShaderDebugInfo100Instructions dbg_inst) {
|
||||
return dbg_inst == NonSemanticShaderDebugInfo100DebugTypeMatrix;
|
||||
};
|
||||
if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
// Check for common types.
|
||||
std::function<bool(CommonDebugInfoInstructions)> expectation =
|
||||
[&allow_template_param](CommonDebugInfoInstructions dbg_inst) {
|
||||
if (allow_template_param &&
|
||||
@ -2719,6 +2749,86 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
|
||||
|
||||
auto num_words = inst->words().size();
|
||||
|
||||
// Handle any non-common NonSemanticShaderDebugInfo instructions.
|
||||
if (vulkanDebugInfo) {
|
||||
const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
|
||||
NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
|
||||
switch (ext_inst_key) {
|
||||
// The following block of instructions will be handled by the common
|
||||
// validation.
|
||||
case NonSemanticShaderDebugInfo100DebugInfoNone:
|
||||
case NonSemanticShaderDebugInfo100DebugCompilationUnit:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeBasic:
|
||||
case NonSemanticShaderDebugInfo100DebugTypePointer:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeQualifier:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeArray:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeVector:
|
||||
case NonSemanticShaderDebugInfo100DebugTypedef:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeFunction:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeEnum:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeComposite:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeMember:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeInheritance:
|
||||
case NonSemanticShaderDebugInfo100DebugTypePtrToMember:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplate:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter:
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack:
|
||||
case NonSemanticShaderDebugInfo100DebugGlobalVariable:
|
||||
case NonSemanticShaderDebugInfo100DebugFunctionDeclaration:
|
||||
case NonSemanticShaderDebugInfo100DebugFunction:
|
||||
case NonSemanticShaderDebugInfo100DebugLexicalBlock:
|
||||
case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator:
|
||||
case NonSemanticShaderDebugInfo100DebugScope:
|
||||
case NonSemanticShaderDebugInfo100DebugNoScope:
|
||||
case NonSemanticShaderDebugInfo100DebugInlinedAt:
|
||||
case NonSemanticShaderDebugInfo100DebugLocalVariable:
|
||||
case NonSemanticShaderDebugInfo100DebugInlinedVariable:
|
||||
case NonSemanticShaderDebugInfo100DebugDeclare:
|
||||
case NonSemanticShaderDebugInfo100DebugValue:
|
||||
case NonSemanticShaderDebugInfo100DebugOperation:
|
||||
case NonSemanticShaderDebugInfo100DebugExpression:
|
||||
case NonSemanticShaderDebugInfo100DebugMacroDef:
|
||||
case NonSemanticShaderDebugInfo100DebugMacroUndef:
|
||||
case NonSemanticShaderDebugInfo100DebugImportedEntity:
|
||||
case NonSemanticShaderDebugInfo100DebugSource:
|
||||
break;
|
||||
case NonSemanticShaderDebugInfo100DebugTypeMatrix: {
|
||||
CHECK_DEBUG_OPERAND("Vector Type", CommonDebugInfoDebugTypeVector, 5);
|
||||
|
||||
CHECK_CONST_UINT_OPERAND("Vector Count", 6);
|
||||
|
||||
uint32_t vector_count = inst->word(6);
|
||||
uint64_t const_val;
|
||||
if (!_.GetConstantValUint64(vector_count, &const_val)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< ext_inst_name()
|
||||
<< ": Vector Count must be 32-bit integer OpConstant";
|
||||
}
|
||||
|
||||
vector_count = const_val & 0xffffffff;
|
||||
if (!vector_count || vector_count > 4) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< ext_inst_name() << ": Vector Count must be positive "
|
||||
<< "integer less than or equal to 4";
|
||||
}
|
||||
break;
|
||||
}
|
||||
// TODO: Add validation rules for remaining cases as well.
|
||||
case NonSemanticShaderDebugInfo100DebugFunctionDefinition:
|
||||
case NonSemanticShaderDebugInfo100DebugSourceContinued:
|
||||
case NonSemanticShaderDebugInfo100DebugLine:
|
||||
case NonSemanticShaderDebugInfo100DebugNoLine:
|
||||
case NonSemanticShaderDebugInfo100DebugBuildIdentifier:
|
||||
case NonSemanticShaderDebugInfo100DebugStoragePath:
|
||||
case NonSemanticShaderDebugInfo100DebugEntryPoint:
|
||||
break;
|
||||
case NonSemanticShaderDebugInfo100InstructionsMax:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle any non-common OpenCL insts, then common
|
||||
if (ext_inst_type != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
|
||||
OpenCLDebugInfo100Instructions(ext_inst_index) !=
|
||||
|
@ -596,23 +596,23 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vulkan Appendix A: Check that if contains initializer, then
|
||||
// storage class is Output, Private, or Function.
|
||||
if (inst->operands().size() > 3 && storage_class != SpvStorageClassOutput &&
|
||||
storage_class != SpvStorageClassPrivate &&
|
||||
storage_class != SpvStorageClassFunction) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
// Initializers in Vulkan are only allowed in some storage clases
|
||||
if (inst->operands().size() > 3) {
|
||||
if (storage_class == SpvStorageClassWorkgroup) {
|
||||
auto init_id = inst->GetOperandAs<uint32_t>(3);
|
||||
auto init = _.FindDef(init_id);
|
||||
if (init->opcode() != SpvOpConstantNull) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "Variable initializers in Workgroup storage class are "
|
||||
"limited to OpConstantNull";
|
||||
<< _.VkErrorID(4734) << "OpVariable, <id> '"
|
||||
<< _.getIdName(inst->id())
|
||||
<< "', initializers are limited to OpConstantNull in "
|
||||
"Workgroup "
|
||||
"storage class";
|
||||
}
|
||||
} else {
|
||||
} else if (storage_class != SpvStorageClassOutput &&
|
||||
storage_class != SpvStorageClassPrivate &&
|
||||
storage_class != SpvStorageClassFunction) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< _.VkErrorID(4651) << "OpVariable, <id> '"
|
||||
<< _.getIdName(inst->id())
|
||||
|
@ -1882,6 +1882,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732);
|
||||
case 4733:
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733);
|
||||
case 4734:
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734);
|
||||
case 4780:
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-Result-04780);
|
||||
case 4915:
|
||||
|
Loading…
Reference in New Issue
Block a user