diff --git a/3rdparty/spirv-tools/include/generated/build-version.inc b/3rdparty/spirv-tools/include/generated/build-version.inc index 9f8a87129..b052f188f 100644 --- a/3rdparty/spirv-tools/include/generated/build-version.inc +++ b/3rdparty/spirv-tools/include/generated/build-version.inc @@ -1 +1 @@ -"v2022.2-dev", "SPIRV-Tools v2022.2-dev 5ae22716672dc8dbefc3b24f142ffa9f50bab74c" +"v2022.3-dev", "SPIRV-Tools v2022.3-dev 560669f6c0e19daf8f29e1f085599f0765e4ee35" diff --git a/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc b/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc index 9b25055c0..d3a781e71 100644 --- a/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc +++ b/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc @@ -28,6 +28,7 @@ static const SpvCapability pygen_variable_caps_GroupNonUniformArithmeticGroupNon static const SpvCapability pygen_variable_caps_GroupNonUniformBallot[] = {SpvCapabilityGroupNonUniformBallot}; static const SpvCapability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformPartitionedNV}; static const SpvCapability pygen_variable_caps_GroupNonUniformQuad[] = {SpvCapabilityGroupNonUniformQuad}; +static const SpvCapability pygen_variable_caps_GroupNonUniformRotateKHR[] = {SpvCapabilityGroupNonUniformRotateKHR}; static const SpvCapability pygen_variable_caps_GroupNonUniformShuffle[] = {SpvCapabilityGroupNonUniformShuffle}; static const SpvCapability pygen_variable_caps_GroupNonUniformShuffleRelative[] = {SpvCapabilityGroupNonUniformShuffleRelative}; static const SpvCapability pygen_variable_caps_GroupNonUniformVote[] = {SpvCapabilityGroupNonUniformVote}; @@ -454,6 +455,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = { {"SubgroupAllKHR", SpvOpSubgroupAllKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, {"SubgroupAnyKHR", SpvOpSubgroupAnyKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, {"SubgroupAllEqualKHR", SpvOpSubgroupAllEqualKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformRotateKHR", SpvOpGroupNonUniformRotateKHR, 1, pygen_variable_caps_GroupNonUniformRotateKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SubgroupReadInvocationKHR", SpvOpSubgroupReadInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, {"TraceRayKHR", SpvOpTraceRayKHR, 1, pygen_variable_caps_RayTracingKHR, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, {"ExecuteCallableKHR", SpvOpExecuteCallableKHR, 1, pygen_variable_caps_RayTracingKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, diff --git a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc index b7c1c90e4..a0b618ff3 100644 --- a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc +++ b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc @@ -140,6 +140,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_KHR_physical_storage_buffer"; case Extension::kSPV_KHR_post_depth_coverage: return "SPV_KHR_post_depth_coverage"; + case Extension::kSPV_KHR_ray_cull_mask: + return "SPV_KHR_ray_cull_mask"; case Extension::kSPV_KHR_ray_query: return "SPV_KHR_ray_query"; case Extension::kSPV_KHR_ray_tracing: @@ -154,6 +156,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_KHR_shader_draw_parameters"; case Extension::kSPV_KHR_storage_buffer_storage_class: return "SPV_KHR_storage_buffer_storage_class"; + case Extension::kSPV_KHR_subgroup_rotate: + return "SPV_KHR_subgroup_rotate"; case Extension::kSPV_KHR_subgroup_uniform_control_flow: return "SPV_KHR_subgroup_uniform_control_flow"; case Extension::kSPV_KHR_subgroup_vote: @@ -209,8 +213,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_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_uniform_group_instructions", "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_uniform_group_instructions, 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_cull_mask", "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_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "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_cull_mask, 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_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, 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( @@ -602,8 +606,12 @@ const char* CapabilityToString(SpvCapability capability) { return "DotProductInput4x8BitPacked"; case SpvCapabilityDotProduct: return "DotProduct"; + case SpvCapabilityRayCullMaskKHR: + return "RayCullMaskKHR"; case SpvCapabilityBitInstructions: return "BitInstructions"; + case SpvCapabilityGroupNonUniformRotateKHR: + return "GroupNonUniformRotateKHR"; case SpvCapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; case SpvCapabilityAtomicFloat64AddEXT: diff --git a/3rdparty/spirv-tools/include/generated/extension_enum.inc b/3rdparty/spirv-tools/include/generated/extension_enum.inc index 126846452..649d0c02d 100644 --- a/3rdparty/spirv-tools/include/generated/extension_enum.inc +++ b/3rdparty/spirv-tools/include/generated/extension_enum.inc @@ -68,6 +68,7 @@ kSPV_KHR_no_integer_wrap_decoration, kSPV_KHR_non_semantic_info, kSPV_KHR_physical_storage_buffer, kSPV_KHR_post_depth_coverage, +kSPV_KHR_ray_cull_mask, kSPV_KHR_ray_query, kSPV_KHR_ray_tracing, kSPV_KHR_shader_atomic_counter_ops, @@ -75,6 +76,7 @@ kSPV_KHR_shader_ballot, kSPV_KHR_shader_clock, kSPV_KHR_shader_draw_parameters, kSPV_KHR_storage_buffer_storage_class, +kSPV_KHR_subgroup_rotate, kSPV_KHR_subgroup_uniform_control_flow, kSPV_KHR_subgroup_vote, kSPV_KHR_terminate_invocation, diff --git a/3rdparty/spirv-tools/include/generated/generators.inc b/3rdparty/spirv-tools/include/generated/generators.inc index 6adca7886..35d190dfe 100644 --- a/3rdparty/spirv-tools/include/generated/generators.inc +++ b/3rdparty/spirv-tools/include/generated/generators.inc @@ -31,4 +31,5 @@ {30, "SpvGenTwo community", "SpvGenTwo SPIR-V IR Tools", "SpvGenTwo community SpvGenTwo SPIR-V IR Tools"}, {31, "Google", "Skia SkSL", "Google Skia SkSL"}, {32, "TornadoVM", "SPIRV Beehive Toolkit", "TornadoVM SPIRV Beehive Toolkit"}, -{33, "DragonJoker", "ShaderWriter", "DragonJoker ShaderWriter"}, \ No newline at end of file +{33, "DragonJoker", "ShaderWriter", "DragonJoker ShaderWriter"}, +{34, "Rayan Hatout", "SPIRVSmith", "Rayan Hatout SPIRVSmith"}, \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc b/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc index 60c1e1347..610783c50 100644 --- a/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc +++ b/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc @@ -70,6 +70,7 @@ static const SpvCapability pygen_variable_caps_OptNoneINTEL[] = {SpvCapabilityOp static const SpvCapability pygen_variable_caps_PerViewAttributesNVMeshShadingNV[] = {SpvCapabilityPerViewAttributesNV, SpvCapabilityMeshShadingNV}; static const SpvCapability pygen_variable_caps_PhysicalStorageBufferAddresses[] = {SpvCapabilityPhysicalStorageBufferAddresses}; static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes}; +static const SpvCapability pygen_variable_caps_RayCullMaskKHR[] = {SpvCapabilityRayCullMaskKHR}; static const SpvCapability pygen_variable_caps_RayQueryKHR[] = {SpvCapabilityRayQueryKHR}; static const SpvCapability pygen_variable_caps_RayQueryKHRRayTracingKHR[] = {SpvCapabilityRayQueryKHR, SpvCapabilityRayTracingKHR}; static const SpvCapability pygen_variable_caps_RayTracingKHR[] = {SpvCapabilityRayTracingKHR}; @@ -183,6 +184,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_linkonce_odr[] = {s static const spvtools::Extension pygen_variable_exts_SPV_KHR_multiview[] = {spvtools::Extension::kSPV_KHR_multiview}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration[] = {spvtools::Extension::kSPV_KHR_no_integer_wrap_decoration}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_post_depth_coverage[] = {spvtools::Extension::kSPV_KHR_post_depth_coverage}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_cull_mask[] = {spvtools::Extension::kSPV_KHR_ray_cull_mask}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_querySPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_query, spvtools::Extension::kSPV_KHR_ray_tracing}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing}; @@ -193,6 +195,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {s static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parameters[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parametersSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters, spvtools::Extension::kSPV_NV_mesh_shader}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_storage_buffer_storage_class, spvtools::Extension::kSPV_KHR_variable_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_rotate[] = {spvtools::Extension::kSPV_KHR_subgroup_rotate}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_uniform_control_flow[] = {spvtools::Extension::kSPV_KHR_subgroup_uniform_control_flow}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_uniform_group_instructions[] = {spvtools::Extension::kSPV_KHR_uniform_group_instructions}; @@ -357,7 +360,8 @@ static const spv_operand_desc_t pygen_variable_SourceLanguageEntries[] = { {"OpenCL_C", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"OpenCL_CPP", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"HLSL", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, - {"CPP_for_OpenCL", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} + {"CPP_for_OpenCL", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SYCL", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_ExecutionModelEntries[] = { @@ -467,7 +471,8 @@ static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = { {"MaxWorkDimINTEL", 5894, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"NoGlobalOffsetINTEL", 5895, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, {"NumSIMDWorkitemsINTEL", 5896, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, - {"SchedulerTargetFmaxMhzINTEL", 5903, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} + {"SchedulerTargetFmaxMhzINTEL", 5903, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"NamedBarrierCountINTEL", 6417, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = { @@ -907,7 +912,8 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = { {"WarpsPerSMNV", 5374, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, {"SMCountNV", 5375, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, {"WarpIDNV", 5376, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, - {"SMIDNV", 5377, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu} + {"SMIDNV", 5377, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"CullMaskKHR", 6021, 1, pygen_variable_caps_RayCullMaskKHR, 1, pygen_variable_exts_SPV_KHR_ray_cull_mask, {}, 0xffffffffu, 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_ScopeEntries[] = { @@ -1151,7 +1157,9 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"DotProductInput4x8BitPackedKHR", 6018, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, {"DotProduct", 6019, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, {"DotProductKHR", 6019, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"RayCullMaskKHR", 6020, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_ray_cull_mask, {}, 0xffffffffu, 0xffffffffu}, {"BitInstructions", 6025, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_bit_instructions, {}, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformRotateKHR", 6026, 1, pygen_variable_caps_GroupNonUniform, 1, pygen_variable_exts_SPV_KHR_subgroup_rotate, {}, 0xffffffffu, 0xffffffffu}, {"AtomicFloat32AddEXT", 6033, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu}, {"AtomicFloat64AddEXT", 6034, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu}, {"LongConstantCompositeINTEL", 6089, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_long_constant_composite, {}, 0xffffffffu, 0xffffffffu}, diff --git a/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp b/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp index fbbd9bc07..df830d7f8 100644 --- a/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp +++ b/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp @@ -907,6 +907,11 @@ Optimizer::PassToken CreateConvertToSampledImagePass( // from every function in the module. This is useful if you want the inliner to // inline these functions some reason. Optimizer::PassToken CreateRemoveDontInlinePass(); +// Create a fix-func-call-param pass to fix non memory argument for the function +// call, as spirv-validation requires function parameters to be an memory +// object, currently the pass would remove accesschain pointer argument passed +// to the function +Optimizer::PassToken CreateFixFuncCallArgumentsPass(); } // namespace spvtools #endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ diff --git a/3rdparty/spirv-tools/source/link/linker.cpp b/3rdparty/spirv-tools/source/link/linker.cpp index 76ce775d5..3b388cc6e 100644 --- a/3rdparty/spirv-tools/source/link/linker.cpp +++ b/3rdparty/spirv-tools/source/link/linker.cpp @@ -34,6 +34,7 @@ #include "source/opt/ir_loader.h" #include "source/opt/pass_manager.h" #include "source/opt/remove_duplicates_pass.h" +#include "source/opt/remove_unused_interface_variables_pass.h" #include "source/opt/type_manager.h" #include "source/spirv_constant.h" #include "source/spirv_target_env.h" @@ -807,11 +808,16 @@ spv_result_t Link(const Context& context, const uint32_t* const* binaries, pass_res = manager.Run(&linked_context); if (pass_res == opt::Pass::Status::Failure) return SPV_ERROR_INVALID_DATA; - // Phase 11: Warn if SPIR-V limits were exceeded + // Phase 11: Recompute EntryPoint variables + manager.AddPass(); + pass_res = manager.Run(&linked_context); + if (pass_res == opt::Pass::Status::Failure) return SPV_ERROR_INVALID_DATA; + + // Phase 12: Warn if SPIR-V limits were exceeded res = VerifyLimits(consumer, linked_context); if (res != SPV_SUCCESS) return res; - // Phase 12: Output the module + // Phase 13: Output the module linked_context.module()->ToBinary(linked_binary, true); return SPV_SUCCESS; diff --git a/3rdparty/spirv-tools/source/opcode.cpp b/3rdparty/spirv-tools/source/opcode.cpp index c9c425d8b..2584d51eb 100644 --- a/3rdparty/spirv-tools/source/opcode.cpp +++ b/3rdparty/spirv-tools/source/opcode.cpp @@ -528,6 +528,7 @@ bool spvOpcodeIsNonUniformGroupOperation(SpvOp opcode) { case SpvOpGroupNonUniformLogicalXor: case SpvOpGroupNonUniformQuadBroadcast: case SpvOpGroupNonUniformQuadSwap: + case SpvOpGroupNonUniformRotateKHR: return true; default: return false; diff --git a/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.cpp b/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.cpp new file mode 100644 index 000000000..d140fb4b0 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.cpp @@ -0,0 +1,90 @@ +// Copyright (c) 2022 Advanced Micro Devices, 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. + +#include "fix_func_call_arguments.h" + +#include "ir_builder.h" + +using namespace spvtools; +using namespace opt; + +bool FixFuncCallArgumentsPass::ModuleHasASingleFunction() { + auto funcsNum = get_module()->end() - get_module()->begin(); + return funcsNum == 1; +} + +Pass::Status FixFuncCallArgumentsPass::Process() { + bool modified = false; + if (ModuleHasASingleFunction()) return Status::SuccessWithoutChange; + for (auto& func : *get_module()) { + func.ForEachInst([this, &modified](Instruction* inst) { + if (inst->opcode() == SpvOpFunctionCall) { + modified |= FixFuncCallArguments(inst); + } + }); + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool FixFuncCallArgumentsPass::FixFuncCallArguments( + Instruction* func_call_inst) { + bool modified = false; + for (uint32_t i = 0; i < func_call_inst->NumInOperands(); ++i) { + Operand& op = func_call_inst->GetInOperand(i); + if (op.type != SPV_OPERAND_TYPE_ID) continue; + Instruction* operand_inst = get_def_use_mgr()->GetDef(op.AsId()); + if (operand_inst->opcode() == SpvOpAccessChain) { + uint32_t var_id = + ReplaceAccessChainFuncCallArguments(func_call_inst, operand_inst); + func_call_inst->SetInOperand(i, {var_id}); + modified = true; + } + } + if (modified) { + context()->UpdateDefUse(func_call_inst); + } + return modified; +} + +uint32_t FixFuncCallArgumentsPass::ReplaceAccessChainFuncCallArguments( + Instruction* func_call_inst, Instruction* operand_inst) { + InstructionBuilder builder( + context(), func_call_inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + Instruction* next_insert_point = func_call_inst->NextNode(); + // Get Variable insertion point + Function* func = context()->get_instr_block(func_call_inst)->GetParent(); + Instruction* variable_insertion_point = &*(func->begin()->begin()); + Instruction* op_ptr_type = get_def_use_mgr()->GetDef(operand_inst->type_id()); + Instruction* op_type = + get_def_use_mgr()->GetDef(op_ptr_type->GetSingleWordInOperand(1)); + uint32_t varType = context()->get_type_mgr()->FindPointerToType( + op_type->result_id(), SpvStorageClassFunction); + // Create new variable + builder.SetInsertPoint(variable_insertion_point); + Instruction* var = builder.AddVariable(varType, SpvStorageClassFunction); + // Load access chain to the new variable before function call + builder.SetInsertPoint(func_call_inst); + + uint32_t operand_id = operand_inst->result_id(); + Instruction* load = builder.AddLoad(op_type->result_id(), operand_id); + builder.AddStore(var->result_id(), load->result_id()); + // Load return value to the acesschain after function call + builder.SetInsertPoint(next_insert_point); + load = builder.AddLoad(op_type->result_id(), var->result_id()); + builder.AddStore(operand_id, load->result_id()); + + return var->result_id(); +} diff --git a/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.h b/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.h new file mode 100644 index 000000000..15781b8c6 --- /dev/null +++ b/3rdparty/spirv-tools/source/opt/fix_func_call_arguments.h @@ -0,0 +1,47 @@ +// Copyright (c) 2022 Advanced Micro Devices, 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 _VAR_FUNC_CALL_PASS_H +#define _VAR_FUNC_CALL_PASS_H + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { +class FixFuncCallArgumentsPass : public Pass { + public: + FixFuncCallArgumentsPass() {} + const char* name() const override { return "fix-for-funcall-param"; } + Status Process() override; + // Returns true if the module has one one function. + bool ModuleHasASingleFunction(); + // Copies from the memory pointed to by |operand_inst| to a new function scope + // variable created before |func_call_inst|, and + // copies the value of the new variable back to the memory pointed to by + // |operand_inst| after |funct_call_inst| Returns the id of + // the new variable. + uint32_t ReplaceAccessChainFuncCallArguments(Instruction* func_call_inst, + Instruction* operand_inst); + + // Fix function call |func_call_inst| non memory object arguments + bool FixFuncCallArguments(Instruction* func_call_inst); + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisTypes; + } +}; +} // namespace opt +} // namespace spvtools + +#endif // _VAR_FUNC_CALL_PASS_H \ No newline at end of file diff --git a/3rdparty/spirv-tools/source/opt/folding_rules.cpp b/3rdparty/spirv-tools/source/opt/folding_rules.cpp index c879a0c50..d15ad0437 100644 --- a/3rdparty/spirv-tools/source/opt/folding_rules.cpp +++ b/3rdparty/spirv-tools/source/opt/folding_rules.cpp @@ -1430,6 +1430,64 @@ FoldingRule FactorAddMuls() { }; } +// Replaces |inst| inplace with an FMA instruction |(x*y)+a|. +void ReplaceWithFma(Instruction* inst, uint32_t x, uint32_t y, uint32_t a) { + uint32_t ext = + inst->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + + if (ext == 0) { + inst->context()->AddExtInstImport("GLSL.std.450"); + ext = inst->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + assert(ext != 0 && + "Could not add the GLSL.std.450 extended instruction set"); + } + + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {ext}}); + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {GLSLstd450Fma}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {x}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {a}}); + + inst->SetOpcode(SpvOpExtInst); + inst->SetInOperands(std::move(operands)); +} + +// Folds a multiple and add into an Fma. +// +// Cases: +// (x * y) + a = Fma x y a +// a + (x * y) = Fma x y a +bool MergeMulAddArithmetic(IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == SpvOpFAdd); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + for (int i = 0; i < 2; i++) { + uint32_t op_id = inst->GetSingleWordInOperand(i); + Instruction* op_inst = def_use_mgr->GetDef(op_id); + + if (op_inst->opcode() != SpvOpFMul) { + continue; + } + + if (!op_inst->IsFloatingPointFoldingAllowed()) { + continue; + } + + uint32_t x = op_inst->GetSingleWordInOperand(0); + uint32_t y = op_inst->GetSingleWordInOperand(1); + uint32_t a = inst->GetSingleWordInOperand((i + 1) % 2); + ReplaceWithFma(inst, x, y, a); + return true; + } + return false; +} + FoldingRule IntMultipleBy1() { return [](IRContext*, Instruction* inst, const std::vector& constants) { @@ -2543,6 +2601,7 @@ void FoldingRules::AddFoldingRules() { rules_[SpvOpFAdd].push_back(MergeAddSubArithmetic()); rules_[SpvOpFAdd].push_back(MergeGenericAddSubArithmetic()); rules_[SpvOpFAdd].push_back(FactorAddMuls()); + rules_[SpvOpFAdd].push_back(MergeMulAddArithmetic); rules_[SpvOpFDiv].push_back(RedundantFDiv()); rules_[SpvOpFDiv].push_back(ReciprocalFDiv()); diff --git a/3rdparty/spirv-tools/source/opt/if_conversion.cpp b/3rdparty/spirv-tools/source/opt/if_conversion.cpp index 492066177..d1debd055 100644 --- a/3rdparty/spirv-tools/source/opt/if_conversion.cpp +++ b/3rdparty/spirv-tools/source/opt/if_conversion.cpp @@ -169,6 +169,8 @@ bool IfConversion::CheckBlock(BasicBlock* block, DominatorAnalysis* dominators, if (branch->opcode() != SpvOpBranchConditional) return false; auto merge = (*common)->GetMergeInst(); if (!merge || merge->opcode() != SpvOpSelectionMerge) return false; + if (merge->GetSingleWordInOperand(1) == SpvSelectionControlDontFlattenMask) + return false; if ((*common)->MergeBlockIdIfAny() != block->id()) return false; return true; diff --git a/3rdparty/spirv-tools/source/opt/ir_builder.h b/3rdparty/spirv-tools/source/opt/ir_builder.h index 4433cf0d1..9d4fa8fe3 100644 --- a/3rdparty/spirv-tools/source/opt/ir_builder.h +++ b/3rdparty/spirv-tools/source/opt/ir_builder.h @@ -487,6 +487,15 @@ class InstructionBuilder { return AddInstruction(std::move(new_inst)); } + Instruction* AddVariable(uint32_t type_id, uint32_t storage_class) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {storage_class}}); + std::unique_ptr new_inst( + new Instruction(GetContext(), SpvOpVariable, type_id, + GetContext()->TakeNextId(), operands)); + return AddInstruction(std::move(new_inst)); + } + Instruction* AddStore(uint32_t ptr_id, uint32_t obj_id) { std::vector operands; operands.push_back({SPV_OPERAND_TYPE_ID, {ptr_id}}); diff --git a/3rdparty/spirv-tools/source/opt/ir_context.cpp b/3rdparty/spirv-tools/source/opt/ir_context.cpp index a80d4f2de..c9c3f1b5d 100644 --- a/3rdparty/spirv-tools/source/opt/ir_context.cpp +++ b/3rdparty/spirv-tools/source/opt/ir_context.cpp @@ -926,6 +926,19 @@ bool IRContext::ProcessCallTreeFromRoots(ProcessFunction& pfn, return modified; } +void IRContext::CollectCallTreeFromRoots(unsigned entryId, + std::unordered_set* funcs) { + std::queue roots; + roots.push(entryId); + while (!roots.empty()) { + const uint32_t fi = roots.front(); + roots.pop(); + funcs->insert(fi); + Function* fn = GetFunction(fi); + AddCalls(fn, &roots); + } +} + void IRContext::EmitErrorMessage(std::string message, Instruction* inst) { if (!consumer()) { return; diff --git a/3rdparty/spirv-tools/source/opt/ir_context.h b/3rdparty/spirv-tools/source/opt/ir_context.h index 946f9e9d0..f9f51532b 100644 --- a/3rdparty/spirv-tools/source/opt/ir_context.h +++ b/3rdparty/spirv-tools/source/opt/ir_context.h @@ -411,6 +411,10 @@ class IRContext { void CollectNonSemanticTree(Instruction* inst, std::unordered_set* to_kill); + // Collect function reachable from |entryId|, returns |funcs| + void CollectCallTreeFromRoots(unsigned entryId, + std::unordered_set* funcs); + // Returns true if all of the given analyses are valid. bool AreAnalysesValid(Analysis set) { return (set & valid_analyses_) == set; } diff --git a/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp b/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp index 9bc495e51..4feb64e86 100644 --- a/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp +++ b/3rdparty/spirv-tools/source/opt/loop_descriptor.cpp @@ -754,6 +754,10 @@ bool Loop::FindNumberOfIterations(const Instruction* induction, // |step_value| is NOT cleanly divisible then we add one to the sum. int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, int64_t init_value, int64_t step_value) const { + if (step_value == 0) { + return 0; + } + int64_t diff = 0; switch (condition) { diff --git a/3rdparty/spirv-tools/source/opt/loop_descriptor.h b/3rdparty/spirv-tools/source/opt/loop_descriptor.h index e88ff9363..df012274c 100644 --- a/3rdparty/spirv-tools/source/opt/loop_descriptor.h +++ b/3rdparty/spirv-tools/source/opt/loop_descriptor.h @@ -398,7 +398,8 @@ class Loop { // Each different loop |condition| affects how we calculate the number of // iterations using the |condition_value|, |init_value|, and |step_values| of // the induction variable. This method will return the number of iterations in - // a loop with those values for a given |condition|. + // a loop with those values for a given |condition|. Returns 0 if the number + // of iterations could not be computed. int64_t GetIterations(SpvOp condition, int64_t condition_value, int64_t init_value, int64_t step_value) const; diff --git a/3rdparty/spirv-tools/source/opt/optimizer.cpp b/3rdparty/spirv-tools/source/opt/optimizer.cpp index f28b1baf2..051d573d8 100644 --- a/3rdparty/spirv-tools/source/opt/optimizer.cpp +++ b/3rdparty/spirv-tools/source/opt/optimizer.cpp @@ -525,6 +525,8 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) { RegisterPass(CreateRemoveDontInlinePass()); } else if (pass_name == "eliminate-dead-input-components") { RegisterPass(CreateEliminateDeadInputComponentsPass()); + } else if (pass_name == "fix-func-call-param") { + RegisterPass(CreateFixFuncCallArgumentsPass()); } else if (pass_name == "convert-to-sampled-image") { if (pass_args.size() > 0) { auto descriptor_set_binding_pairs = @@ -1022,4 +1024,9 @@ Optimizer::PassToken CreateRemoveDontInlinePass() { return MakeUnique( MakeUnique()); } + +Optimizer::PassToken CreateFixFuncCallArgumentsPass() { + return MakeUnique( + MakeUnique()); +} } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/passes.h b/3rdparty/spirv-tools/source/opt/passes.h index a12c76b81..facaa410e 100644 --- a/3rdparty/spirv-tools/source/opt/passes.h +++ b/3rdparty/spirv-tools/source/opt/passes.h @@ -37,6 +37,7 @@ #include "source/opt/eliminate_dead_input_components_pass.h" #include "source/opt/eliminate_dead_members_pass.h" #include "source/opt/empty_pass.h" +#include "source/opt/fix_func_call_arguments.h" #include "source/opt/fix_storage_class.h" #include "source/opt/flatten_decoration_pass.h" #include "source/opt/fold_spec_constant_op_and_composite_pass.h" diff --git a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp index a1d34329a..b61fd0f4c 100644 --- a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp +++ b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp @@ -68,38 +68,12 @@ bool HasVolatileDecoration(analysis::DecorationManager* decoration_manager, return decoration_manager->HasDecoration(var_id, SpvDecorationVolatile); } -bool HasOnlyEntryPointsAsFunctions(IRContext* context, Module* module) { - std::unordered_set entry_function_ids; - for (Instruction& entry_point : module->entry_points()) { - entry_function_ids.insert( - entry_point.GetSingleWordInOperand(kOpEntryPointInOperandEntryPoint)); - } - for (auto& function : *module) { - if (entry_function_ids.find(function.result_id()) == - entry_function_ids.end()) { - std::string message( - "Functions of SPIR-V for spread-volatile-semantics pass input must " - "be inlined except entry points"); - message += "\n " + function.DefInst().PrettyPrint( - SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); - context->consumer()(SPV_MSG_ERROR, "", {0, 0, 0}, message.c_str()); - return false; - } - } - return true; -} - } // namespace Pass::Status SpreadVolatileSemantics::Process() { if (HasNoExecutionModel()) { return Status::SuccessWithoutChange; } - - if (!HasOnlyEntryPointsAsFunctions(context(), get_module())) { - return Status::Failure; - } - const bool is_vk_memory_model_enabled = context()->get_feature_mgr()->HasCapability( SpvCapabilityVulkanMemoryModel); @@ -142,6 +116,8 @@ bool SpreadVolatileSemantics::IsTargetUsedByNonVolatileLoadInEntryPoint( uint32_t var_id, Instruction* entry_point) { uint32_t entry_function_id = entry_point->GetSingleWordInOperand(kOpEntryPointInOperandEntryPoint); + std::unordered_set funcs; + context()->CollectCallTreeFromRoots(entry_function_id, &funcs); return !VisitLoadsOfPointersToVariableInEntries( var_id, [](Instruction* load) { @@ -154,7 +130,7 @@ bool SpreadVolatileSemantics::IsTargetUsedByNonVolatileLoadInEntryPoint( load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); return (memory_operands & SpvMemoryAccessVolatileMask) != 0; }, - {entry_function_id}); + funcs); } bool SpreadVolatileSemantics::HasInterfaceInConflictOfVolatileSemantics() { @@ -225,7 +201,7 @@ void SpreadVolatileSemantics::DecorateVarWithVolatile(Instruction* var) { bool SpreadVolatileSemantics::VisitLoadsOfPointersToVariableInEntries( uint32_t var_id, const std::function& handle_load, - const std::unordered_set& entry_function_ids) { + const std::unordered_set& function_ids) { std::vector worklist({var_id}); auto* def_use_mgr = context()->get_def_use_mgr(); while (!worklist.empty()) { @@ -233,11 +209,11 @@ bool SpreadVolatileSemantics::VisitLoadsOfPointersToVariableInEntries( worklist.pop_back(); bool finish_traversal = !def_use_mgr->WhileEachUser( ptr_id, [this, &worklist, &ptr_id, handle_load, - &entry_function_ids](Instruction* user) { + &function_ids](Instruction* user) { BasicBlock* block = context()->get_instr_block(user); if (block == nullptr || - entry_function_ids.find(block->GetParent()->result_id()) == - entry_function_ids.end()) { + function_ids.find(block->GetParent()->result_id()) == + function_ids.end()) { return true; } @@ -266,21 +242,25 @@ void SpreadVolatileSemantics::SetVolatileForLoadsInEntries( Instruction* var, const std::unordered_set& entry_function_ids) { // Set Volatile memory operand for all load instructions if they do not have // it. - VisitLoadsOfPointersToVariableInEntries( - var->result_id(), - [](Instruction* load) { - if (load->NumInOperands() <= kOpLoadInOperandMemoryOperands) { - load->AddOperand( - {SPV_OPERAND_TYPE_MEMORY_ACCESS, {SpvMemoryAccessVolatileMask}}); + for (auto entry_id : entry_function_ids) { + std::unordered_set funcs; + context()->CollectCallTreeFromRoots(entry_id, &funcs); + VisitLoadsOfPointersToVariableInEntries( + var->result_id(), + [](Instruction* load) { + if (load->NumInOperands() <= kOpLoadInOperandMemoryOperands) { + load->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, + {SpvMemoryAccessVolatileMask}}); + return true; + } + uint32_t memory_operands = + load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); + memory_operands |= SpvMemoryAccessVolatileMask; + load->SetInOperand(kOpLoadInOperandMemoryOperands, {memory_operands}); return true; - } - uint32_t memory_operands = - load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); - memory_operands |= SpvMemoryAccessVolatileMask; - load->SetInOperand(kOpLoadInOperandMemoryOperands, {memory_operands}); - return true; - }, - entry_function_ids); + }, + funcs); + } } bool SpreadVolatileSemantics::IsTargetForVolatileSemantics( diff --git a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h index 531a21d50..014858d3f 100644 --- a/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h +++ b/3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h @@ -72,15 +72,14 @@ class SpreadVolatileSemantics : public Pass { Instruction* entry_point); // Visits load instructions of pointers to variable whose result id is - // |var_id| if the load instructions are in entry points whose - // function id is one of |entry_function_ids|. |handle_load| is a function to - // do some actions for the load instructions. Finishes the traversal and - // returns false if |handle_load| returns false for a load instruction. - // Otherwise, returns true after running |handle_load| for all the load - // instructions. + // |var_id| if the load instructions are in reachable functions from entry + // points. |handle_load| is a function to do some actions for the load + // instructions. Finishes the traversal and returns false if |handle_load| + // returns false for a load instruction. Otherwise, returns true after running + // |handle_load| for all the load instructions. bool VisitLoadsOfPointersToVariableInEntries( uint32_t var_id, const std::function& handle_load, - const std::unordered_set& entry_function_ids); + const std::unordered_set& function_ids); // Sets Memory Operands of OpLoad instructions that load |var| or pointers // of |var| as Volatile if the function id of the OpLoad instruction is diff --git a/3rdparty/spirv-tools/source/val/validate_builtins.cpp b/3rdparty/spirv-tools/source/val/validate_builtins.cpp index 57dde8ad9..0ee2b0978 100644 --- a/3rdparty/spirv-tools/source/val/validate_builtins.cpp +++ b/3rdparty/spirv-tools/source/val/validate_builtins.cpp @@ -120,7 +120,7 @@ typedef enum VUIDError_ { VUIDErrorMax, } VUIDError; -const static uint32_t NumVUIDBuiltins = 33; +const static uint32_t NumVUIDBuiltins = 34; typedef struct { SpvBuiltIn builtIn; @@ -162,6 +162,7 @@ std::array builtinVUIDInfo = {{ {SpvBuiltInFragSizeEXT, {4220, 4221, 4222}}, {SpvBuiltInFragStencilRefEXT, {4223, 4224, 4225}}, {SpvBuiltInFullyCoveredEXT, {4232, 4233, 4234}}, + {SpvBuiltInCullMaskKHR, {6735, 6736, 6737}}, // clang-format off } }; @@ -208,6 +209,7 @@ bool IsExecutionModelValidForRtBuiltIn(SpvBuiltIn builtin, case SpvBuiltInRayTmaxKHR: case SpvBuiltInWorldRayDirectionKHR: case SpvBuiltInWorldRayOriginKHR: + case SpvBuiltInCullMaskKHR: switch (stage) { case SpvExecutionModelIntersectionKHR: case SpvExecutionModelAnyHitKHR: @@ -3851,6 +3853,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( case SpvBuiltInInstanceId: case SpvBuiltInRayGeometryIndexKHR: case SpvBuiltInIncomingRayFlagsKHR: + case SpvBuiltInCullMaskKHR: // i32 scalar if (spv_result_t error = ValidateI32( decoration, inst, @@ -4151,7 +4154,8 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( case SpvBuiltInObjectToWorldKHR: // alias SpvBuiltInObjectToWorldNV case SpvBuiltInWorldToObjectKHR: // alias SpvBuiltInWorldToObjectNV case SpvBuiltInIncomingRayFlagsKHR: // alias SpvBuiltInIncomingRayFlagsNV - case SpvBuiltInRayGeometryIndexKHR: { // NOT present in NV + case SpvBuiltInRayGeometryIndexKHR: // NOT present in NV + case SpvBuiltInCullMaskKHR: { return ValidateRayTracingBuiltinsAtDefinition(decoration, inst); } case SpvBuiltInWorkDim: diff --git a/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp b/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp index 2b6eb8b5b..6d4f8a284 100644 --- a/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp +++ b/3rdparty/spirv-tools/source/val/validate_non_uniform.cpp @@ -63,6 +63,59 @@ spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _, return SPV_SUCCESS; } +spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _, + const Instruction* inst) { + // Scope is already checked by ValidateExecutionScope() above. + const uint32_t result_type = inst->type_id(); + if (!_.IsIntScalarOrVectorType(result_type) && + !_.IsFloatScalarOrVectorType(result_type) && + !_.IsBoolScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a scalar or vector of " + "floating-point, integer or boolean type."; + } + + const uint32_t value_type = _.GetTypeId(inst->GetOperandAs(3)); + if (value_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type must be the same as the type of Value."; + } + + const uint32_t delta_type = _.GetTypeId(inst->GetOperandAs(4)); + if (!_.IsUnsignedIntScalarType(delta_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Delta must be a scalar of integer type, whose Signedness " + "operand is 0."; + } + + if (inst->words().size() > 6) { + const uint32_t cluster_size_op_id = inst->GetOperandAs(5); + const uint32_t cluster_size_type = _.GetTypeId(cluster_size_op_id); + if (!_.IsUnsignedIntScalarType(cluster_size_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ClusterSize must be a scalar of integer type, whose " + "Signedness operand is 0."; + } + + uint64_t cluster_size; + if (!_.GetConstantValUint64(cluster_size_op_id, &cluster_size)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ClusterSize must come from a constant instruction."; + } + + if ((cluster_size == 0) || ((cluster_size & (cluster_size - 1)) != 0)) { + return _.diag(SPV_WARNING, inst) + << "Behavior is undefined unless ClusterSize is at least 1 and a " + "power of 2."; + } + + // TODO(kpet) Warn about undefined behavior when ClusterSize is greater than + // the declared SubGroupSize + } + + return SPV_SUCCESS; +} + } // namespace // Validates correctness of non-uniform group instructions. @@ -79,6 +132,8 @@ spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) { switch (opcode) { case SpvOpGroupNonUniformBallotBitCount: return ValidateGroupNonUniformBallotBitCount(_, inst); + case SpvOpGroupNonUniformRotateKHR: + return ValidateGroupNonUniformRotateKHR(_, inst); default: break; } diff --git a/3rdparty/spirv-tools/source/val/validation_state.cpp b/3rdparty/spirv-tools/source/val/validation_state.cpp index 9aa6c63e8..9ae6d0768 100644 --- a/3rdparty/spirv-tools/source/val/validation_state.cpp +++ b/3rdparty/spirv-tools/source/val/validation_state.cpp @@ -1443,6 +1443,12 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-CullDistance-CullDistance-04199); case 4200: return VUID_WRAP(VUID-CullDistance-CullDistance-04200); + case 6735: + return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06735); // Execution Model + case 6736: + return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06736); // input storage + case 6737: + return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06737); // 32 int scalar case 4205: return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04205); case 4206: @@ -1926,4 +1932,4 @@ std::string ValidationState_t::VkErrorID(uint32_t id, } } // namespace val -} // namespace spvtools \ No newline at end of file +} // namespace spvtools