diff --git a/3rdparty/spirv-tools/include/generated/DebugInfo.h b/3rdparty/spirv-tools/include/generated/DebugInfo.h index 9639ea107..0b3406cc8 100644 --- a/3rdparty/spirv-tools/include/generated/DebugInfo.h +++ b/3rdparty/spirv-tools/include/generated/DebugInfo.h @@ -134,4 +134,4 @@ enum DebugInfoDebugOperation { } #endif -#endif // SPIRV_EXTINST_DebugInfo_H_ +#endif // SPIRV_EXTINST_DebugInfo_H_ \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/build-version.inc b/3rdparty/spirv-tools/include/generated/build-version.inc index 00c5d1c7a..16d097b1b 100644 --- a/3rdparty/spirv-tools/include/generated/build-version.inc +++ b/3rdparty/spirv-tools/include/generated/build-version.inc @@ -1 +1 @@ -"v2019.4-dev", "SPIRV-Tools v2019.4-dev v2019.3-90-g76b75c40" +"v2019.4-dev", "SPIRV-Tools v2019.4-dev v2019.3-99-g65f49dfc" diff --git a/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc b/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc index 936b6052d..ad5451592 100644 --- a/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc +++ b/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc @@ -32,6 +32,7 @@ static const SpvCapability pygen_variable_caps_PipeStorage[] = {SpvCapabilityPip static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes}; static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV}; static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader}; +static const SpvCapability pygen_variable_caps_ShaderClockKHR[] = {SpvCapabilityShaderClockKHR}; static const SpvCapability pygen_variable_caps_SparseResidency[] = {SpvCapabilitySparseResidency}; static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL}; static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL}; @@ -51,6 +52,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_int static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_decorate_string, spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock}; 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_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix}; static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader}; @@ -419,6 +421,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = { {"GroupSMaxNonUniformAMD", SpvOpGroupSMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, {"FragmentMaskFetchAMD", SpvOpFragmentMaskFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 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_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu}, {"FragmentFetchAMD", SpvOpFragmentFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu}, + {"ReadClockKHR", SpvOpReadClockKHR, 1, pygen_variable_caps_ShaderClockKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_clock, 0xffffffffu, 0xffffffffu}, {"ImageSampleFootprintNV", SpvOpImageSampleFootprintNV, 1, pygen_variable_caps_ImageFootprintNV, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, 0xffffffffu, 0xffffffffu}, {"GroupNonUniformPartitionNV", SpvOpGroupNonUniformPartitionNV, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, 0xffffffffu, 0xffffffffu}, {"WritePackedPrimitiveIndices4x8NV", SpvOpWritePackedPrimitiveIndices4x8NV, 1, pygen_variable_caps_MeshShadingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_mesh_shader, 0xffffffffu, 0xffffffffu}, @@ -583,4 +586,4 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = { {"SubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SubgroupAvcSicGetInterRawSadsINTEL", SpvOpSubgroupAvcSicGetInterRawSadsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/debuginfo.insts.inc b/3rdparty/spirv-tools/include/generated/debuginfo.insts.inc index e28cc97d2..4fc30e3b0 100644 --- a/3rdparty/spirv-tools/include/generated/debuginfo.insts.inc +++ b/3rdparty/spirv-tools/include/generated/debuginfo.insts.inc @@ -35,4 +35,4 @@ static const spv_ext_inst_desc_t debuginfo_entries[] = { {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc index 44a9fd6b7..00cc64e0e 100644 --- a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc +++ b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc @@ -68,6 +68,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_KHR_shader_atomic_counter_ops"; case Extension::kSPV_KHR_shader_ballot: return "SPV_KHR_shader_ballot"; + case Extension::kSPV_KHR_shader_clock: + return "SPV_KHR_shader_clock"; case Extension::kSPV_KHR_shader_draw_parameters: return "SPV_KHR_shader_draw_parameters"; case Extension::kSPV_KHR_storage_buffer_storage_class: @@ -115,8 +117,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_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_post_depth_coverage", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "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_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_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_device_side_avc_motion_estimation, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, 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_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_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_post_depth_coverage", "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_vote", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "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_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_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_device_side_avc_motion_estimation, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_post_depth_coverage, 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_vote, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, 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_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( @@ -318,6 +320,8 @@ const char* CapabilityToString(SpvCapability capability) { return "StencilExportEXT"; case SpvCapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case SpvCapabilityShaderClockKHR: + return "ShaderClockKHR"; case SpvCapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; case SpvCapabilityGeometryShaderPassthroughNV: @@ -412,4 +416,4 @@ const char* CapabilityToString(SpvCapability capability) { }; return ""; -} +} \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/extension_enum.inc b/3rdparty/spirv-tools/include/generated/extension_enum.inc index 24ff0bc3f..81ee5f124 100644 --- a/3rdparty/spirv-tools/include/generated/extension_enum.inc +++ b/3rdparty/spirv-tools/include/generated/extension_enum.inc @@ -32,6 +32,7 @@ kSPV_KHR_no_integer_wrap_decoration, kSPV_KHR_post_depth_coverage, kSPV_KHR_shader_atomic_counter_ops, kSPV_KHR_shader_ballot, +kSPV_KHR_shader_clock, kSPV_KHR_shader_draw_parameters, kSPV_KHR_storage_buffer_storage_class, kSPV_KHR_subgroup_vote, @@ -51,4 +52,4 @@ kSPV_NV_shader_subgroup_partitioned, kSPV_NV_shading_rate, kSPV_NV_stereo_view_rendering, kSPV_NV_viewport_array2, -kSPV_VALIDATOR_ignore_type_decl_unique +kSPV_VALIDATOR_ignore_type_decl_unique \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/generators.inc b/3rdparty/spirv-tools/include/generated/generators.inc index 096a5630e..be262f96c 100644 --- a/3rdparty/spirv-tools/include/generated/generators.inc +++ b/3rdparty/spirv-tools/include/generated/generators.inc @@ -20,4 +20,4 @@ {19, "Clay", "Clay Shader Compiler", "Clay Clay Shader Compiler"}, {20, "W3C WebGPU Group", "WHLSL Shader Translator", "W3C WebGPU Group WHLSL Shader Translator"}, {21, "Google", "Clspv", "Google Clspv"}, -{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"}, +{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"}, \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc b/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc index 6bb2e7662..7d3866d80 100644 --- a/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc +++ b/3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc @@ -83,4 +83,4 @@ static const spv_ext_inst_desc_t glsl_entries[] = { {"NMin", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"NMax", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"NClamp", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/opencl.std.insts.inc b/3rdparty/spirv-tools/include/generated/opencl.std.insts.inc index abc76efc3..cd0a9c37a 100644 --- a/3rdparty/spirv-tools/include/generated/opencl.std.insts.inc +++ b/3rdparty/spirv-tools/include/generated/opencl.std.insts.inc @@ -163,4 +163,4 @@ static const spv_ext_inst_desc_t opencl_entries[] = { {"u_abs_diff", 202, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"u_mul_hi", 203, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"u_mad_hi", 204, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} -}; +}; \ 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 c47fb978f..4f9a9731c 100644 --- a/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc +++ b/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc @@ -114,6 +114,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_no_integer_wrap_dec 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_shader_atomic_counter_ops[] = {spvtools::Extension::kSPV_KHR_shader_atomic_counter_ops}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock}; 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}; @@ -781,6 +782,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"FragmentMaskAMD", 5010, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, {}, 0xffffffffu, 0xffffffffu}, {"StencilExportEXT", 5013, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, {"ImageReadWriteLodAMD", 5015, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_image_load_store_lod, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderClockKHR", 5055, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_clock, {}, 0xffffffffu, 0xffffffffu}, {"SampleMaskOverrideCoverageNV", 5249, 1, pygen_variable_caps_SampleRateShading, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu}, {"GeometryShaderPassthroughNV", 5251, 1, pygen_variable_caps_Geometry, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu}, {"ShaderViewportIndexLayerEXT", 5254, 1, pygen_variable_caps_MultiViewport, 2, pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, @@ -921,4 +923,4 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = { {SPV_OPERAND_TYPE_OPTIONAL_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries}, {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries}, {SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/spv-amd-gcn-shader.insts.inc b/3rdparty/spirv-tools/include/generated/spv-amd-gcn-shader.insts.inc index 48f7f4768..1682aff5f 100644 --- a/3rdparty/spirv-tools/include/generated/spv-amd-gcn-shader.insts.inc +++ b/3rdparty/spirv-tools/include/generated/spv-amd-gcn-shader.insts.inc @@ -4,4 +4,4 @@ static const spv_ext_inst_desc_t spv_amd_gcn_shader_entries[] = { {"CubeFaceIndexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"CubeFaceCoordAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"TimeAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_NONE}} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/spv-amd-shader-ballot.insts.inc b/3rdparty/spirv-tools/include/generated/spv-amd-shader-ballot.insts.inc index 6216051b9..c3b4aa09b 100644 --- a/3rdparty/spirv-tools/include/generated/spv-amd-shader-ballot.insts.inc +++ b/3rdparty/spirv-tools/include/generated/spv-amd-shader-ballot.insts.inc @@ -5,4 +5,4 @@ static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = { {"SwizzleInvocationsMaskedAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"WriteInvocationAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"MbcntAMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc b/3rdparty/spirv-tools/include/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc index 6b612854f..1ed559596 100644 --- a/3rdparty/spirv-tools/include/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc +++ b/3rdparty/spirv-tools/include/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc @@ -2,4 +2,4 @@ static const spv_ext_inst_desc_t spv_amd_shader_explicit_vertex_parameter_entries[] = { {"InterpolateAtVertexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/include/generated/spv-amd-shader-trinary-minmax.insts.inc b/3rdparty/spirv-tools/include/generated/spv-amd-shader-trinary-minmax.insts.inc index 061e862a4..af7ce826a 100644 --- a/3rdparty/spirv-tools/include/generated/spv-amd-shader-trinary-minmax.insts.inc +++ b/3rdparty/spirv-tools/include/generated/spv-amd-shader-trinary-minmax.insts.inc @@ -10,4 +10,4 @@ static const spv_ext_inst_desc_t spv_amd_shader_trinary_minmax_entries[] = { {"FMid3AMD", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"UMid3AMD", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, {"SMid3AMD", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} -}; +}; \ No newline at end of file diff --git a/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp b/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp index bc7ec874b..11a9574d9 100644 --- a/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp @@ -490,6 +490,28 @@ bool AggressiveDCEPass::AggressiveDCE(Function* func) { ProcessLoad(varId); } } + + // Add OpDecorateId instructions that apply to this instruction to the work + // list. We use the decoration manager to look through the group + // decorations to get to the OpDecorate* instructions themselves. + auto decorations = + get_decoration_mgr()->GetDecorationsFor(liveInst->result_id(), false); + for (Instruction* dec : decorations) { + // We only care about OpDecorateId instructions because the are the only + // decorations that will reference an id that will have to be kept live + // because of that use. + if (dec->opcode() != SpvOpDecorateId) { + continue; + } + if (dec->GetSingleWordInOperand(1) == + SpvDecorationHlslCounterBufferGOOGLE) { + // These decorations should not force the use id to be live. It will be + // removed if either the target or the in operand are dead. + continue; + } + AddToWorklist(dec); + } + worklist_.pop(); } @@ -618,14 +640,6 @@ Pass::Status AggressiveDCEPass::ProcessImpl() { // return unmodified. if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; - // If the decoration manager is kept live then the context will try to keep it - // up to date. ADCE deals with group decorations by changing the operands in - // |OpGroupDecorate| instruction directly without informing the decoration - // manager. This can put it in an invalid state which will cause an error - // when the context tries to update it. To avoid this problem invalidate - // the decoration manager upfront. - context()->InvalidateAnalyses(IRContext::Analysis::kAnalysisDecorations); - // Eliminate Dead functions. bool modified = EliminateDeadFunctions(); @@ -635,6 +649,17 @@ Pass::Status AggressiveDCEPass::ProcessImpl() { ProcessFunction pfn = [this](Function* fp) { return AggressiveDCE(fp); }; modified |= context()->ProcessEntryPointCallTree(pfn); + // If the decoration manager is kept live then the context will try to keep it + // up to date. ADCE deals with group decorations by changing the operands in + // |OpGroupDecorate| instruction directly without informing the decoration + // manager. This can put it in an invalid state which will cause an error + // when the context tries to update it. To avoid this problem invalidate + // the decoration manager upfront. + // + // We kill it at now because it is used when processing the entry point + // functions. + context()->InvalidateAnalyses(IRContext::Analysis::kAnalysisDecorations); + // Process module-level instructions. Now that all live instructions have // been marked, it is safe to remove dead global values. modified |= ProcessGlobalValues(); diff --git a/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp b/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp index 2eeab46e1..b283354b0 100644 --- a/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp @@ -398,20 +398,9 @@ void InstBindlessCheckPass::GenInitCheckCode( void InstBindlessCheckPass::InitializeInstBindlessCheck() { // Initialize base class InitializeInstrument(); - // Look for related extensions - ext_descriptor_indexing_defined_ = false; - for (auto& ei : get_module()->extensions()) { - const char* ext_name = - reinterpret_cast(&ei.GetInOperand(0).words[0]); - if (strcmp(ext_name, "SPV_EXT_descriptor_indexing") == 0) { - ext_descriptor_indexing_defined_ = true; - break; - } - } - // If descriptor indexing extension and runtime array length support enabled, - // create variable mappings. Length support is always enabled if descriptor - // init check is enabled. - if (ext_descriptor_indexing_defined_ && input_length_enabled_) + // If runtime array length support enabled, create variable mappings. Length + // support is always enabled if descriptor init check is enabled. + if (input_length_enabled_) for (auto& anno : get_module()->annotations()) if (anno.opcode() == SpvOpDecorate) { if (anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet) @@ -433,7 +422,7 @@ Pass::Status InstBindlessCheckPass::ProcessImpl() { new_blocks); }; bool modified = InstProcessEntryPointCallTree(pfn); - if (ext_descriptor_indexing_defined_ && input_init_enabled_) { + if (input_init_enabled_) { // Perform descriptor initialization check on each entry point function in // module pfn = [this](BasicBlock::iterator ref_inst_itr, diff --git a/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.h b/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.h index 12384b1fd..51d771277 100644 --- a/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.h +++ b/3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.h @@ -162,9 +162,6 @@ class InstBindlessCheckPass : public InstrumentPass { // GenInitCheckCode to every instruction in module. Pass::Status ProcessImpl(); - // True if VK_EXT_descriptor_indexing is defined - bool ext_descriptor_indexing_defined_; - // Enable instrumentation of runtime array length checking bool input_length_enabled_; diff --git a/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp b/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp index 6e7284baf..b938b2fe9 100644 --- a/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/merge_return_pass.cpp @@ -81,6 +81,7 @@ bool MergeReturnPass::ProcessStructured( return false; } + RecordImmediateDominators(function); AddDummyLoopAroundFunction(); std::list order; @@ -236,10 +237,6 @@ void MergeReturnPass::UpdatePhiNodes(BasicBlock* new_source, inst->AddOperand({SPV_OPERAND_TYPE_ID, {new_source->id()}}); context()->UpdateDefUse(inst); }); - - // Store the immediate dominator for this block in case new phi nodes will be - // needed later. - RecordImmediateDominator(target); } void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, @@ -683,7 +680,7 @@ void MergeReturnPass::AddNewPhiNodes(BasicBlock* bb) { return; } - BasicBlock* current_bb = new_merge_nodes_[bb]; + BasicBlock* current_bb = context()->get_instr_block(original_dominator_[bb]); while (current_bb != nullptr && current_bb != dominator) { for (Instruction& inst : *current_bb) { CreatePhiNodesForInst(bb, inst); @@ -692,11 +689,16 @@ void MergeReturnPass::AddNewPhiNodes(BasicBlock* bb) { } } -void MergeReturnPass::RecordImmediateDominator(BasicBlock* block) { - DominatorAnalysis* dom_tree = - context()->GetDominatorAnalysis(block->GetParent()); - auto idom = dom_tree->ImmediateDominator(block); - new_merge_nodes_[block] = idom; +void MergeReturnPass::RecordImmediateDominators(Function* function) { + DominatorAnalysis* dom_tree = context()->GetDominatorAnalysis(function); + for (BasicBlock& bb : *function) { + BasicBlock* dominator_bb = dom_tree->ImmediateDominator(&bb); + if (dominator_bb && dominator_bb != cfg()->pseudo_entry_block()) { + original_dominator_[&bb] = dominator_bb->terminator(); + } else { + original_dominator_[&bb] = nullptr; + } + } } void MergeReturnPass::InsertAfterElement(BasicBlock* element, diff --git a/3rdparty/spirv-tools/source/opt/merge_return_pass.h b/3rdparty/spirv-tools/source/opt/merge_return_pass.h index d9eae39fd..f8edd27b5 100644 --- a/3rdparty/spirv-tools/source/opt/merge_return_pass.h +++ b/3rdparty/spirv-tools/source/opt/merge_return_pass.h @@ -246,24 +246,23 @@ class MergeReturnPass : public MemPass { // instruction. void CreatePhiNodesForInst(BasicBlock* merge_block, Instruction& inst); - // Traverse the nodes in |new_merge_nodes_|, and adds the OpPhi instructions - // that are needed to make the code correct. It is assumed that at this point - // there are no unreachable blocks in the control flow graph. + // Add new phi nodes for any id that no longer dominate all of it uses. A phi + // node is added to a block |bb| for an id if the id is defined between the + // original immediate dominator of |bb| and its new immidiate dominator. It + // is assumed that at this point there are no unreachable blocks in the + // control flow graph. void AddNewPhiNodes(); // Creates any new phi nodes that are needed in |bb|. |AddNewPhiNodes| must // have already been called on the original dominators of |bb|. void AddNewPhiNodes(BasicBlock* bb); - // Saves |block| to a list of basic block that will require OpPhi nodes to be - // added by calling |AddNewPhiNodes|. It is assumed that |block| used to have - // a single predecessor, |single_original_pred|, but now has more. - void RecordImmediateDominator(BasicBlock* block); + // Records the terminator of immediate dominator for every basic block in + // |function|. + void RecordImmediateDominators(Function* function); // Modifies existing OpPhi instruction in |target| block to account for the - // new edge from |new_source|. The value for that edge will be an Undef. If - // |target| only had a single predecessor, then it is marked as needing new - // phi nodes. See |RecordImmediateDominator|. + // new edge from |new_source|. The value for that edge will be an Undef. // // The CFG must not include the edge from |new_source| to |target| yet. void UpdatePhiNodes(BasicBlock* new_source, BasicBlock* target); @@ -317,9 +316,10 @@ class MergeReturnPass : public MemPass { // after processing the current function. BasicBlock* final_return_block_; - // This is a map from a node to its original immediate dominator. This is - // used to determine which values will require a new phi node. - std::unordered_map new_merge_nodes_; + // This is a map from a node to its original immediate dominator identified by + // the terminator if that block. We use the terminator because the block we + // want may change if the block is split. + std::unordered_map original_dominator_; // A map from a basic block, bb, to the set of basic blocks which represent // the new edges that reach |bb|. diff --git a/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp b/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp index f2cb2da28..7144ca0ca 100644 --- a/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp +++ b/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp @@ -102,6 +102,7 @@ void SSARewriter::ReplacePhiUsersWith(const PhiCandidate& phi_to_remove, uint32_t repl_id) { for (uint32_t user_id : phi_to_remove.users()) { PhiCandidate* user_phi = GetPhiCandidate(user_id); + BasicBlock* bb = pass_->context()->get_instr_block(user_id); if (user_phi) { // If the user is a Phi candidate, replace all arguments that refer to // |phi_to_remove.result_id()| with |repl_id|. @@ -110,6 +111,10 @@ void SSARewriter::ReplacePhiUsersWith(const PhiCandidate& phi_to_remove, arg = repl_id; } } + } else if (bb->id() == user_id) { + // The phi candidate is the definition of the variable at basic block + // |bb|. We must change this to the replacement. + WriteVariable(phi_to_remove.var_id(), bb, repl_id); } else { // For regular loads, traverse the |load_replacement_| table looking for // instances of |phi_to_remove|. @@ -259,6 +264,8 @@ uint32_t SSARewriter::GetReachingDef(uint32_t var_id, BasicBlock* bb) { // require a Phi instruction. This will act as |var_id|'s current // definition to break potential cycles. PhiCandidate& phi_candidate = CreatePhiCandidate(var_id, bb); + + // Set the value for |bb| to avoid an infinite recursion. WriteVariable(var_id, bb, phi_candidate.result_id()); val_id = AddPhiOperands(&phi_candidate); } diff --git a/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.h b/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.h index c0373dc06..fddbdaf54 100644 --- a/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.h +++ b/3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.h @@ -188,6 +188,9 @@ class SSARewriter { // value |val_id|. void WriteVariable(uint32_t var_id, BasicBlock* bb, uint32_t val_id) { defs_at_block_[bb][var_id] = val_id; + if (auto* pc = GetPhiCandidate(val_id)) { + pc->AddUser(bb->id()); + } } // Processes the store operation |inst| in basic block |bb|. This extracts diff --git a/3rdparty/spirv-tools/source/val/function.cpp b/3rdparty/spirv-tools/source/val/function.cpp index af1498d2f..876a6081a 100644 --- a/3rdparty/spirv-tools/source/val/function.cpp +++ b/3rdparty/spirv-tools/source/val/function.cpp @@ -317,13 +317,10 @@ int Function::GetBlockDepth(BasicBlock* bb) { if (!bb_dom || bb == bb_dom) { // This block has no dominator, so it's at depth 0. block_depth_[bb] = 0; - } else if (bb->is_type(kBlockTypeMerge)) { - // If this is a merge block, its depth is equal to the block before - // branching. - BasicBlock* header = merge_block_header_[bb]; - assert(header); - block_depth_[bb] = GetBlockDepth(header); } else if (bb->is_type(kBlockTypeContinue)) { + // This rule must precede the rule for merge blocks in order to set up + // depths correctly. If a block is both a merge and continue then the merge + // is nested within the continue's loop (or the graph is incorrect). // The depth of the continue block entry point is 1 + loop header depth. Construct* continue_construct = entry_block_to_construct_[std::make_pair(bb, ConstructType::kContinue)]; @@ -341,6 +338,12 @@ int Function::GetBlockDepth(BasicBlock* bb) { } else { block_depth_[bb] = 1 + GetBlockDepth(loop_header); } + } else if (bb->is_type(kBlockTypeMerge)) { + // If this is a merge block, its depth is equal to the block before + // branching. + BasicBlock* header = merge_block_header_[bb]; + assert(header); + block_depth_[bb] = GetBlockDepth(header); } else if (bb_dom->is_type(kBlockTypeHeader) || bb_dom->is_type(kBlockTypeLoop)) { // The dominator of the given block is a header block. So, the nesting diff --git a/3rdparty/spirv-tools/source/val/validate_annotation.cpp b/3rdparty/spirv-tools/source/val/validate_annotation.cpp index 4e8a2cd51..269528035 100644 --- a/3rdparty/spirv-tools/source/val/validate_annotation.cpp +++ b/3rdparty/spirv-tools/source/val/validate_annotation.cpp @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/val/validate.h" - #include "source/opcode.h" #include "source/spirv_target_env.h" #include "source/val/instruction.h" +#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -287,11 +286,11 @@ spv_result_t ValidateDecorationGroup(ValidationState_t& _, auto use = pair.first; if (use->opcode() != SpvOpDecorate && use->opcode() != SpvOpGroupDecorate && use->opcode() != SpvOpGroupMemberDecorate && - use->opcode() != SpvOpName) { + use->opcode() != SpvOpName && use->opcode() != SpvOpDecorateId) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result id of OpDecorationGroup can only " << "be targeted by OpName, OpGroupDecorate, " - << "OpDecorate, and OpGroupMemberDecorate"; + << "OpDecorate, OpDecorateId, and OpGroupMemberDecorate"; } } return SPV_SUCCESS; diff --git a/3rdparty/spirv-tools/source/val/validate_atomics.cpp b/3rdparty/spirv-tools/source/val/validate_atomics.cpp index e9e496056..b8867ddcc 100644 --- a/3rdparty/spirv-tools/source/val/validate_atomics.cpp +++ b/3rdparty/spirv-tools/source/val/validate_atomics.cpp @@ -25,6 +25,28 @@ #include "source/val/validate_scopes.h" #include "source/val/validation_state.h" +namespace { + +bool IsStorageClassAllowedByUniversalRules(uint32_t storage_class) { + switch (storage_class) { + case SpvStorageClassUniform: + case SpvStorageClassStorageBuffer: + case SpvStorageClassWorkgroup: + case SpvStorageClassCrossWorkgroup: + case SpvStorageClassGeneric: + case SpvStorageClassAtomicCounter: + case SpvStorageClassImage: + case SpvStorageClassFunction: + case SpvStorageClassPhysicalStorageBufferEXT: + return true; + break; + default: + return false; + } +} + +} // namespace + namespace spvtools { namespace val { @@ -119,32 +141,42 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { << ": expected Pointer to be of type OpTypePointer"; } - switch (storage_class) { - case SpvStorageClassUniform: - case SpvStorageClassWorkgroup: - case SpvStorageClassCrossWorkgroup: - case SpvStorageClassGeneric: - case SpvStorageClassAtomicCounter: - case SpvStorageClassImage: - case SpvStorageClassStorageBuffer: - case SpvStorageClassPhysicalStorageBufferEXT: - break; - default: - if (spvIsOpenCLEnv(_.context()->target_env)) { - if (storage_class != SpvStorageClassFunction) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(opcode) - << ": expected Pointer Storage Class to be Uniform, " - "Workgroup, CrossWorkgroup, Generic, AtomicCounter, " - "Image, StorageBuffer or Function"; - } - } else { + // Validate storage class against universal rules + if (!IsStorageClassAllowedByUniversalRules(storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": storage class forbidden by universal validation rules."; + } + + // Then Shader rules + if (_.HasCapability(SpvCapabilityShader)) { + if (storage_class == SpvStorageClassFunction) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Function storage class forbidden when the Shader " + "capability is declared."; + } + } + + // And finally OpenCL environment rules + if (spvIsOpenCLEnv(_.context()->target_env)) { + if ((storage_class != SpvStorageClassFunction) && + (storage_class != SpvStorageClassWorkgroup) && + (storage_class != SpvStorageClassCrossWorkgroup) && + (storage_class != SpvStorageClassGeneric)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": storage class must be Function, Workgroup, " + "CrossWorkGroup or Generic in the OpenCL environment."; + } + + if (_.context()->target_env == SPV_ENV_OPENCL_1_2) { + if (storage_class == SpvStorageClassGeneric) { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(opcode) - << ": expected Pointer Storage Class to be Uniform, " - "Workgroup, CrossWorkgroup, Generic, AtomicCounter, " - "Image or StorageBuffer"; + << "Storage class cannot be Generic in OpenCL 1.2 " + "environment"; } + } } if (opcode == SpvOpAtomicFlagTestAndSet || diff --git a/3rdparty/spirv-tools/source/val/validate_cfg.cpp b/3rdparty/spirv-tools/source/val/validate_cfg.cpp index 5a5082fb0..8d8839e2f 100644 --- a/3rdparty/spirv-tools/source/val/validate_cfg.cpp +++ b/3rdparty/spirv-tools/source/val/validate_cfg.cpp @@ -493,41 +493,54 @@ spv_result_t StructuredSwitchChecks(ValidationState_t& _, Function* function, std::map num_fall_through_targeted; uint32_t default_case_fall_through = 0u; uint32_t default_target = switch_inst->GetOperandAs(1u); - std::unordered_set seen; + bool default_appears_multiple_times = false; + for (uint32_t i = 3; i < switch_inst->operands().size(); i += 2) { + if (default_target == switch_inst->GetOperandAs(i)) { + default_appears_multiple_times = true; + break; + } + } + std::unordered_map seen_to_fall_through; for (uint32_t i = 1; i < switch_inst->operands().size(); i += 2) { uint32_t target = switch_inst->GetOperandAs(i); if (target == merge->id()) continue; - if (!seen.insert(target).second) continue; - - const auto target_block = function->GetBlock(target).first; - // OpSwitch must dominate all its case constructs. - if (header->reachable() && target_block->reachable() && - !header->dominates(*target_block)) { - return _.diag(SPV_ERROR_INVALID_CFG, header->label()) - << "Selection header " << _.getIdName(header->id()) - << " does not dominate its case construct " << _.getIdName(target); - } - uint32_t case_fall_through = 0u; - if (auto error = FindCaseFallThrough(_, target_block, &case_fall_through, - merge, case_targets, function)) { - return error; - } - - // Track how many time the fall through case has been targeted. - if (case_fall_through != 0u) { - auto where = num_fall_through_targeted.lower_bound(case_fall_through); - if (where == num_fall_through_targeted.end() || - where->first != case_fall_through) { - num_fall_through_targeted.insert(where, - std::make_pair(case_fall_through, 1)); - } else { - where->second++; + auto seen_iter = seen_to_fall_through.find(target); + if (seen_iter == seen_to_fall_through.end()) { + const auto target_block = function->GetBlock(target).first; + // OpSwitch must dominate all its case constructs. + if (header->reachable() && target_block->reachable() && + !header->dominates(*target_block)) { + return _.diag(SPV_ERROR_INVALID_CFG, header->label()) + << "Selection header " << _.getIdName(header->id()) + << " does not dominate its case construct " + << _.getIdName(target); } + + if (auto error = FindCaseFallThrough(_, target_block, &case_fall_through, + merge, case_targets, function)) { + return error; + } + + // Track how many time the fall through case has been targeted. + if (case_fall_through != 0u) { + auto where = num_fall_through_targeted.lower_bound(case_fall_through); + if (where == num_fall_through_targeted.end() || + where->first != case_fall_through) { + num_fall_through_targeted.insert( + where, std::make_pair(case_fall_through, 1)); + } else { + where->second++; + } + } + seen_to_fall_through.insert(std::make_pair(target, case_fall_through)); + } else { + case_fall_through = seen_iter->second; } - if (case_fall_through == default_target) { + if (case_fall_through == default_target && + !default_appears_multiple_times) { case_fall_through = default_case_fall_through; } if (case_fall_through != 0u) { diff --git a/3rdparty/spirv-tools/source/val/validate_derivatives.cpp b/3rdparty/spirv-tools/source/val/validate_derivatives.cpp index 718970769..b3f046ab7 100644 --- a/3rdparty/spirv-tools/source/val/validate_derivatives.cpp +++ b/3rdparty/spirv-tools/source/val/validate_derivatives.cpp @@ -53,37 +53,45 @@ spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { << "Expected P type and Result Type to be the same: " << spvOpcodeString(opcode); } - - const spvtools::Extension compute_shader_derivatives_extension = - kSPV_NV_compute_shader_derivatives; - ExtensionSet exts(1, &compute_shader_derivatives_extension); - - if (_.HasAnyOfExtensions(exts)) { - _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model, - std::string* message) { - if (model != SpvExecutionModelFragment && - model != SpvExecutionModelGLCompute) { - if (message) { - *message = - std::string( - "Derivative instructions require Fragment execution " - "model: ") + - spvOpcodeString(opcode); - } - return false; + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model, + std::string* message) { + if (model != SpvExecutionModelFragment && + model != SpvExecutionModelGLCompute) { + if (message) { + *message = + std::string( + "Derivative instructions require Fragment or GLCompute " + "execution model: ") + + spvOpcodeString(opcode); } - return true; - }); - } else { - _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, - std::string( - "Derivative instructions require Fragment execution " - "model: ") + - spvOpcodeString(opcode)); - } + return false; + } + return true; + }); + _.function(inst->function()->id()) + ->RegisterLimitation([opcode](const ValidationState_t& state, + const Function* entry_point, + std::string* message) { + const auto* models = state.GetExecutionModels(entry_point->id()); + const auto* modes = state.GetExecutionModes(entry_point->id()); + if (models->find(SpvExecutionModelGLCompute) != models->end() && + modes->find(SpvExecutionModeDerivativeGroupLinearNV) == + modes->end() && + modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == + modes->end()) { + if (message) { + *message = std::string( + "Derivative instructions require " + "DerivativeGroupQuadsNV " + "or DerivativeGroupLinearNV execution mode for " + "GLCompute execution model: ") + + spvOpcodeString(opcode); + } + return false; + } + return true; + }); break; } diff --git a/3rdparty/spirv-tools/source/val/validate_image.cpp b/3rdparty/spirv-tools/source/val/validate_image.cpp index 2fdb4767e..bc2753cf9 100644 --- a/3rdparty/spirv-tools/source/val/validate_image.cpp +++ b/3rdparty/spirv-tools/source/val/validate_image.cpp @@ -1710,8 +1710,39 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, const Instruction* inst) { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, - "OpImageQueryLod requires Fragment execution model"); + [&](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelFragment && + model != SpvExecutionModelGLCompute) { + if (message) { + *message = std::string( + "OpImageQueryLod requires Fragment or GLCompute execution " + "model"); + } + return false; + } + return true; + }); + _.function(inst->function()->id()) + ->RegisterLimitation([](const ValidationState_t& state, + const Function* entry_point, + std::string* message) { + const auto* models = state.GetExecutionModels(entry_point->id()); + const auto* modes = state.GetExecutionModes(entry_point->id()); + if (models->find(SpvExecutionModelGLCompute) != models->end() && + modes->find(SpvExecutionModeDerivativeGroupLinearNV) == + modes->end() && + modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == + modes->end()) { + if (message) { + *message = std::string( + "OpImageQueryLod requires DerivativeGroupQuadsNV " + "or DerivativeGroupLinearNV execution mode for GLCompute " + "execution model"); + } + return false; + } + return true; + }); const uint32_t result_type = inst->type_id(); if (!_.IsFloatVectorType(result_type)) { @@ -1835,9 +1866,44 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { const SpvOp opcode = inst->opcode(); if (IsImplicitLod(opcode)) { _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation( - SpvExecutionModelFragment, - "ImplicitLod instructions require Fragment execution model"); + ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model, + std::string* message) { + if (model != SpvExecutionModelFragment && + model != SpvExecutionModelGLCompute) { + if (message) { + *message = + std::string( + "ImplicitLod instructions require Fragment or GLCompute " + "execution model: ") + + spvOpcodeString(opcode); + } + return false; + } + return true; + }); + _.function(inst->function()->id()) + ->RegisterLimitation([opcode](const ValidationState_t& state, + const Function* entry_point, + std::string* message) { + const auto* models = state.GetExecutionModels(entry_point->id()); + const auto* modes = state.GetExecutionModes(entry_point->id()); + if (models->find(SpvExecutionModelGLCompute) != models->end() && + modes->find(SpvExecutionModeDerivativeGroupLinearNV) == + modes->end() && + modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == + modes->end()) { + if (message) { + *message = + std::string( + "ImplicitLod instructions require DerivativeGroupQuadsNV " + "or DerivativeGroupLinearNV execution mode for GLCompute " + "execution model: ") + + spvOpcodeString(opcode); + } + return false; + } + return true; + }); } switch (opcode) { diff --git a/3rdparty/spirv-tools/test/opt/aggressive_dead_code_elim_test.cpp b/3rdparty/spirv-tools/test/opt/aggressive_dead_code_elim_test.cpp index f3238015b..b4ab10d98 100644 --- a/3rdparty/spirv-tools/test/opt/aggressive_dead_code_elim_test.cpp +++ b/3rdparty/spirv-tools/test/opt/aggressive_dead_code_elim_test.cpp @@ -6560,6 +6560,62 @@ OpFunctionEnd SinglePassRunAndMatch(spirv, true); } +TEST_F(AggressiveDCETest, LiveDecorateId) { + const std::string spirv = R"(OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %1 "main" %2 +OpExecutionMode %1 LocalSize 8 1 1 +OpDecorate %2 DescriptorSet 0 +OpDecorate %2 Binding 0 +OpDecorateId %3 UniformId %uint_2 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%uint_2 = OpConstant %uint 2 +%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +%2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer +%8 = OpTypeFunction %void +%1 = OpFunction %void None %8 +%9 = OpLabel +%3 = OpLoad %uint %2 +OpStore %2 %3 +OpReturn +OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + OptimizerOptions()->preserve_spec_constants_ = true; + SinglePassRunAndCheck(spirv, spirv, true); +} + +TEST_F(AggressiveDCETest, LiveDecorateIdOnGroup) { + const std::string spirv = R"(OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %1 "main" %2 +OpExecutionMode %1 LocalSize 8 1 1 +OpDecorate %2 DescriptorSet 0 +OpDecorate %2 Binding 0 +OpDecorateId %3 UniformId %uint_2 +%3 = OpDecorationGroup +OpGroupDecorate %3 %5 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%uint_2 = OpConstant %uint 2 +%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +%2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer +%9 = OpTypeFunction %void +%1 = OpFunction %void None %9 +%10 = OpLabel +%5 = OpLoad %uint %2 +OpStore %2 %5 +OpReturn +OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + OptimizerOptions()->preserve_spec_constants_ = true; + SinglePassRunAndCheck(spirv, spirv, true); +} + // TODO(greg-lunarg): Add tests to verify handling of these cases: // // Check that logical addressing required diff --git a/3rdparty/spirv-tools/test/opt/inst_bindless_check_test.cpp b/3rdparty/spirv-tools/test/opt/inst_bindless_check_test.cpp index 25f0baa15..6fe27c64a 100644 --- a/3rdparty/spirv-tools/test/opt/inst_bindless_check_test.cpp +++ b/3rdparty/spirv-tools/test/opt/inst_bindless_check_test.cpp @@ -255,7 +255,7 @@ OpFunctionEnd func_pt2_before, entry_after + names_annots + new_annots + consts_types_vars + new_consts_types_vars + func_pt1 + func_pt2_after + output_func, - true, true); + true, true, 7u, 23u, false, false, 1u); } TEST_F(InstBindlessTest, NoInstrumentConstIndexInbounds) { @@ -335,7 +335,8 @@ OpFunctionEnd )"; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndCheck(before, before, true, true); + SinglePassRunAndCheck(before, before, true, true, 7u, + 23u, false, false, 1u); } TEST_F(InstBindlessTest, InstrumentMultipleInstructions) { @@ -630,7 +631,7 @@ OpFunctionEnd SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true); + true, 7u, 23u, false, false, 1u); } TEST_F(InstBindlessTest, InstrumentOpImage) { @@ -858,7 +859,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true); + true, 7u, 23u, false, false, 1u); } TEST_F(InstBindlessTest, InstrumentSampledImage) { @@ -1081,7 +1082,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true); + true, 7u, 23u, false, false, 1u); } TEST_F(InstBindlessTest, InstrumentImageWrite) { @@ -1306,7 +1307,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true); + true, 7u, 23u, false, false, 1u); } TEST_F(InstBindlessTest, InstrumentVertexSimple) { @@ -1580,7 +1581,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true); + true, 7u, 23u, false, false, 1u); } TEST_F(InstBindlessTest, MultipleDebugFunctions) { @@ -1903,7 +1904,8 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func1_before + func2_before, - defs_after + func1_after + func2_after + output_func, true, true); + defs_after + func1_after + func2_after + output_func, true, true, 7u, 23u, + false, false, 1u); } TEST_F(InstBindlessTest, RuntimeArray) { @@ -2276,18 +2278,19 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck(whole_file, whole_file, true, - true); + true, 7u, 23u, false, false, 1u); } TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) { // This test verifies that the pass will correctly instrument vanilla // texture sample on a scalar descriptor with an initialization check if the - // SPV_EXT_descriptor_checking extension is enabled. This is the same shader - // as NoInstrumentNonBindless, but with the extension hacked on in the SPIR-V. + // input_init_enable argument is set to true. This can happen when the + // descriptor indexing extension is enabled in the API but the SPIR-V + // does not have the extension enabled because it does not contain a + // runtime array. This is the same shader as NoInstrumentNonBindless. const std::string defs_before = R"(OpCapability Shader -OpExtension "SPV_EXT_descriptor_indexing" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor @@ -2324,7 +2327,6 @@ OpDecorate %_entryPointOutput_vColor Location 0 const std::string defs_after = R"(OpCapability Shader -OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 @@ -2395,7 +2397,7 @@ OpDecorate %gl_FragCoord BuiltIn FragCoord %uint_6 = OpConstant %uint 6 %uint_7 = OpConstant %uint 7 %uint_8 = OpConstant %uint 8 -%uint_40 = OpConstant %uint 40 +%uint_39 = OpConstant %uint 39 %113 = OpConstantNull %v4float )"; @@ -2429,7 +2431,7 @@ OpBranchConditional %52 %55 %56 %59 = OpImageSampleImplicitLod %v4float %58 %20 OpBranch %54 %56 = OpLabel -%112 = OpFunctionCall %void %60 %uint_40 %uint_1 %uint_0 %uint_0 +%112 = OpFunctionCall %void %60 %uint_39 %uint_1 %uint_0 %uint_0 OpBranch %54 %54 = OpLabel %114 = OpPhi %v4float %59 %55 %113 %56 @@ -4456,7 +4458,7 @@ OpFunctionEnd func_pt2_before, entry_after + names_annots + new_annots + consts_types_vars + new_consts_types_vars + func_pt1 + func_pt2_after + output_func, - true, true, 7u, 23u, true, true, 2u); + true, true, 7u, 23u, false, false, 2u); } TEST_F(InstBindlessTest, InstrumentMultipleInstructionsV2) { @@ -4751,7 +4753,7 @@ OpFunctionEnd SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true, 7u, 23u, true, true, 2u); + true, 7u, 23u, false, false, 2u); } TEST_F(InstBindlessTest, InstrumentOpImageV2) { @@ -4979,7 +4981,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true, 7u, 23u, true, true, 2u); + true, 7u, 23u, false, false, 2u); } TEST_F(InstBindlessTest, InstrumentSampledImageV2) { @@ -5202,7 +5204,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true, 7u, 23u, true, true, 2u); + true, 7u, 23u, false, false, 2u); } TEST_F(InstBindlessTest, InstrumentImageWriteV2) { @@ -5427,7 +5429,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true, 7u, 23u, true, true, 2u); + true, 7u, 23u, false, false, 2u); } TEST_F(InstBindlessTest, InstrumentVertexSimpleV2) { @@ -5701,7 +5703,7 @@ OpFunctionEnd // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndCheck( defs_before + func_before, defs_after + func_after + output_func, true, - true, 7u, 23u, true, true, 2u); + true, 7u, 23u, false, false, 2u); } TEST_F(InstBindlessTest, MultipleDebugFunctionsV2) { @@ -6025,7 +6027,7 @@ OpFunctionEnd SinglePassRunAndCheck( defs_before + func1_before + func2_before, defs_after + func1_after + func2_after + output_func, true, true, 7u, 23u, - true, true, 2u); + false, false, 2u); } TEST_F(InstBindlessTest, RuntimeArrayV2) { @@ -6327,12 +6329,13 @@ OpFunctionEnd TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptorV2) { // This test verifies that the pass will correctly instrument vanilla // texture sample on a scalar descriptor with an initialization check if the - // SPV_EXT_descriptor_checking extension is enabled. This is the same shader - // as NoInstrumentNonBindless, but with the extension hacked on in the SPIR-V. + // input_init_enable argument is set to true. This can happen when the + // descriptor indexing extension is enabled in the API but the SPIR-V + // does not have the extension enabled because it does not contain a + // runtime array. This is the same shader as NoInstrumentNonBindless. const std::string defs_before = R"(OpCapability Shader -OpExtension "SPV_EXT_descriptor_indexing" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor @@ -6369,7 +6372,6 @@ OpDecorate %_entryPointOutput_vColor Location 0 const std::string defs_after = R"(OpCapability Shader -OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 @@ -6440,7 +6442,7 @@ OpDecorate %gl_FragCoord BuiltIn FragCoord %uint_7 = OpConstant %uint 7 %uint_8 = OpConstant %uint 8 %uint_9 = OpConstant %uint 9 -%uint_40 = OpConstant %uint 40 +%uint_39 = OpConstant %uint 39 %113 = OpConstantNull %v4float )"; @@ -6474,7 +6476,7 @@ OpBranchConditional %52 %55 %56 %59 = OpImageSampleImplicitLod %v4float %58 %20 OpBranch %54 %56 = OpLabel -%112 = OpFunctionCall %void %60 %uint_40 %uint_1 %uint_0 %uint_0 +%112 = OpFunctionCall %void %60 %uint_39 %uint_1 %uint_0 %uint_0 OpBranch %54 %54 = OpLabel %114 = OpPhi %v4float %59 %55 %113 %56 diff --git a/3rdparty/spirv-tools/test/opt/local_ssa_elim_test.cpp b/3rdparty/spirv-tools/test/opt/local_ssa_elim_test.cpp index d2da1f9c1..a490d5290 100644 --- a/3rdparty/spirv-tools/test/opt/local_ssa_elim_test.cpp +++ b/3rdparty/spirv-tools/test/opt/local_ssa_elim_test.cpp @@ -1930,6 +1930,63 @@ TEST_F(LocalSSAElimTest, VariablePointerTest2) { SinglePassRunAndMatch(text, false); } +TEST_F(LocalSSAElimTest, ChainedTrivialPhis) { + // Check that the copy object get the undef value implicitly assigned in the + // entry block. + const std::string text = R"( +; CHECK: [[undef:%\w+]] = OpUndef %v4float +; CHECK: OpCopyObject %v4float [[undef]] + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %2 "main" + OpExecutionMode %2 LocalSize 1 18 6 + OpSource ESSL 310 + %void = OpTypeVoid + %4 = OpTypeFunction %void + %bool = OpTypeBool + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Function_v4float = OpTypePointer Function %v4float + %2 = OpFunction %void None %4 + %9 = OpLabel + %10 = OpVariable %_ptr_Function_v4float Function + OpBranch %11 + %11 = OpLabel + OpLoopMerge %12 %13 None + OpBranch %14 + %14 = OpLabel + %15 = OpUndef %bool + OpBranchConditional %15 %16 %12 + %16 = OpLabel + %17 = OpUndef %bool + OpSelectionMerge %18 None + OpBranchConditional %17 %19 %18 + %19 = OpLabel + %20 = OpUndef %bool + OpLoopMerge %21 %22 None + OpBranchConditional %20 %23 %21 + %23 = OpLabel + %24 = OpLoad %v4float %10 + %25 = OpCopyObject %v4float %24 + %26 = OpUndef %bool + OpBranch %22 + %22 = OpLabel + OpBranch %19 + %21 = OpLabel + OpBranch %12 + %18 = OpLabel + OpBranch %13 + %13 = OpLabel + OpBranch %11 + %12 = OpLabel + %27 = OpLoad %v4float %10 + OpReturn + OpFunctionEnd + )"; + SinglePassRunAndMatch(text, false); +} + // TODO(greg-lunarg): Add tests to verify handling of these cases: // // No optimization in the presence of diff --git a/3rdparty/spirv-tools/test/opt/pass_merge_return_test.cpp b/3rdparty/spirv-tools/test/opt/pass_merge_return_test.cpp index f6b30de7c..baf7820e8 100644 --- a/3rdparty/spirv-tools/test/opt/pass_merge_return_test.cpp +++ b/3rdparty/spirv-tools/test/opt/pass_merge_return_test.cpp @@ -1779,6 +1779,57 @@ TEST_F(MergeReturnPassTest, MergeToMergeBranch) { SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndMatch(text, true); } +TEST_F(MergeReturnPassTest, PhiInSecondMerge) { + // Add and use a phi in the second merge block from the return. + const std::string text = + R"( +; CHECK: OpLoopMerge +; CHECK: OpLoopMerge [[merge_bb:%\w+]] [[continue_bb:%\w+]] +; CHECK: [[continue_bb]] = OpLabel +; CHECK-NEXT: [[val:%\w+]] = OpUndef %float +; CHECK: [[merge_bb]] = OpLabel +; CHECK-NEXT: [[phi:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} [[val]] [[continue_bb]] +; CHECK-NOT: OpLabel +; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} [[old_merge:%\w+]] +; CHECK: [[old_merge]] = OpLabel +; CHECK-NEXT: OpConvertFToS %int [[phi]] + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %2 "main" + OpExecutionMode %2 OriginUpperLeft + OpSource ESSL 310 + %void = OpTypeVoid + %4 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %float = OpTypeFloat 32 + %bool = OpTypeBool + %8 = OpUndef %bool + %2 = OpFunction %void None %4 + %9 = OpLabel + OpBranch %10 + %10 = OpLabel + OpLoopMerge %11 %12 None + OpBranch %13 + %13 = OpLabel + OpLoopMerge %12 %14 None + OpBranchConditional %8 %15 %12 + %15 = OpLabel + OpReturn + %14 = OpLabel + OpBranch %13 + %12 = OpLabel + %16 = OpUndef %float + OpBranchConditional %8 %10 %11 + %11 = OpLabel + %17 = OpConvertFToS %int %16 + OpReturn + OpFunctionEnd +)"; + + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} } // namespace } // namespace opt diff --git a/3rdparty/spirv-tools/test/scripts/test_compact_ids.py b/3rdparty/spirv-tools/test/scripts/test_compact_ids.py index b9b5b1bc0..6ca6e67b2 100644 --- a/3rdparty/spirv-tools/test/scripts/test_compact_ids.py +++ b/3rdparty/spirv-tools/test/scripts/test_compact_ids.py @@ -14,8 +14,6 @@ # limitations under the License. """Tests correctness of opt pass tools/opt --compact-ids.""" -from __future__ import print_function - import os.path import sys import tempfile diff --git a/3rdparty/spirv-tools/test/tools/spirv_test_framework.py b/3rdparty/spirv-tools/test/tools/spirv_test_framework.py index 03ad08fa8..d8d64f3e4 100755 --- a/3rdparty/spirv-tools/test/tools/spirv_test_framework.py +++ b/3rdparty/spirv-tools/test/tools/spirv_test_framework.py @@ -44,8 +44,6 @@ If --leave-output was not specified, all temporary files and directories will be deleted. """ -from __future__ import print_function - import argparse import fnmatch import inspect diff --git a/3rdparty/spirv-tools/test/val/val_atomics_test.cpp b/3rdparty/spirv-tools/test/val/val_atomics_test.cpp index a0056141e..15887eb36 100644 --- a/3rdparty/spirv-tools/test/val/val_atomics_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_atomics_test.cpp @@ -190,6 +190,9 @@ OpMemoryModel Physical32 OpenCL %f32_ptr_uniformconstant = OpTypePointer UniformConstant %f32 %f32_uc_var = OpVariable %f32_ptr_uniformconstant UniformConstant +%f32_ptr_image = OpTypePointer Image %f32 +%f32_im_var = OpVariable %f32_ptr_image Image + %main = OpFunction %void None %func %main_entry = OpLabel )"; @@ -288,11 +291,9 @@ OpAtomicStore %f32_var_function %device %relaxed %f32_1 CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("AtomicStore: expected Pointer Storage Class to be Uniform, " - "Workgroup, CrossWorkgroup, Generic, AtomicCounter, Image or " - "StorageBuffer")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("AtomicStore: Function storage class forbidden when " + "the Shader capability is declared.")); } // TODO(atgoo@github.com): the corresponding check fails Vulkan CTS, @@ -500,8 +501,7 @@ TEST_F(ValidateAtomics, AtomicLoadWrongScopeType) { ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), - HasSubstr("AtomicLoad: expected Memory Scope to be a 32-bit int\n %40 = " - "OpAtomicLoad %float %28 %float_1 %uint_0_1\n")); + HasSubstr("AtomicLoad: expected Memory Scope to be a 32-bit int")); } TEST_F(ValidateAtomics, AtomicLoadWrongMemorySemanticsType) { @@ -641,6 +641,19 @@ OpAtomicStore %f32vec4_var %device %relaxed %f32_1 "type")); } +TEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageTypeForOpenCL) { + const std::string body = R"( +OpAtomicStore %f32_im_var %device %relaxed %f32_1 +)"; + + CompileSuccessfully(GenerateKernelCode(body)); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("AtomicStore: storage class must be Function, Workgroup, " + "CrossWorkGroup or Generic in the OpenCL environment.")); +} + TEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageType) { const std::string body = R"( OpAtomicStore %f32_uc_var %device %relaxed %f32_1 @@ -648,11 +661,9 @@ OpAtomicStore %f32_uc_var %device %relaxed %f32_1 CompileSuccessfully(GenerateKernelCode(body)); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("AtomicStore: expected Pointer Storage Class to be Uniform, " - "Workgroup, CrossWorkgroup, Generic, AtomicCounter, Image or " - "StorageBuffer")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("AtomicStore: storage class forbidden by universal " + "validation rules.")); } TEST_F(ValidateAtomics, AtomicStoreWrongScopeType) { @@ -778,9 +789,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), - HasSubstr( - "AtomicExchange: expected Memory Scope to be a 32-bit int\n %40 = " - "OpAtomicExchange %float %28 %float_1 %uint_0_1 %float_0\n")); + HasSubstr("AtomicExchange: expected Memory Scope to be a 32-bit int")); } TEST_F(ValidateAtomics, AtomicExchangeWrongMemorySemanticsType) { @@ -895,8 +904,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1 EXPECT_THAT( getDiagnosticString(), HasSubstr("AtomicCompareExchange: expected Memory Scope to be a 32-bit " - "int\n %40 = OpAtomicCompareExchange %float %28 %float_1 " - "%uint_0_1 %uint_0_1 %float_0 %float_0\n")); + "int")); } TEST_F(ValidateAtomics, AtomicCompareExchangeWrongMemorySemanticsType1) { @@ -1077,8 +1085,7 @@ TEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongScopeType) { EXPECT_THAT( getDiagnosticString(), HasSubstr( - "AtomicFlagTestAndSet: expected Memory Scope to be a 32-bit int\n " - "%40 = OpAtomicFlagTestAndSet %bool %30 %ulong_1 %uint_0_1\n")); + "AtomicFlagTestAndSet: expected Memory Scope to be a 32-bit int")); } TEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongMemorySemanticsType) { @@ -1179,8 +1186,7 @@ OpAtomicStore %u32_var %device %relaxed %u32_1 EXPECT_THAT(getDiagnosticString(), HasSubstr("AtomicIIncrement: Memory Semantics can have at most " "one of the following bits set: Acquire, Release, " - "AcquireRelease or SequentiallyConsistent\n %40 = " - "OpAtomicIIncrement %uint %30 %uint_1_0 %uint_6\n")); + "AcquireRelease or SequentiallyConsistent")); } TEST_F(ValidateAtomics, AtomicUniformMemorySemanticsShader) { diff --git a/3rdparty/spirv-tools/test/val/val_cfg_test.cpp b/3rdparty/spirv-tools/test/val/val_cfg_test.cpp index 0a9357bc7..b22db0655 100644 --- a/3rdparty/spirv-tools/test/val/val_cfg_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_cfg_test.cpp @@ -2623,6 +2623,134 @@ OpFunctionEnd ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } +TEST_F(ValidateCFG, SwitchCaseOrderingBad1) { + const std::string text = R"( +OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical GLSL450 +OpName %default "default" +OpName %other "other" +%void = OpTypeVoid +%int = OpTypeInt 32 0 +%undef = OpUndef %int +%void_fn = OpTypeFunction %void +%func = OpFunction %void None %void_fn +%entry = OpLabel +OpSelectionMerge %merge None +OpSwitch %undef %default 0 %other 1 %default +%default = OpLabel +OpBranch %other +%other = OpLabel +OpBranch %merge +%merge = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("Case construct that targets 1[%default] has branches to the " + "case construct that targets 2[%other], but does not " + "immediately precede it in the OpSwitch's target list")); +} + +TEST_F(ValidateCFG, SwitchCaseOrderingBad2) { + const std::string text = R"( +OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical GLSL450 +OpName %default "default" +OpName %other "other" +%void = OpTypeVoid +%int = OpTypeInt 32 0 +%undef = OpUndef %int +%void_fn = OpTypeFunction %void +%func = OpFunction %void None %void_fn +%entry = OpLabel +OpSelectionMerge %merge None +OpSwitch %undef %default 0 %default 1 %other +%other = OpLabel +OpBranch %default +%default = OpLabel +OpBranch %merge +%merge = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("Case construct that targets 2[%other] has branches to the " + "case construct that targets 1[%default], but does not " + "immediately precede it in the OpSwitch's target list")); +} + +TEST_F(ValidateCFG, SwitchMultipleDefaultWithFallThroughGood) { + const std::string text = R"( +OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical GLSL450 +OpName %first "first" +OpName %second "second" +OpName %third "third" +%void = OpTypeVoid +%int = OpTypeInt 32 0 +%undef = OpUndef %int +%void_fn = OpTypeFunction %void +%func = OpFunction %void None %void_fn +%entry = OpLabel +OpSelectionMerge %merge None +OpSwitch %undef %second 0 %first 1 %second 2 %third +%first = OpLabel +OpBranch %second +%second = OpLabel +OpBranch %third +%third = OpLabel +OpBranch %merge +%merge = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateCFG, SwitchMultipleDefaultWithFallThroughBad) { + const std::string text = R"( +OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical GLSL450 +OpName %first "first" +OpName %second "second" +OpName %third "third" +%void = OpTypeVoid +%int = OpTypeInt 32 0 +%undef = OpUndef %int +%void_fn = OpTypeFunction %void +%func = OpFunction %void None %void_fn +%entry = OpLabel +OpSelectionMerge %merge None +OpSwitch %undef %second 0 %second 1 %first 2 %third +%first = OpLabel +OpBranch %second +%second = OpLabel +OpBranch %third +%third = OpLabel +OpBranch %merge +%merge = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); +} + TEST_F(ValidateCFG, GoodUnreachableSelection) { const std::string text = R"( OpCapability Shader @@ -3575,6 +3703,52 @@ OpFunctionEnd "10[%10], but not via a structured exit")); } +TEST_F(ValidateCFG, ContinueFromNestedSelection) { + const std::string text = R"( +OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical GLSL450 +%void = OpTypeVoid +%void_fn = OpTypeFunction %void +%bool = OpTypeBool +%undef = OpUndef %bool +%4 = OpFunction %void None %void_fn +%5 = OpLabel +OpBranch %48 +%48 = OpLabel +OpLoopMerge %47 %50 None +OpBranch %10 +%10 = OpLabel +OpLoopMerge %12 %37 None +OpBranchConditional %undef %11 %12 +%11 = OpLabel +OpSelectionMerge %31 None +OpBranchConditional %undef %30 %31 +%30 = OpLabel +OpSelectionMerge %37 None +OpBranchConditional %undef %36 %37 +%36 = OpLabel +OpBranch %37 +%37 = OpLabel +OpBranch %10 +%31 = OpLabel +OpBranch %12 +%12 = OpLabel +OpSelectionMerge %55 None +OpBranchConditional %undef %47 %55 +%55 = OpLabel +OpBranch %47 +%50 = OpLabel +OpBranch %48 +%47 = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + /// TODO(umar): Nested CFG constructs } // namespace diff --git a/3rdparty/spirv-tools/test/val/val_derivatives_test.cpp b/3rdparty/spirv-tools/test/val/val_derivatives_test.cpp index 480042a7d..dac95f6eb 100644 --- a/3rdparty/spirv-tools/test/val/val_derivatives_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_derivatives_test.cpp @@ -145,10 +145,9 @@ TEST_F(ValidateDerivatives, OpDPdxWrongExecutionModel) { CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str()); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Derivative instructions require Fragment execution model: DPdx")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Derivative instructions require Fragment or GLCompute " + "execution model: DPdx")); } } // namespace diff --git a/3rdparty/spirv-tools/test/val/val_id_test.cpp b/3rdparty/spirv-tools/test/val/val_id_test.cpp index 883949044..299e38eb1 100644 --- a/3rdparty/spirv-tools/test/val/val_id_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_id_test.cpp @@ -314,7 +314,7 @@ TEST_F(ValidateIdWithMessage, OpDecorationGroupBad) { EXPECT_THAT(getDiagnosticString(), HasSubstr("Result id of OpDecorationGroup can only " "be targeted by OpName, OpGroupDecorate, " - "OpDecorate, and OpGroupMemberDecorate")); + "OpDecorate, OpDecorateId, and OpGroupMemberDecorate")); } TEST_F(ValidateIdWithMessage, OpGroupDecorateDecorationGroupBad) { std::string spirv = R"( diff --git a/3rdparty/spirv-tools/test/val/val_image_test.cpp b/3rdparty/spirv-tools/test/val/val_image_test.cpp index c2fcb4fd4..fd3d886a6 100644 --- a/3rdparty/spirv-tools/test/val/val_image_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_image_test.cpp @@ -35,6 +35,7 @@ std::string GenerateShaderCode( const std::string& body, const std::string& capabilities_and_extensions = "", const std::string& execution_model = "Fragment", + const std::string& execution_mode = "", const spv_target_env env = SPV_ENV_UNIVERSAL_1_0, const std::string& memory_model = "GLSL450") { std::ostringstream ss; @@ -85,6 +86,7 @@ OpCapability ImageBuffer if (execution_model == "Fragment") { ss << "OpExecutionMode %main OriginUpperLeft\n"; } + ss << execution_mode; if (env == SPV_ENV_VULKAN_1_0) { ss << R"( @@ -606,7 +608,7 @@ TEST_F(ValidateImage, SampledImageVulkanSuccess) { )"; const spv_target_env env = SPV_ENV_VULKAN_1_0; - CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env), env); + CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env)); } @@ -658,7 +660,7 @@ TEST_F(ValidateImage, SampledImageVulkanUnknownSampled) { )"; const spv_target_env env = SPV_ENV_VULKAN_1_0; - CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env), env); + CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); EXPECT_THAT(getDiagnosticString(), HasSubstr("Expected Image 'Sampled' parameter to " @@ -847,7 +849,7 @@ TEST_F(ValidateImage, SampleImplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -967,7 +969,7 @@ TEST_F(ValidateImage, SampleExplicitLodSuccessShader) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -1552,7 +1554,7 @@ TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -1686,7 +1688,7 @@ TEST_F(ValidateImage, SampleProjImplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -1807,7 +1809,7 @@ TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -1930,7 +1932,7 @@ TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -2054,7 +2056,7 @@ TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -2177,7 +2179,7 @@ TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -2280,7 +2282,7 @@ TEST_F(ValidateImage, FetchSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -2439,7 +2441,7 @@ TEST_F(ValidateImage, GatherSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -2695,7 +2697,7 @@ TEST_F(ValidateImage, DrefGatherSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -2790,7 +2792,7 @@ TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) { )"; spv_target_env env = SPV_ENV_VULKAN_1_0; - CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env).c_str(), + CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(), env); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); EXPECT_THAT(getDiagnosticString(), @@ -3008,7 +3010,7 @@ TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) { )"; spv_target_env env = SPV_ENV_VULKAN_1_0; - CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env).c_str(), + CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(), env); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); EXPECT_THAT( @@ -3710,8 +3712,10 @@ TEST_F(ValidateImage, QueryLodWrongExecutionModel) { CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str()); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("OpImageQueryLod requires Fragment execution model")); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpImageQueryLod requires Fragment or GLCompute execution model")); } TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) { @@ -3729,8 +3733,55 @@ OpFunctionEnd CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str()); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpImageQueryLod requires Fragment or GLCompute execution model")); +} + +TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) { + const std::string body = R"( +%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler +%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh +)"; + + const std::string extra = R"( +OpCapability ComputeDerivativeGroupLinearNV +OpExtension "SPV_NV_compute_shader_derivatives" +)"; + const std::string mode = R"( +OpExecutionMode %main LocalSize 8 8 1 +OpExecutionMode %main DerivativeGroupLinearNV +)"; + CompileSuccessfully( + GenerateShaderCode(body, extra, "GLCompute", mode).c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) { + const std::string body = R"( +%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler +%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh +)"; + + const std::string extra = R"( +OpCapability ComputeDerivativeGroupLinearNV +OpExtension "SPV_NV_compute_shader_derivatives" +)"; + const std::string mode = R"( +OpExecutionMode %main LocalSize 8 8 1 +)"; + CompileSuccessfully( + GenerateShaderCode(body, extra, "GLCompute", mode).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("OpImageQueryLod requires Fragment execution model")); + HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or " + "DerivativeGroupLinearNV execution mode for GLCompute " + "execution model")); } TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) { @@ -3743,9 +3794,55 @@ TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) { CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str()); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("ImplicitLod instructions require Fragment or " + "GLCompute execution model")); +} + +TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) { + const std::string body = R"( +%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler +%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh +)"; + + const std::string extra = R"( +OpCapability ComputeDerivativeGroupLinearNV +OpExtension "SPV_NV_compute_shader_derivatives" +)"; + const std::string mode = R"( +OpExecutionMode %main LocalSize 8 8 1 +OpExecutionMode %main DerivativeGroupLinearNV +)"; + CompileSuccessfully( + GenerateShaderCode(body, extra, "GLCompute", mode).c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) { + const std::string body = R"( +%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler +%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh +)"; + + const std::string extra = R"( +OpCapability ComputeDerivativeGroupLinearNV +OpExtension "SPV_NV_compute_shader_derivatives" +)"; + const std::string mode = R"( +OpExecutionMode %main LocalSize 8 8 1 +)"; + CompileSuccessfully( + GenerateShaderCode(body, extra, "GLCompute", mode).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), - HasSubstr("ImplicitLod instructions require Fragment execution model")); + HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or " + "DerivativeGroupLinearNV execution mode for GLCompute " + "execution model")); } TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) { @@ -3779,7 +3876,7 @@ TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -3907,7 +4004,7 @@ TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4001,7 +4098,7 @@ TEST_F(ValidateImage, SparseFetchSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4218,7 +4315,7 @@ TEST_F(ValidateImage, SparseGatherSuccess) { OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4359,7 +4456,7 @@ OpCapability StorageImageReadWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4376,7 +4473,7 @@ OpCapability StorageImageReadWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4395,7 +4492,7 @@ OpCapability StorageImageReadWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, @@ -4417,7 +4514,7 @@ OpCapability StorageImageReadWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, @@ -4438,7 +4535,7 @@ OpCapability StorageImageWriteWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4457,7 +4554,7 @@ OpCapability StorageImageReadWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, @@ -4478,7 +4575,7 @@ OpCapability StorageImageWriteWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, @@ -4499,7 +4596,7 @@ OpCapability StorageImageWriteWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, @@ -4522,7 +4619,7 @@ OpCapability VulkanMemoryModelKHR OpCapability VulkanMemoryModelDeviceScopeKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4539,7 +4636,7 @@ OpCapability StorageImageReadWithoutFormat OpCapability VulkanMemoryModelKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, @@ -4562,7 +4659,7 @@ OpCapability VulkanMemoryModelKHR OpCapability VulkanMemoryModelDeviceScopeKHR OpExtension "SPV_KHR_vulkan_memory_model" )"; - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "VulkanKHR") .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); @@ -4609,7 +4706,7 @@ TEST_F(ValidateImage, SignExtendV13Bad) { %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend )"; - EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", + EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3)), HasSubstr("Invalid image operand 'SignExtend'")); } @@ -4620,7 +4717,7 @@ TEST_F(ValidateImage, ZeroExtendV13Bad) { %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend )"; - EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", + EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3)), HasSubstr("Invalid image operand 'ZeroExtend'")); } @@ -4634,7 +4731,7 @@ TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); @@ -4649,7 +4746,7 @@ TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); @@ -4663,7 +4760,7 @@ TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); @@ -4677,7 +4774,7 @@ TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); @@ -4695,7 +4792,7 @@ TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); @@ -4710,7 +4807,7 @@ TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); @@ -4724,7 +4821,7 @@ TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); @@ -4738,7 +4835,7 @@ TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) { const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; CompileSuccessfully( - GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4), + GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4), SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT(getDiagnosticString(), Eq("")); diff --git a/3rdparty/spirv-tools/utils/check_copyright.py b/3rdparty/spirv-tools/utils/check_copyright.py index fc249e9bd..5a95e3228 100755 --- a/3rdparty/spirv-tools/utils/check_copyright.py +++ b/3rdparty/spirv-tools/utils/check_copyright.py @@ -16,7 +16,6 @@ current directory. Optionally insert them. When inserting, replaces an MIT or Khronos free use license with Apache 2. """ -from __future__ import print_function import argparse import fileinput diff --git a/3rdparty/spirv-tools/utils/check_symbol_exports.py b/3rdparty/spirv-tools/utils/check_symbol_exports.py index a8f3785a5..e14c2eb89 100755 --- a/3rdparty/spirv-tools/utils/check_symbol_exports.py +++ b/3rdparty/spirv-tools/utils/check_symbol_exports.py @@ -14,8 +14,6 @@ # limitations under the License. """Checks names of global exports from a library.""" -from __future__ import print_function - import os.path import re import subprocess diff --git a/3rdparty/spirv-tools/utils/generate_grammar_tables.py b/3rdparty/spirv-tools/utils/generate_grammar_tables.py index a06934923..13f392ac0 100755 --- a/3rdparty/spirv-tools/utils/generate_grammar_tables.py +++ b/3rdparty/spirv-tools/utils/generate_grammar_tables.py @@ -14,8 +14,6 @@ # limitations under the License. """Generates various info tables from SPIR-V JSON grammar.""" -from __future__ import print_function - import errno import json import os.path @@ -36,8 +34,8 @@ SPV_AMD_shader_trinary_minmax def make_path_to_file(f): - """Makes all ancestor directories to the given file, if they - don't yet exist. + """Makes all ancestor directories to the given file, if they don't yet + exist. Arguments: f: The file whose ancestor directories are to be created. @@ -53,8 +51,8 @@ def make_path_to_file(f): def convert_min_required_version(version): - """Converts the minimal required SPIR-V version encoded in the - grammar to the symbol in SPIRV-Tools""" + """Converts the minimal required SPIR-V version encoded in the grammar to + the symbol in SPIRV-Tools.""" if version is None: return 'SPV_SPIRV_VERSION_WORD(1, 0)' if version == 'None': @@ -63,8 +61,8 @@ def convert_min_required_version(version): def convert_max_required_version(version): - """Converts the maximum required SPIR-V version encoded in the - grammar to the symbol in SPIRV-Tools""" + """Converts the maximum required SPIR-V version encoded in the grammar to + the symbol in SPIRV-Tools.""" if version is None: return '0xffffffffu' return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ',')) @@ -79,7 +77,7 @@ def compose_capability_list(caps): Returns: a string containing the braced list of SpvCapability* enums named by caps. """ - return "{" + ", ".join(['SpvCapability{}'.format(c) for c in caps]) + "}" + return '{' + ', '.join(['SpvCapability{}'.format(c) for c in caps]) + '}' def get_capability_array_name(caps): @@ -116,8 +114,8 @@ def compose_extension_list(exts): Returns: a string containing the braced list of extensions named by exts. """ - return "{" + ", ".join( - ['spvtools::Extension::k{}'.format(e) for e in exts]) + "}" + return '{' + ', '.join( + ['spvtools::Extension::k{}'.format(e) for e in exts]) + '}' def get_extension_array_name(extensions): @@ -148,8 +146,8 @@ def generate_extension_arrays(extensions): def convert_operand_kind(operand_tuple): - """Returns the corresponding operand type used in spirv-tools for - the given operand kind and quantifier used in the JSON grammar. + """Returns the corresponding operand type used in spirv-tools for the given + operand kind and quantifier used in the JSON grammar. Arguments: - operand_tuple: a tuple of two elements: @@ -211,8 +209,8 @@ def convert_operand_kind(operand_tuple): class InstInitializer(object): - """Instances holds a SPIR-V instruction suitable for printing as - the initializer for spv_opcode_desc_t.""" + """Instances holds a SPIR-V instruction suitable for printing as the + initializer for spv_opcode_desc_t.""" def __init__(self, opname, caps, exts, operands, version, lastVersion): """Initialization. @@ -244,8 +242,8 @@ class InstInitializer(object): self.lastVersion = convert_max_required_version(lastVersion) def fix_syntax(self): - """Fix an instruction's syntax, adjusting for differences between - the officially released grammar and how SPIRV-Tools uses the grammar. + """Fix an instruction's syntax, adjusting for differences between the + officially released grammar and how SPIRV-Tools uses the grammar. Fixes: - ExtInst should not end with SPV_OPERAND_VARIABLE_ID. @@ -337,8 +335,8 @@ def generate_instruction(inst, is_ext_inst): def generate_instruction_table(inst_table): - """Returns the info table containing all SPIR-V instructions, - sorted by opcode, and prefixed by capability arrays. + """Returns the info table containing all SPIR-V instructions, sorted by + opcode, and prefixed by capability arrays. Note: - the built-in sorted() function is guaranteed to be stable. @@ -435,9 +433,9 @@ def generate_enum_operand_kind_entry(entry, extension_map): value = entry.get('value') caps = entry.get('capabilities', []) if value in extension_map: - exts = extension_map[value] + exts = extension_map[value] else: - exts = [] + exts = [] params = entry.get('parameters', []) params = [p.get('kind') for p in params] params = zip(params, [''] * len(params)) @@ -453,8 +451,10 @@ def generate_enum_operand_kind_entry(entry, extension_map): def generate_enum_operand_kind(enum, synthetic_exts_list): """Returns the C definition for the given operand kind. - Also appends to |synthetic_exts_list| a list of extension - lists used.""" + + Also appends to |synthetic_exts_list| a list of extension lists + used. + """ kind = enum.get('kind') assert kind is not None @@ -462,9 +462,9 @@ def generate_enum_operand_kind(enum, synthetic_exts_list): # preserve their order so the first name listed in the grammar # as the preferred name for disassembly. if enum.get('category') == 'ValueEnum': - functor = lambda k: (k['value']) + def functor(k): return (k['value']) else: - functor = lambda k: (int(k['value'], 16)) + def functor(k): return (int(k['value'], 16)) entries = sorted(enum.get('enumerants', []), key=functor) # SubgroupEqMask and SubgroupEqMaskKHR are the same number with @@ -472,16 +472,16 @@ def generate_enum_operand_kind(enum, synthetic_exts_list): # does. Both should have the extension list. # So create a mapping from enum value to the union of the extensions # across all those grammar entries. Preserve order. - extension_map = { } + extension_map = {} for e in entries: - value = e.get('value') - extension_map[value] = [] + value = e.get('value') + extension_map[value] = [] for e in entries: - value = e.get('value') - exts = e.get('extensions', []) - for ext in exts: - if ext not in extension_map[value]: - extension_map[value].append(ext) + value = e.get('value') + exts = e.get('extensions', []) + for ext in exts: + if ext not in extension_map[value]: + extension_map[value].append(ext) synthetic_exts_list.extend(extension_map.values()) name = '{}_{}Entries'.format(PYGEN_VARIABLE_PREFIX, kind) @@ -544,7 +544,8 @@ def get_extension_list(instructions, operand_kinds): things_with_an_extensions_field = [item for item in instructions] - enumerants = sum([item.get('enumerants', []) for item in operand_kinds], []) + enumerants = sum([item.get('enumerants', []) + for item in operand_kinds], []) things_with_an_extensions_field.extend(enumerants) @@ -553,11 +554,12 @@ def get_extension_list(instructions, operand_kinds): if item.get('extensions')], []) for item in EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split(): - # If it's already listed in a grammar, then don't put it in the - # special exceptions list. - assert item not in extensions, "Extension %s is already in a grammar file" % item + # If it's already listed in a grammar, then don't put it in the + # special exceptions list. + assert item not in extensions, 'Extension %s is already in a grammar file' % item - extensions.extend(EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split()) + extensions.extend( + EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split()) # Validator would ignore type declaration unique check. Should only be used # for legacy autogenerated test files containing multiple instances of the @@ -570,8 +572,7 @@ def get_extension_list(instructions, operand_kinds): def get_capabilities(operand_kinds): """Returns capabilities as a list of JSON objects, in order of - appearance. - """ + appearance.""" enumerants = sum([item.get('enumerants', []) for item in operand_kinds if item.get('kind') in ['Capability']], []) return enumerants @@ -620,6 +621,7 @@ def generate_string_to_extension_mapping(extensions): def generate_capability_to_string_mapping(operand_kinds): """Returns mapping function from capabilities to corresponding strings. + We take care to avoid emitting duplicate values. """ function = 'const char* CapabilityToString(SpvCapability capability) {\n' @@ -649,8 +651,8 @@ def generate_all_string_enum_mappings(extensions, operand_kinds): def precondition_operand_kinds(operand_kinds): - """For operand kinds that have the same number, make sure they all have - the same extension list""" + """For operand kinds that have the same number, make sure they all have the + same extension list.""" return operand_kinds @@ -751,45 +753,47 @@ def main(): if args.core_insts_output is not None: make_path_to_file(args.core_insts_output) make_path_to_file(args.operand_kinds_output) - print(generate_instruction_table(core_grammar['instructions']), - file=open(args.core_insts_output, 'w')) - print(generate_operand_kind_table(operand_kinds), - file=open(args.operand_kinds_output, 'w')) + with open(args.core_insts_output, 'w') as f: + f.write(generate_instruction_table( + core_grammar['instructions'])) + with open(args.operand_kinds_output, 'w') as f: + f.write(generate_operand_kind_table(operand_kinds)) if args.extension_enum_output is not None: make_path_to_file(args.extension_enum_output) - print(generate_extension_enum(extensions), - file=open(args.extension_enum_output, 'w')) + with open(args.extension_enum_output, 'w') as f: + f.write(generate_extension_enum(extensions)) if args.enum_string_mapping_output is not None: make_path_to_file(args.enum_string_mapping_output) - print(generate_all_string_enum_mappings(extensions, operand_kinds), - file=open(args.enum_string_mapping_output, 'w')) + with open(args.enum_string_mapping_output, 'w') as f: + f.write(generate_all_string_enum_mappings( + extensions, operand_kinds)) if args.extinst_glsl_grammar is not None: with open(args.extinst_glsl_grammar) as json_file: grammar = json.loads(json_file.read()) make_path_to_file(args.glsl_insts_output) - print(generate_extended_instruction_table( - grammar['instructions'], "glsl"), - file=open(args.glsl_insts_output, 'w')) + with open(args.glsl_insts_output, 'w') as f: + f.write(generate_extended_instruction_table( + grammar['instructions'], 'glsl')) if args.extinst_opencl_grammar is not None: with open(args.extinst_opencl_grammar) as json_file: grammar = json.loads(json_file.read()) make_path_to_file(args.opencl_insts_output) - print(generate_extended_instruction_table( - grammar['instructions'], "opencl"), - file=open(args.opencl_insts_output, 'w')) + with open(args.opencl_insts_output, 'w') as f: + f.write(generate_extended_instruction_table( + grammar['instructions'], 'opencl')) if args.extinst_vendor_grammar is not None: with open(args.extinst_vendor_grammar) as json_file: grammar = json.loads(json_file.read()) make_path_to_file(args.vendor_insts_output) name = args.extinst_vendor_grammar - start = name.find("extinst.") + len("extinst.") - name = name[start:-len(".grammar.json")].replace("-", "_") - print(generate_extended_instruction_table( - grammar['instructions'], name), - file=open(args.vendor_insts_output, 'w')) + start = name.find('extinst.') + len('extinst.') + name = name[start:-len('.grammar.json')].replace('-', '_') + with open(args.vendor_insts_output, 'w') as f: + f.write(generate_extended_instruction_table( + grammar['instructions'], name)) if __name__ == '__main__': diff --git a/3rdparty/spirv-tools/utils/generate_language_headers.py b/3rdparty/spirv-tools/utils/generate_language_headers.py index 1886bf4f3..029616336 100755 --- a/3rdparty/spirv-tools/utils/generate_language_headers.py +++ b/3rdparty/spirv-tools/utils/generate_language_headers.py @@ -14,8 +14,6 @@ # limitations under the License. """Generates language headers from a JSON grammar file""" -from __future__ import print_function - import errno import json import os.path @@ -181,7 +179,8 @@ def main(): version = grammar_json['version'], revision = grammar_json['revision']) make_path_to_file(args.extinst_output_base) - print(CGenerator().generate(grammar), file=open(args.extinst_output_base + '.h', 'w')) + with open(args.extinst_output_base + '.h', 'w') as f: + f.write(CGenerator().generate(grammar)) if __name__ == '__main__': diff --git a/3rdparty/spirv-tools/utils/generate_registry_tables.py b/3rdparty/spirv-tools/utils/generate_registry_tables.py index 8b1c35721..e662ba99b 100755 --- a/3rdparty/spirv-tools/utils/generate_registry_tables.py +++ b/3rdparty/spirv-tools/utils/generate_registry_tables.py @@ -14,8 +14,6 @@ # limitations under the License. """Generates the vendor tool table from the SPIR-V XML registry.""" -from __future__ import print_function - import distutils.dir_util import os.path import xml.etree.ElementTree @@ -65,7 +63,8 @@ def main(): registry = xml.etree.ElementTree.fromstring(xml_in.read()) distutils.dir_util.mkpath(os.path.dirname(args.generator_output)) - print(generate_vendor_table(registry), file=open(args.generator_output, 'w')) + with open(args.generator_output, 'w') as f: + f.write(generate_vendor_table(registry)) if __name__ == '__main__': diff --git a/3rdparty/spirv-tools/utils/generate_vim_syntax.py b/3rdparty/spirv-tools/utils/generate_vim_syntax.py index 03c0b478b..da7e99ba7 100755 --- a/3rdparty/spirv-tools/utils/generate_vim_syntax.py +++ b/3rdparty/spirv-tools/utils/generate_vim_syntax.py @@ -14,8 +14,6 @@ # limitations under the License. """Generates Vim syntax rules for SPIR-V assembly (.spvasm) files""" -from __future__ import print_function - import json PREAMBLE="""" Vim syntax file diff --git a/3rdparty/spirv-tools/utils/update_build_version.py b/3rdparty/spirv-tools/utils/update_build_version.py index d71aeccd9..119bb054f 100755 --- a/3rdparty/spirv-tools/utils/update_build_version.py +++ b/3rdparty/spirv-tools/utils/update_build_version.py @@ -29,8 +29,6 @@ # "unknown hash". # The string contents are escaped as necessary. -from __future__ import print_function - import datetime import errno import os