diff --git a/3rdparty/spirv-tools/Android.mk b/3rdparty/spirv-tools/Android.mk index c7f8e4790..2eb43682d 100644 --- a/3rdparty/spirv-tools/Android.mk +++ b/3rdparty/spirv-tools/Android.mk @@ -250,6 +250,8 @@ $(LOCAL_PATH)/source/ext_inst.cpp: \ $(1)/spv-amd-shader-ballot.insts.inc \ $(1)/spv-amd-shader-explicit-vertex-parameter.insts.inc \ $(1)/spv-amd-shader-trinary-minmax.insts.inc +$(LOCAL_PATH)/source/opt/amd_ext_to_khr.cpp: \ + $(1)/spv-amd-shader-ballot.insts.inc endef $(eval $(call gen_spvtools_grammar_tables,$(SPVTOOLS_OUT_PATH))) diff --git a/3rdparty/spirv-tools/BUILD.gn b/3rdparty/spirv-tools/BUILD.gn index 970e29521..ef83476ea 100644 --- a/3rdparty/spirv-tools/BUILD.gn +++ b/3rdparty/spirv-tools/BUILD.gn @@ -288,7 +288,10 @@ config("spvtools_internal_config") { configs = [ ":spvtools_public_config" ] if (is_clang) { - cflags = [ "-Wno-implicit-fallthrough" ] + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-newline-eof", + ] } } diff --git a/3rdparty/spirv-tools/CONTRIBUTING.md b/3rdparty/spirv-tools/CONTRIBUTING.md index 93a5610ee..b46ae31ec 100644 --- a/3rdparty/spirv-tools/CONTRIBUTING.md +++ b/3rdparty/spirv-tools/CONTRIBUTING.md @@ -4,7 +4,7 @@ We organize known future work in GitHub projects. See [Tracking SPIRV-Tools work with GitHub -projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/projects.md) +projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/docs/projects.md) for more. To report a new bug or request a new feature, please file a GitHub issue. Please diff --git a/3rdparty/spirv-tools/DEPS b/3rdparty/spirv-tools/DEPS index 70685ad80..5d2f3b787 100644 --- a/3rdparty/spirv-tools/DEPS +++ b/3rdparty/spirv-tools/DEPS @@ -6,7 +6,7 @@ vars = { 'effcee_revision': 'b83b58d177b797edd1f94c5f10837f2cc2863f0a', 'googletest_revision': '2f42d769ad1b08742f7ccb5ad4dd357fc5ff248c', 're2_revision': 'e356bd3f80e0c15c1050323bb5a2d0f8ea4845f4', - 'spirv_headers_revision': '123dc278f204f8e833e1a88d31c46d0edf81d4b2', + 'spirv_headers_revision': '601d738723ac381741311c6c98c36d6170be14a2', } deps = { diff --git a/3rdparty/spirv-tools/README.md b/3rdparty/spirv-tools/README.md index 8a5c85e11..b7e43fc8a 100644 --- a/3rdparty/spirv-tools/README.md +++ b/3rdparty/spirv-tools/README.md @@ -26,7 +26,7 @@ headers, and XML registry. MacOS[![MacOS Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_macos_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html) Windows[![Windows Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_windows_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_release.html) -[More downloads](downloads.md) +[More downloads](docs/downloads.md) ## Versioning SPIRV-Tools @@ -59,7 +59,7 @@ version. An API call reports the software version as a C-style string. IDs or types is performed, except to check literal arguments to `OpConstant`, `OpSpecConstant`, and `OpSwitch`. -See [`syntax.md`](syntax.md) for the assembly language syntax. +See [`docs/syntax.md`](docs/syntax.md) for the assembly language syntax. ### Validator @@ -171,7 +171,7 @@ specific work is tracked via issues and sometimes in one of the (To provide feedback on the SPIR-V _specification_, file an issue on the [SPIRV-Headers][spirv-headers] GitHub repository.) -See [`projects.md`](projects.md) to see how we use the +See [`docs/projects.md`](docs/projects.md) to see how we use the [GitHub Project feature](https://help.github.com/articles/tracking-the-progress-of-your-work-with-projects/) to organize planned and in-progress work. diff --git a/3rdparty/spirv-tools/downloads.md b/3rdparty/spirv-tools/docs/downloads.md similarity index 100% rename from 3rdparty/spirv-tools/downloads.md rename to 3rdparty/spirv-tools/docs/downloads.md diff --git a/3rdparty/spirv-tools/projects.md b/3rdparty/spirv-tools/docs/projects.md similarity index 100% rename from 3rdparty/spirv-tools/projects.md rename to 3rdparty/spirv-tools/docs/projects.md diff --git a/3rdparty/spirv-tools/syntax.md b/3rdparty/spirv-tools/docs/syntax.md similarity index 100% rename from 3rdparty/spirv-tools/syntax.md rename to 3rdparty/spirv-tools/docs/syntax.md diff --git a/3rdparty/spirv-tools/include/generated/build-version.inc b/3rdparty/spirv-tools/include/generated/build-version.inc index ea88d12a4..e7ab73ec9 100644 --- a/3rdparty/spirv-tools/include/generated/build-version.inc +++ b/3rdparty/spirv-tools/include/generated/build-version.inc @@ -1 +1 @@ -"v2019.5-dev", "SPIRV-Tools v2019.5-dev v2019.4-51-g1e146e8a" +"v2019.5-dev", "SPIRV-Tools v2019.5-dev v2019.4-71-g6b072126" diff --git a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc index 157c22e5d..49dc61907 100644 --- a/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc +++ b/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc @@ -62,6 +62,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_KHR_multiview"; case Extension::kSPV_KHR_no_integer_wrap_decoration: return "SPV_KHR_no_integer_wrap_decoration"; + case Extension::kSPV_KHR_physical_storage_buffer: + return "SPV_KHR_physical_storage_buffer"; case Extension::kSPV_KHR_post_depth_coverage: return "SPV_KHR_post_depth_coverage"; case Extension::kSPV_KHR_shader_atomic_counter_ops: @@ -117,8 +119,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_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 }; + 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_physical_storage_buffer", "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_physical_storage_buffer, 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( diff --git a/3rdparty/spirv-tools/include/generated/extension_enum.inc b/3rdparty/spirv-tools/include/generated/extension_enum.inc index 81ee5f124..e34f942bb 100644 --- a/3rdparty/spirv-tools/include/generated/extension_enum.inc +++ b/3rdparty/spirv-tools/include/generated/extension_enum.inc @@ -29,6 +29,7 @@ kSPV_KHR_device_group, kSPV_KHR_float_controls, kSPV_KHR_multiview, kSPV_KHR_no_integer_wrap_decoration, +kSPV_KHR_physical_storage_buffer, kSPV_KHR_post_depth_coverage, kSPV_KHR_shader_atomic_counter_ops, kSPV_KHR_shader_ballot, diff --git a/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc b/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc index 284e6009e..eb4bc6712 100644 --- a/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc +++ b/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc @@ -97,7 +97,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_descriptor_indexing static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_fully_covered[] = {spvtools::Extension::kSPV_EXT_fragment_fully_covered}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate[] = {spvtools::Extension::kSPV_EXT_fragment_invocation_density, spvtools::Extension::kSPV_NV_shading_rate}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock}; -static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer, spvtools::Extension::kSPV_KHR_physical_storage_buffer}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_stencil_export[] = {spvtools::Extension::kSPV_EXT_shader_stencil_export}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer, spvtools::Extension::kSPV_NV_viewport_array2}; static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; @@ -267,8 +267,8 @@ static const spv_operand_desc_t pygen_variable_AddressingModelEntries[] = { {"Logical", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"Physical32", 1, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"Physical64", 2, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, - {"PhysicalStorageBuffer64", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} + {"PhysicalStorageBuffer64", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_MemoryModelEntries[] = { @@ -358,8 +358,8 @@ static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = { {"HitAttributeNV", 5339, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"IncomingRayPayloadNV", 5342, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"ShaderRecordBufferNV", 5343, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} + {"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_DimEntries[] = { @@ -561,10 +561,10 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = { {"PerVertexNV", 5285, 1, pygen_variable_caps_FragmentBarycentricNV, 1, pygen_variable_exts_SPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, {"NonUniform", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"NonUniformEXT", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"RestrictPointer", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"RestrictPointerEXT", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"AliasedPointer", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"AliasedPointerEXT", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RestrictPointer", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RestrictPointerEXT", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"AliasedPointer", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"AliasedPointerEXT", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"CounterBuffer", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, {"HlslCounterBufferGOOGLE", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, {"UserSemantic", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, @@ -846,8 +846,8 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"VulkanMemoryModelKHR", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"VulkanMemoryModelDeviceScope", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"VulkanMemoryModelDeviceScopeKHR", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"PhysicalStorageBufferAddresses", 5347, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, - {"PhysicalStorageBufferAddressesEXT", 5347, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferAddresses", 5347, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferAddressesEXT", 5347, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"ComputeDerivativeGroupLinearNV", 5350, 0, nullptr, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, {"CooperativeMatrixNV", 5357, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, {}, 0xffffffffu, 0xffffffffu}, {"FragmentShaderSampleInterlockEXT", 5363, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, diff --git a/3rdparty/spirv-tools/include/spirv-tools/libspirv.h b/3rdparty/spirv-tools/include/spirv-tools/libspirv.h index 672848ea1..dd2526bf3 100644 --- a/3rdparty/spirv-tools/include/spirv-tools/libspirv.h +++ b/3rdparty/spirv-tools/include/spirv-tools/libspirv.h @@ -612,6 +612,11 @@ SPIRV_TOOLS_EXPORT spv_fuzzer_options spvFuzzerOptionsCreate(); // Destroys the given fuzzer options object. SPIRV_TOOLS_EXPORT void spvFuzzerOptionsDestroy(spv_fuzzer_options options); +// Enables running the validator after every transformation is applied during +// a replay. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableReplayValidation( + spv_fuzzer_options options); + // Sets the seed with which the random number generator used by the fuzzer // should be initialized. SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetRandomSeed( diff --git a/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp b/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp index 2da1152aa..b09fdd457 100644 --- a/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp +++ b/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp @@ -214,6 +214,11 @@ class FuzzerOptions { return options_; } + // See spvFuzzerOptionsEnableReplayValidation. + void enable_replay_validation() { + spvFuzzerOptionsEnableReplayValidation(options_); + } + // See spvFuzzerOptionsSetRandomSeed. void set_random_seed(uint32_t seed) { spvFuzzerOptionsSetRandomSeed(options_, seed); diff --git a/3rdparty/spirv-tools/source/fuzz/CMakeLists.txt b/3rdparty/spirv-tools/source/fuzz/CMakeLists.txt index c0592b347..ac8c002b3 100644 --- a/3rdparty/spirv-tools/source/fuzz/CMakeLists.txt +++ b/3rdparty/spirv-tools/source/fuzz/CMakeLists.txt @@ -13,6 +13,9 @@ # limitations under the License. if(SPIRV_BUILD_FUZZER) + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/protobufs) + set(PROTOBUF_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/protobufs/spvtoolsfuzz.proto) add_custom_command( @@ -34,6 +37,7 @@ if(SPIRV_BUILD_FUZZER) fuzzer_pass_add_dead_breaks.h fuzzer_pass_add_dead_continues.h fuzzer_pass_add_useful_constructs.h + fuzzer_pass_apply_id_synonyms.h fuzzer_pass_copy_objects.h fuzzer_pass_obfuscate_constants.h fuzzer_pass_permute_blocks.h @@ -58,6 +62,7 @@ if(SPIRV_BUILD_FUZZER) transformation_move_block_down.h transformation_replace_boolean_constant_with_constant_binary.h transformation_replace_constant_with_uniform.h + transformation_replace_id_with_synonym.h transformation_split_block.h uniform_buffer_element_descriptor.h ${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.h @@ -70,6 +75,7 @@ if(SPIRV_BUILD_FUZZER) fuzzer_pass_add_dead_breaks.cpp fuzzer_pass_add_dead_continues.cpp fuzzer_pass_add_useful_constructs.cpp + fuzzer_pass_apply_id_synonyms.cpp fuzzer_pass_copy_objects.cpp fuzzer_pass_obfuscate_constants.cpp fuzzer_pass_permute_blocks.cpp @@ -93,6 +99,7 @@ if(SPIRV_BUILD_FUZZER) transformation_move_block_down.cpp transformation_replace_boolean_constant_with_constant_binary.cpp transformation_replace_constant_with_uniform.cpp + transformation_replace_id_with_synonym.cpp transformation_split_block.cpp uniform_buffer_element_descriptor.cpp ${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.cc diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer.cpp b/3rdparty/spirv-tools/source/fuzz/fuzzer.cpp index 9d2a7c74a..3b0349381 100644 --- a/3rdparty/spirv-tools/source/fuzz/fuzzer.cpp +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer.cpp @@ -22,6 +22,7 @@ #include "source/fuzz/fuzzer_pass_add_dead_breaks.h" #include "source/fuzz/fuzzer_pass_add_dead_continues.h" #include "source/fuzz/fuzzer_pass_add_useful_constructs.h" +#include "source/fuzz/fuzzer_pass_apply_id_synonyms.h" #include "source/fuzz/fuzzer_pass_copy_objects.h" #include "source/fuzz/fuzzer_pass_obfuscate_constants.h" #include "source/fuzz/fuzzer_pass_permute_blocks.h" @@ -111,6 +112,9 @@ Fuzzer::FuzzerResultStatus Fuzzer::Run( FuzzerPassCopyObjects(ir_context.get(), &fact_manager, &fuzzer_context, transformation_sequence_out) .Apply(); + FuzzerPassApplyIdSynonyms(ir_context.get(), &fact_manager, &fuzzer_context, + transformation_sequence_out) + .Apply(); FuzzerPassSplitBlocks(ir_context.get(), &fact_manager, &fuzzer_context, transformation_sequence_out) .Apply(); diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer_context.cpp b/3rdparty/spirv-tools/source/fuzz/fuzzer_context.cpp index e9398d5fd..8d097b095 100644 --- a/3rdparty/spirv-tools/source/fuzz/fuzzer_context.cpp +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer_context.cpp @@ -29,6 +29,7 @@ const uint32_t kDefaultChanceOfAddingDeadContinue = 20; const uint32_t kDefaultChanceOfCopyingObject = 20; const uint32_t kDefaultChanceOfMovingBlockDown = 25; const uint32_t kDefaultChanceOfObfuscatingConstant = 20; +const uint32_t kDefaultChanceOfReplacingIdWithSynonym = 20; const uint32_t kDefaultChanceOfSplittingBlock = 20; // Default functions for controlling how deep to go during recursive @@ -52,6 +53,8 @@ FuzzerContext::FuzzerContext(RandomGenerator* random_generator, chance_of_copying_object_(kDefaultChanceOfCopyingObject), chance_of_moving_block_down_(kDefaultChanceOfMovingBlockDown), chance_of_obfuscating_constant_(kDefaultChanceOfObfuscatingConstant), + chance_of_replacing_id_with_synonym_( + kDefaultChanceOfReplacingIdWithSynonym), chance_of_splitting_block_(kDefaultChanceOfSplittingBlock), go_deeper_in_constant_obfuscation_( kDefaultGoDeeperInConstantObfuscation) {} diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer_context.h b/3rdparty/spirv-tools/source/fuzz/fuzzer_context.h index ed6a3551a..90d875668 100644 --- a/3rdparty/spirv-tools/source/fuzz/fuzzer_context.h +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer_context.h @@ -66,6 +66,9 @@ class FuzzerContext { uint32_t GetChanceOfObfuscatingConstant() { return chance_of_obfuscating_constant_; } + uint32_t GetChanceOfReplacingIdWithSynonym() { + return chance_of_replacing_id_with_synonym_; + } uint32_t GetChanceOfSplittingBlock() { return chance_of_splitting_block_; } // Functions to control how deeply to recurse. @@ -87,6 +90,7 @@ class FuzzerContext { uint32_t chance_of_copying_object_; uint32_t chance_of_moving_block_down_; uint32_t chance_of_obfuscating_constant_; + uint32_t chance_of_replacing_id_with_synonym_; uint32_t chance_of_splitting_block_; // Functions to determine with what probability to go deeper when generating diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_breaks.cpp b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_breaks.cpp index d8380d3e7..fa6b09884 100644 --- a/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_breaks.cpp +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_breaks.cpp @@ -47,9 +47,9 @@ void FuzzerPassAddDeadBreaks::Apply() { // ones that turn out to be no good. for (auto& block : function) { for (auto merge_block_id : merge_block_ids) { - // TODO(afd): right now we completely ignore OpPhi instructions at - // merge blocks. This will lead to interesting opportunities being - // missed. + // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2856): right + // now we completely ignore OpPhi instructions at merge blocks. This + // will lead to interesting opportunities being missed. auto candidate_transformation = TransformationAddDeadBreak( block.id(), merge_block_id, GetFuzzerContext()->ChooseEven(), {}); if (candidate_transformation.IsApplicable(GetIRContext(), diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_continues.cpp b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_continues.cpp index ac4c72f76..51bcb91eb 100644 --- a/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_continues.cpp +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_add_dead_continues.cpp @@ -36,9 +36,9 @@ void FuzzerPassAddDeadContinues::Apply() { // node turns out to be inappropriate (e.g. by not being in a loop) the // precondition for the transformation will fail and it will be ignored. // - // TODO(afd): right now we completely ignore OpPhi instructions at - // merge blocks. This will lead to interesting opportunities being - // missed. + // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2856): right + // now we completely ignore OpPhi instructions at continue targets. + // This will lead to interesting opportunities being missed. auto candidate_transformation = TransformationAddDeadContinue( block.id(), GetFuzzerContext()->ChooseEven(), {}); // Probabilistically decide whether to apply the transformation in the diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp new file mode 100644 index 000000000..703f6f271 --- /dev/null +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp @@ -0,0 +1,108 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/fuzz/fuzzer_pass_apply_id_synonyms.h" + +#include "source/fuzz/id_use_descriptor.h" +#include "source/fuzz/transformation_replace_id_with_synonym.h" + +namespace spvtools { +namespace fuzz { + +FuzzerPassApplyIdSynonyms::FuzzerPassApplyIdSynonyms( + opt::IRContext* ir_context, FactManager* fact_manager, + FuzzerContext* fuzzer_context, + protobufs::TransformationSequence* transformations) + : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {} + +FuzzerPassApplyIdSynonyms::~FuzzerPassApplyIdSynonyms() = default; + +void FuzzerPassApplyIdSynonyms::Apply() { + std::vector transformations_to_apply; + + for (auto id_with_known_synonyms : + GetFactManager()->GetIdsForWhichSynonymsAreKnown()) { + GetIRContext()->get_def_use_mgr()->ForEachUse( + id_with_known_synonyms, + [this, id_with_known_synonyms, &transformations_to_apply]( + opt::Instruction* use_inst, uint32_t use_index) -> void { + auto block_containing_use = GetIRContext()->get_instr_block(use_inst); + // The use might not be in a block; e.g. it could be a decoration. + if (!block_containing_use) { + return; + } + if (!GetFuzzerContext()->ChoosePercentage( + GetFuzzerContext()->GetChanceOfReplacingIdWithSynonym())) { + return; + } + + std::vector synonyms_to_try; + for (auto& data_descriptor : + GetFactManager()->GetSynonymsForId(id_with_known_synonyms)) { + synonyms_to_try.push_back(&data_descriptor); + } + while (!synonyms_to_try.empty()) { + auto synonym_index = + GetFuzzerContext()->RandomIndex(synonyms_to_try); + auto synonym_to_try = synonyms_to_try[synonym_index]; + synonyms_to_try.erase(synonyms_to_try.begin() + synonym_index); + assert(synonym_to_try->index().empty() && + "Right now we only support id == id synonyms; supporting " + "e.g. id == index-into-vector will come later"); + + if (!TransformationReplaceIdWithSynonym:: + ReplacingUseWithSynonymIsOk(GetIRContext(), use_inst, + use_index, *synonym_to_try)) { + continue; + } + + // |use_index| is the absolute index of the operand. We require + // the index of the operand restricted to input operands only, so + // we subtract the number of non-input operands from |use_index|. + uint32_t number_of_non_input_operands = + use_inst->NumOperands() - use_inst->NumInOperands(); + TransformationReplaceIdWithSynonym replace_id_transformation( + transformation::MakeIdUseDescriptorFromUse( + GetIRContext(), use_inst, + use_index - number_of_non_input_operands), + *synonym_to_try, 0); + // The transformation should be applicable by construction. + assert(replace_id_transformation.IsApplicable(GetIRContext(), + *GetFactManager())); + // We cannot actually apply the transformation here, as this would + // change the analysis results that are being depended on for usage + // iteration. We instead store them up and apply them at the end + // of the method. + transformations_to_apply.push_back(replace_id_transformation); + break; + } + }); + } + + for (auto& replace_id_transformation : transformations_to_apply) { + // Even though replacing id uses with synonyms may lead to new instructions + // (to compute indices into composites), as these instructions will generate + // ids, their presence should not affect the id use descriptors that were + // computed during the creation of transformations. Thus transformations + // should not disable one another. + assert(replace_id_transformation.IsApplicable(GetIRContext(), + *GetFactManager())); + replace_id_transformation.Apply(GetIRContext(), GetFactManager()); + *GetTransformations()->add_transformation() = + replace_id_transformation.ToMessage(); + } +} + +} // namespace fuzz +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_apply_id_synonyms.h b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_apply_id_synonyms.h new file mode 100644 index 000000000..1a0748eb4 --- /dev/null +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer_pass_apply_id_synonyms.h @@ -0,0 +1,42 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_FUZZ_FUZZER_PASS_APPLY_ID_SYNONYMS_ +#define SOURCE_FUZZ_FUZZER_PASS_APPLY_ID_SYNONYMS_ + +#include "source/fuzz/fuzzer_pass.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace fuzz { + +// A pass that replaces ids with other ids, or accesses into structures, that +// are known to hold the same values. +class FuzzerPassApplyIdSynonyms : public FuzzerPass { + public: + FuzzerPassApplyIdSynonyms(opt::IRContext* ir_context, + FactManager* fact_manager, + FuzzerContext* fuzzer_context, + protobufs::TransformationSequence* transformations); + + ~FuzzerPassApplyIdSynonyms() override; + + void Apply() override; +}; + +} // namespace fuzz +} // namespace spvtools + +#endif // SOURCE_FUZZ_FUZZER_PASS_APPLY_ID_SYNONYMS_ diff --git a/3rdparty/spirv-tools/source/fuzz/fuzzer_util.cpp b/3rdparty/spirv-tools/source/fuzz/fuzzer_util.cpp index 4cf3f2059..8173d0f2c 100644 --- a/3rdparty/spirv-tools/source/fuzz/fuzzer_util.cpp +++ b/3rdparty/spirv-tools/source/fuzz/fuzzer_util.cpp @@ -205,6 +205,7 @@ opt::BasicBlock::iterator GetIteratorForBaseInstructionAndOffset( return nullptr; } +// Returns the ids of all successors of |block| std::vector GetSuccessors(opt::BasicBlock* block) { std::vector result; switch (block->terminator()->opcode()) { @@ -226,6 +227,41 @@ std::vector GetSuccessors(opt::BasicBlock* block) { return result; } +// The FindBypassedBlocks method and its helpers perform a depth-first search; +// this struct represents an element of the stack used during depth-first +// search. +struct FindBypassedBlocksDfsStackNode { + opt::BasicBlock* block; // The block that is being explored + bool handled_merge; // We visit merge blocks before successors; this field + // tracks whether we have yet processed the merge block + // (if any) associated with the block + uint32_t next_successor; // The next as-yet unexplored successor of this + // block; exploration of a block is complete when + // this field's value reaches the successor count +}; + +// Helper method for the depth-first-search routine that collects blocks that a +// new break or continue control flow graph edge will bypass. +void HandleSuccessorDuringSearchForBypassedBlocks( + opt::BasicBlock* successor, bool new_blocks_will_be_bypassed, + std::set* already_visited, + std::set* bypassed_blocks, + std::vector* dfs_stack) { + if (already_visited->count(successor->id()) == 0) { + // This is a new block; mark it as visited so that we don't regard it as new + // in the future, and push it on to the stack for exploration. + already_visited->insert(successor->id()); + dfs_stack->push_back({successor, false, 0}); + if (new_blocks_will_be_bypassed) { + // We are in the region of the control-flow graph consisting of blocks + // that the new edge will bypass, so grab this block. + bypassed_blocks->insert(successor); + } + } +} + +// Determines those block that will be bypassed by a break or continue edge from +// |bb_from| to |bb_to|. void FindBypassedBlocks(opt::IRContext* context, opt::BasicBlock* bb_from, opt::BasicBlock* bb_to, std::set* bypassed_blocks) { @@ -240,51 +276,40 @@ void FindBypassedBlocks(opt::IRContext* context, opt::BasicBlock* bb_from, // visited in the sub-search rooted at |bb_from|. (As an optimization, the // search terminates as soon as exploration of |bb_from| has completed.) - // This represents a basic block in a partial state of exploration. As we - // wish to visit merge blocks in advance of regular successors, we track them - // separately. - struct StackNode { - opt::BasicBlock* block; - bool handled_merge; - std::vector successors; - uint32_t next_successor; - }; - auto enclosing_function = bb_from->GetParent(); // The set of block ids already visited during search. We put |bb_to| in // there initially so that search automatically backtracks when this block is // reached. - std::set visited; - visited.insert(bb_to->id()); + std::set already_visited; + already_visited.insert(bb_to->id()); - // Tracks when we are in the region of blocks that are to be grabbed; we flip - // this to 'true' once we reach |bb_from| and have finished searching its - // merge block (in the case that it happens to be a header. - bool interested = false; + // Tracks when we are in the region of blocks that the new edge would bypass; + // we flip this to 'true' once we reach |bb_from| and have finished searching + // its merge block (in the case that it happens to be a header. + bool new_blocks_will_be_bypassed = false; - std::vector dfs_stack; + std::vector dfs_stack; opt::BasicBlock* entry_block = enclosing_function->entry().get(); - dfs_stack.push_back({entry_block, false, GetSuccessors(entry_block), 0}); + dfs_stack.push_back({entry_block, false, 0}); while (!dfs_stack.empty()) { - StackNode* node = &dfs_stack.back(); + auto node_index = dfs_stack.size() - 1; // First make sure we search the merge block associated ith this block, if // there is one. - if (!node->handled_merge) { - node->handled_merge = true; - if (node->block->MergeBlockIdIfAny()) { - opt::BasicBlock* merge_block = - context->cfg()->block(node->block->MergeBlockIdIfAny()); + if (!dfs_stack[node_index].handled_merge) { + dfs_stack[node_index].handled_merge = true; + if (dfs_stack[node_index].block->MergeBlockIdIfAny()) { + opt::BasicBlock* merge_block = context->cfg()->block( + dfs_stack[node_index].block->MergeBlockIdIfAny()); // A block can only be the merge block for one header, so this block // should only be in |visited| if it is |bb_to|, which we put into // |visited| in advance. - assert(visited.count(merge_block->id()) == 0 || merge_block == bb_to); - if (visited.count(merge_block->id()) == 0) { - visited.insert(merge_block->id()); - dfs_stack.push_back( - {merge_block, false, GetSuccessors(merge_block), 0}); - } + assert(already_visited.count(merge_block->id()) == 0 || + merge_block == bb_to); + HandleSuccessorDuringSearchForBypassedBlocks( + merge_block, new_blocks_will_be_bypassed, &already_visited, + bypassed_blocks, &dfs_stack); } continue; } @@ -292,28 +317,23 @@ void FindBypassedBlocks(opt::IRContext* context, opt::BasicBlock* bb_from, // If we find |bb_from|, we are interested in grabbing previously unseen // successor blocks (by this point we will have already searched the merge // block associated with |bb_from|, if there is one. - if (node->block == bb_from) { - interested = true; + if (dfs_stack[node_index].block == bb_from) { + new_blocks_will_be_bypassed = true; } // Consider the next unexplored successor. - if (node->next_successor < node->successors.size()) { - uint32_t successor_id = node->successors[node->next_successor]; - if (visited.count(successor_id) == 0) { - visited.insert(successor_id); - opt::BasicBlock* successor_block = context->cfg()->block(successor_id); - if (interested) { - // If we're in the region of interest, grab this block. - bypassed_blocks->insert(successor_block); - } - dfs_stack.push_back( - {successor_block, false, GetSuccessors(successor_block), 0}); - } - node->next_successor++; + auto successors = GetSuccessors(dfs_stack[node_index].block); + if (dfs_stack[node_index].next_successor < successors.size()) { + HandleSuccessorDuringSearchForBypassedBlocks( + context->cfg()->block( + successors[dfs_stack[node_index].next_successor]), + new_blocks_will_be_bypassed, &already_visited, bypassed_blocks, + &dfs_stack); + dfs_stack[node_index].next_successor++; } else { // We have finished exploring |node|. If it is |bb_from|, we can // terminate search -- we have grabbed all the relevant blocks. - if (node->block == bb_from) { + if (dfs_stack[node_index].block == bb_from) { break; } dfs_stack.pop_back(); diff --git a/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.cpp b/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.cpp index 33d2ca089..8693a7d1b 100644 --- a/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.cpp +++ b/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.cpp @@ -78,5 +78,33 @@ protobufs::IdUseDescriptor transformation::MakeIdUseDescriptor( return result; } +protobufs::IdUseDescriptor transformation::MakeIdUseDescriptorFromUse( + opt::IRContext* context, opt::Instruction* inst, + uint32_t in_operand_index) { + auto in_operand = inst->GetInOperand(in_operand_index); + assert(in_operand.type == SPV_OPERAND_TYPE_ID); + auto id_of_interest = in_operand.words[0]; + + auto block = context->get_instr_block(inst); + uint32_t base_instruction_result_id = block->id(); + uint32_t num_opcodes_to_ignore = 0; + for (auto& inst_in_block : *block) { + if (inst_in_block.HasResultId()) { + base_instruction_result_id = inst_in_block.result_id(); + num_opcodes_to_ignore = 0; + } + if (&inst_in_block == inst) { + return MakeIdUseDescriptor(id_of_interest, inst->opcode(), + in_operand_index, base_instruction_result_id, + num_opcodes_to_ignore); + } + if (inst_in_block.opcode() == inst->opcode()) { + num_opcodes_to_ignore++; + } + } + assert(false && "No matching instruction was found."); + return protobufs::IdUseDescriptor(); +} + } // namespace fuzz } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.h b/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.h index 63016c5da..1657cb923 100644 --- a/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.h +++ b/3rdparty/spirv-tools/source/fuzz/id_use_descriptor.h @@ -35,6 +35,12 @@ protobufs::IdUseDescriptor MakeIdUseDescriptor( uint32_t in_operand_index, uint32_t base_instruction_result_id, uint32_t num_opcodes_to_ignore); +// Given an id use, represented by the instruction |inst| that uses the id, and +// the input operand index |in_operand_index| associated with the usage, returns +// an IdUseDescriptor that represents the use. +protobufs::IdUseDescriptor MakeIdUseDescriptorFromUse( + opt::IRContext* context, opt::Instruction* inst, uint32_t in_operand_index); + } // namespace transformation } // namespace fuzz } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/fuzz/protobufs/spvtoolsfuzz.proto b/3rdparty/spirv-tools/source/fuzz/protobufs/spvtoolsfuzz.proto index 4e8dcac3c..64ccd8efa 100644 --- a/3rdparty/spirv-tools/source/fuzz/protobufs/spvtoolsfuzz.proto +++ b/3rdparty/spirv-tools/source/fuzz/protobufs/spvtoolsfuzz.proto @@ -172,6 +172,7 @@ message Transformation { TransformationReplaceConstantWithUniform replace_constant_with_uniform = 11; TransformationAddDeadContinue add_dead_continue = 12; TransformationCopyObject copy_object = 13; + TransformationReplaceIdWithSynonym replace_id_with_synonym = 14; // Add additional option using the next available number. } } @@ -325,25 +326,6 @@ message TransformationMoveBlockDown { uint32 block_id = 1; } -message TransformationReplaceConstantWithUniform { - - // Replaces a use of a constant id with the the result of a load from an - // element of uniform buffer known to hold the same value as the constant - - // A descriptor for the id we would like to replace - IdUseDescriptor id_use_descriptor = 1; - - // Uniform descriptor to identify which uniform value to choose - UniformBufferElementDescriptor uniform_descriptor = 2; - - // Id that will store the result of an access chain - uint32 fresh_id_for_access_chain = 3; - - // Id that will store the result of a load - uint32 fresh_id_for_load = 4; - -} - message TransformationReplaceBooleanConstantWithConstantBinary { // A transformation to capture replacing a use of a boolean constant with @@ -366,6 +348,42 @@ message TransformationReplaceBooleanConstantWithConstantBinary { } +message TransformationReplaceConstantWithUniform { + + // Replaces a use of a constant id with the result of a load from an + // element of uniform buffer known to hold the same value as the constant + + // A descriptor for the id we would like to replace + IdUseDescriptor id_use_descriptor = 1; + + // Uniform descriptor to identify which uniform value to choose + UniformBufferElementDescriptor uniform_descriptor = 2; + + // Id that will store the result of an access chain + uint32 fresh_id_for_access_chain = 3; + + // Id that will store the result of a load + uint32 fresh_id_for_load = 4; + +} + +message TransformationReplaceIdWithSynonym { + + // Replaces an id use with something known to be synonymous with that id use, + // e.g. because it was obtained via applying OpCopyObject + + // Identifies the id use that is to be replaced + IdUseDescriptor id_use_descriptor = 1; + + // Identifies the data with which the id use is expected to be synonymous + DataDescriptor data_descriptor = 2; + + // In the case that a temporary is required to express the synonym (e.g. to + // obtain an element of a vector, provides a fresh id for the temporary; + // should be set to 0 if no temporary is required + uint32 fresh_id_for_temporary = 3; +} + message TransformationSplitBlock { // A transformation that splits a basic block into two basic blocks diff --git a/3rdparty/spirv-tools/source/fuzz/replayer.cpp b/3rdparty/spirv-tools/source/fuzz/replayer.cpp index b0d4ee2ec..398ce5950 100644 --- a/3rdparty/spirv-tools/source/fuzz/replayer.cpp +++ b/3rdparty/spirv-tools/source/fuzz/replayer.cpp @@ -37,13 +37,18 @@ namespace spvtools { namespace fuzz { struct Replayer::Impl { - explicit Impl(spv_target_env env) : target_env(env) {} + explicit Impl(spv_target_env env, bool validate) + : target_env(env), validate_during_replay(validate) {} const spv_target_env target_env; // Target environment. MessageConsumer consumer; // Message consumer. + + const bool validate_during_replay; // Controls whether the validator should + // be run after every replay step. }; -Replayer::Replayer(spv_target_env env) : impl_(MakeUnique(env)) {} +Replayer::Replayer(spv_target_env env, bool validate_during_replay) + : impl_(MakeUnique(env, validate_during_replay)) {} Replayer::~Replayer() = default; @@ -80,6 +85,13 @@ Replayer::ReplayerResultStatus Replayer::Run( impl_->target_env, impl_->consumer, binary_in.data(), binary_in.size()); assert(ir_context); + // For replay validation, we track the last valid SPIR-V binary that was + // observed. Initially this is the input binary. + std::vector last_valid_binary; + if (impl_->validate_during_replay) { + last_valid_binary = binary_in; + } + FactManager fact_manager; fact_manager.AddFacts(impl_->consumer, initial_facts, ir_context.get()); @@ -93,6 +105,23 @@ Replayer::ReplayerResultStatus Replayer::Run( // sequence of transformations that were applied. transformation->Apply(ir_context.get(), &fact_manager); *transformation_sequence_out->add_transformation() = message; + + if (impl_->validate_during_replay) { + std::vector binary_to_validate; + ir_context->module()->ToBinary(&binary_to_validate, false); + + // Check whether the latest transformation led to a valid binary. + if (!tools.Validate(&binary_to_validate[0], + binary_to_validate.size())) { + impl_->consumer(SPV_MSG_INFO, nullptr, {}, + "Binary became invalid during replay (set a " + "breakpoint to inspect); stopping."); + return Replayer::ReplayerResultStatus::kReplayValidationFailure; + } + + // The binary was valid, so it becomes the latest valid binary. + last_valid_binary = std::move(binary_to_validate); + } } } diff --git a/3rdparty/spirv-tools/source/fuzz/replayer.h b/3rdparty/spirv-tools/source/fuzz/replayer.h index 13391d07c..1d58baeb7 100644 --- a/3rdparty/spirv-tools/source/fuzz/replayer.h +++ b/3rdparty/spirv-tools/source/fuzz/replayer.h @@ -33,10 +33,11 @@ class Replayer { kComplete, kFailedToCreateSpirvToolsInterface, kInitialBinaryInvalid, + kReplayValidationFailure, }; // Constructs a replayer from the given target environment. - explicit Replayer(spv_target_env env); + explicit Replayer(spv_target_env env, bool validate_during_replay); // Disables copy/move constructor/assignment operations. Replayer(const Replayer&) = delete; diff --git a/3rdparty/spirv-tools/source/fuzz/shrinker.cpp b/3rdparty/spirv-tools/source/fuzz/shrinker.cpp index f8d8aa309..1bb92f100 100644 --- a/3rdparty/spirv-tools/source/fuzz/shrinker.cpp +++ b/3rdparty/spirv-tools/source/fuzz/shrinker.cpp @@ -60,16 +60,20 @@ protobufs::TransformationSequence RemoveChunk( } // namespace struct Shrinker::Impl { - explicit Impl(spv_target_env env, uint32_t limit) - : target_env(env), step_limit(limit) {} + explicit Impl(spv_target_env env, uint32_t limit, bool validate) + : target_env(env), step_limit(limit), validate_during_replay(validate) {} - const spv_target_env target_env; // Target environment. - MessageConsumer consumer; // Message consumer. - const uint32_t step_limit; // Step limit for reductions. + const spv_target_env target_env; // Target environment. + MessageConsumer consumer; // Message consumer. + const uint32_t step_limit; // Step limit for reductions. + const bool validate_during_replay; // Determines whether to check for + // validity during the replaying of + // transformations. }; -Shrinker::Shrinker(spv_target_env env, uint32_t step_limit) - : impl_(MakeUnique(env, step_limit)) {} +Shrinker::Shrinker(spv_target_env env, uint32_t step_limit, + bool validate_during_replay) + : impl_(MakeUnique(env, step_limit, validate_during_replay)) {} Shrinker::~Shrinker() = default; @@ -109,7 +113,7 @@ Shrinker::ShrinkerResultStatus Shrinker::Run( // succeeds, (b) get the binary that results from running these // transformations, and (c) get the subsequence of the initial transformations // that actually apply (in principle this could be a strict subsequence). - if (Replayer(impl_->target_env) + if (Replayer(impl_->target_env, impl_->validate_during_replay) .Run(binary_in, initial_facts, transformation_sequence_in, ¤t_best_binary, ¤t_best_transformations) != Replayer::ReplayerResultStatus::kComplete) { @@ -180,7 +184,7 @@ Shrinker::ShrinkerResultStatus Shrinker::Run( // transformations inapplicable. std::vector next_binary; protobufs::TransformationSequence next_transformation_sequence; - if (Replayer(impl_->target_env) + if (Replayer(impl_->target_env, false) .Run(binary_in, initial_facts, transformations_with_chunk_removed, &next_binary, &next_transformation_sequence) != Replayer::ReplayerResultStatus::kComplete) { diff --git a/3rdparty/spirv-tools/source/fuzz/shrinker.h b/3rdparty/spirv-tools/source/fuzz/shrinker.h index 72dd470b0..0163a53ab 100644 --- a/3rdparty/spirv-tools/source/fuzz/shrinker.h +++ b/3rdparty/spirv-tools/source/fuzz/shrinker.h @@ -50,7 +50,8 @@ class Shrinker { const std::vector& binary, uint32_t counter)>; // Constructs a shrinker from the given target environment. - Shrinker(spv_target_env env, uint32_t step_limit); + Shrinker(spv_target_env env, uint32_t step_limit, + bool validate_during_replay); // Disables copy/move constructor/assignment operations. Shrinker(const Shrinker&) = delete; diff --git a/3rdparty/spirv-tools/source/fuzz/transformation.cpp b/3rdparty/spirv-tools/source/fuzz/transformation.cpp index bf2cdcd08..65966f350 100644 --- a/3rdparty/spirv-tools/source/fuzz/transformation.cpp +++ b/3rdparty/spirv-tools/source/fuzz/transformation.cpp @@ -29,6 +29,7 @@ #include "transformation_move_block_down.h" #include "transformation_replace_boolean_constant_with_constant_binary.h" #include "transformation_replace_constant_with_uniform.h" +#include "transformation_replace_id_with_synonym.h" #include "transformation_split_block.h" namespace spvtools { @@ -72,6 +73,9 @@ std::unique_ptr Transformation::FromMessage( kReplaceConstantWithUniform: return MakeUnique( message.replace_constant_with_uniform()); + case protobufs::Transformation::TransformationCase::kReplaceIdWithSynonym: + return MakeUnique( + message.replace_id_with_synonym()); case protobufs::Transformation::TransformationCase::kSplitBlock: return MakeUnique(message.split_block()); case protobufs::Transformation::TRANSFORMATION_NOT_SET: diff --git a/3rdparty/spirv-tools/source/fuzz/transformation_replace_id_with_synonym.cpp b/3rdparty/spirv-tools/source/fuzz/transformation_replace_id_with_synonym.cpp new file mode 100644 index 000000000..a88748086 --- /dev/null +++ b/3rdparty/spirv-tools/source/fuzz/transformation_replace_id_with_synonym.cpp @@ -0,0 +1,155 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/fuzz/transformation_replace_id_with_synonym.h" + +#include + +#include "source/fuzz/data_descriptor.h" +#include "source/fuzz/fuzzer_util.h" +#include "source/fuzz/id_use_descriptor.h" + +namespace spvtools { +namespace fuzz { + +TransformationReplaceIdWithSynonym::TransformationReplaceIdWithSynonym( + const spvtools::fuzz::protobufs::TransformationReplaceIdWithSynonym& + message) + : message_(message) {} + +TransformationReplaceIdWithSynonym::TransformationReplaceIdWithSynonym( + protobufs::IdUseDescriptor id_use_descriptor, + protobufs::DataDescriptor data_descriptor, + uint32_t fresh_id_for_temporary) { + assert(fresh_id_for_temporary == 0 && data_descriptor.index().size() == 0 && + "At present we do not support making an id that is synonymous with an " + "index into a composite."); + *message_.mutable_id_use_descriptor() = std::move(id_use_descriptor); + *message_.mutable_data_descriptor() = std::move(data_descriptor); + message_.set_fresh_id_for_temporary(fresh_id_for_temporary); +} + +bool TransformationReplaceIdWithSynonym::IsApplicable( + spvtools::opt::IRContext* context, + const spvtools::fuzz::FactManager& fact_manager) const { + auto id_of_interest = message_.id_use_descriptor().id_of_interest(); + + // Does the fact manager know about the synonym? + if (fact_manager.GetIdsForWhichSynonymsAreKnown().count(id_of_interest) == + 0) { + return false; + } + + auto available_synonyms = fact_manager.GetSynonymsForId(id_of_interest); + if (std::find_if(available_synonyms.begin(), available_synonyms.end(), + [this](protobufs::DataDescriptor dd) -> bool { + return DataDescriptorEquals()(&dd, + &message_.data_descriptor()); + }) == available_synonyms.end()) { + return false; + } + + auto use_instruction = + transformation::FindInstruction(message_.id_use_descriptor(), context); + if (!use_instruction) { + return false; + } + + if (!ReplacingUseWithSynonymIsOk( + context, use_instruction, + message_.id_use_descriptor().in_operand_index(), + message_.data_descriptor())) { + return false; + } + + assert(message_.fresh_id_for_temporary() == 0); + assert(message_.data_descriptor().index().empty()); + + return true; +} + +void TransformationReplaceIdWithSynonym::Apply( + spvtools::opt::IRContext* context, + spvtools::fuzz::FactManager* /*unused*/) const { + assert(message_.data_descriptor().index().empty()); + auto instruction_to_change = + transformation::FindInstruction(message_.id_use_descriptor(), context); + instruction_to_change->SetInOperand( + message_.id_use_descriptor().in_operand_index(), + {message_.data_descriptor().object()}); + context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); +} + +protobufs::Transformation TransformationReplaceIdWithSynonym::ToMessage() + const { + protobufs::Transformation result; + *result.mutable_replace_id_with_synonym() = message_; + return result; +} + +bool TransformationReplaceIdWithSynonym::ReplacingUseWithSynonymIsOk( + opt::IRContext* context, opt::Instruction* use_instruction, + uint32_t use_in_operand_index, const protobufs::DataDescriptor& synonym) { + auto defining_instruction = + context->get_def_use_mgr()->GetDef(synonym.object()); + + if (use_instruction == defining_instruction) { + // If we have an instruction: + // %a = OpCopyObject %t %b + // then we know %a and %b are synonymous, but we do *not* want to turn + // this into: + // %a = OpCopyObject %t %a + // We require this special case because an instruction dominates itself. + return false; + } + + if (use_instruction->opcode() == SpvOpAccessChain && + use_in_operand_index > 0) { + // This is an access chain index. If the object being accessed has + // pointer-to-struct type then we cannot replace the use with a synonym, as + // the use needs to be an OpConstant. + auto object_being_accessed = context->get_def_use_mgr()->GetDef( + use_instruction->GetSingleWordInOperand(0)); + auto pointer_type = + context->get_type_mgr()->GetType(object_being_accessed->type_id()); + assert(pointer_type->AsPointer()); + if (pointer_type->AsPointer()->pointee_type()->AsStruct()) { + return false; + } + } + + // We now need to check that replacing the use with the synonym will respect + // dominance rules - i.e. the synonym needs to dominate the use. + auto dominator_analysis = context->GetDominatorAnalysis( + context->get_instr_block(use_instruction)->GetParent()); + if (use_instruction->opcode() == SpvOpPhi) { + // In the case where the use is an operand to OpPhi, it is actually the + // *parent* block associated with the operand that must be dominated by the + // synonym. + auto parent_block = + use_instruction->GetSingleWordInOperand(use_in_operand_index + 1); + if (!dominator_analysis->Dominates( + context->get_instr_block(defining_instruction)->id(), + parent_block)) { + return false; + } + } else if (!dominator_analysis->Dominates(defining_instruction, + use_instruction)) { + return false; + } + return true; +} + +} // namespace fuzz +} // namespace spvtools diff --git a/3rdparty/spirv-tools/source/fuzz/transformation_replace_id_with_synonym.h b/3rdparty/spirv-tools/source/fuzz/transformation_replace_id_with_synonym.h new file mode 100644 index 000000000..d0f233e3a --- /dev/null +++ b/3rdparty/spirv-tools/source/fuzz/transformation_replace_id_with_synonym.h @@ -0,0 +1,72 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_FUZZ_TRANSFORMATION_REPLACE_ID_WITH_SYNONYM_H_ +#define SOURCE_FUZZ_TRANSFORMATION_REPLACE_ID_WITH_SYNONYM_H_ + +#include "source/fuzz/fact_manager.h" +#include "source/fuzz/protobufs/spirvfuzz_protobufs.h" +#include "source/fuzz/transformation.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace fuzz { + +class TransformationReplaceIdWithSynonym : public Transformation { + public: + explicit TransformationReplaceIdWithSynonym( + const protobufs::TransformationReplaceIdWithSynonym& message); + + TransformationReplaceIdWithSynonym( + protobufs::IdUseDescriptor id_use_descriptor, + protobufs::DataDescriptor data_descriptor, + uint32_t fresh_id_for_temporary); + + // - The fact manager must know that the id identified by + // |message_.id_use_descriptor| is synonomous with + // |message_.data_descriptor|. + // - Replacing the id in |message_.id_use_descriptor| by the synonym in + // |message_.data_descriptor| must respect SPIR-V's rules about uses being + // dominated by their definitions. + // - The id must not be an index into an access chain whose base object has + // struct type, as such indices must be constants. + // - |fresh_id_for_temporary| must be 0. + // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2855): the + // motivation for the temporary is to support the case where an id is + // synonymous with an element of a composite. Until support for that is + // implemented, 0 records that no temporary is needed. + bool IsApplicable(opt::IRContext* context, + const FactManager& fact_manager) const override; + + // Replaces the use identified by |message_.id_use_descriptor| with the + // synonymous id identified by |message_.data_descriptor|. + // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2855): in due + // course it will also be necessary to add an additional instruction to pull + // the synonym out of a composite. + void Apply(opt::IRContext* context, FactManager* fact_manager) const override; + + protobufs::Transformation ToMessage() const override; + + static bool ReplacingUseWithSynonymIsOk( + opt::IRContext* context, opt::Instruction* use_instruction, + uint32_t use_in_operand_index, const protobufs::DataDescriptor& synonym); + + private: + protobufs::TransformationReplaceIdWithSynonym message_; +}; + +} // namespace fuzz +} // namespace spvtools + +#endif // SOURCE_FUZZ_TRANSFORMATION_REPLACE_ID_WITH_SYNONYM_H_ diff --git a/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp b/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp index 00757e351..b3b90da53 100644 --- a/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp +++ b/3rdparty/spirv-tools/source/opt/copy_prop_arrays.cpp @@ -306,8 +306,7 @@ CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct( analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); const analysis::Constant* last_access = const_mgr->FindDeclaredConstant(memory_object->AccessChain().back()); - if (!last_access || - (!last_access->AsIntConstant() && !last_access->AsNullConstant())) { + if (!last_access || !last_access->type()->AsInteger()) { return nullptr; } @@ -340,7 +339,7 @@ CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct( last_access = const_mgr->FindDeclaredConstant(member_object->AccessChain().back()); - if (!last_access || !last_access->AsIntConstant()) { + if (!last_access || !last_access->type()->AsInteger()) { return nullptr; } @@ -368,8 +367,7 @@ CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { } else if (const analysis::Array* array_type = result_type->AsArray()) { const analysis::Constant* length_const = const_mgr->FindDeclaredConstant(array_type->LengthId()); - assert(length_const->AsIntConstant()); - number_of_elements = length_const->AsIntConstant()->GetU32(); + number_of_elements = length_const->GetU32(); } else if (const analysis::Vector* vector_type = result_type->AsVector()) { number_of_elements = vector_type->element_count(); } else if (const analysis::Matrix* matrix_type = result_type->AsMatrix()) { @@ -401,7 +399,7 @@ CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { const analysis::Constant* last_access = const_mgr->FindDeclaredConstant(memory_object->AccessChain().back()); - if (!last_access || !last_access->AsIntConstant()) { + if (!last_access || !last_access->type()->AsInteger()) { return nullptr; } @@ -449,7 +447,7 @@ CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { const analysis::Constant* current_last_access = const_mgr->FindDeclaredConstant( current_memory_object->AccessChain().back()); - if (!current_last_access || !current_last_access->AsIntConstant()) { + if (!current_last_access || !current_last_access->type()->AsInteger()) { return nullptr; } @@ -513,7 +511,7 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, const analysis::Constant* index_const = const_mgr->FindDeclaredConstant(use->GetSingleWordInOperand(i)); if (index_const) { - access_chain.push_back(index_const->AsIntConstant()->GetU32()); + access_chain.push_back(index_const->GetU32()); } else { // Variable index means the type is a type where every element // is the same type. Use element 0 to get the type. @@ -613,7 +611,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, const analysis::Constant* index_const = const_mgr->FindDeclaredConstant(use->GetSingleWordInOperand(i)); if (index_const) { - access_chain.push_back(index_const->AsIntConstant()->GetU32()); + access_chain.push_back(index_const->GetU32()); } else { // Variable index means the type is an type where every element // is the same type. Use element 0 to get the type. @@ -749,8 +747,8 @@ uint32_t CopyPropagateArrays::MemoryObject::GetNumberOfMembers() { const analysis::Constant* length_const = context->get_constant_mgr()->FindDeclaredConstant( array_type->LengthId()); - assert(length_const->AsIntConstant()); - return length_const->AsIntConstant()->GetU32(); + assert(length_const->type()->AsInteger()); + return length_const->GetU32(); } else if (const analysis::Vector* vector_type = type->AsVector()) { return vector_type->element_count(); } else if (const analysis::Matrix* matrix_type = type->AsMatrix()) { @@ -776,8 +774,7 @@ std::vector CopyPropagateArrays::MemoryObject::GetAccessIds() const { if (!element_index_const) { access_indices.push_back(0); } else { - assert(element_index_const->AsIntConstant()); - access_indices.push_back(element_index_const->AsIntConstant()->GetU32()); + access_indices.push_back(element_index_const->GetU32()); } } return access_indices; diff --git a/3rdparty/spirv-tools/source/opt/function.cpp b/3rdparty/spirv-tools/source/opt/function.cpp index 252005252..efda68b78 100644 --- a/3rdparty/spirv-tools/source/opt/function.cpp +++ b/3rdparty/spirv-tools/source/opt/function.cpp @@ -13,13 +13,14 @@ // limitations under the License. #include "source/opt/function.h" -#include "function.h" -#include "ir_context.h" -#include #include #include +#include "function.h" +#include "ir_context.h" +#include "source/util/bit_vector.h" + namespace spvtools { namespace opt { diff --git a/3rdparty/spirv-tools/source/opt/ir_builder.h b/3rdparty/spirv-tools/source/opt/ir_builder.h index 6720e8926..b0c1d2ec9 100644 --- a/3rdparty/spirv-tools/source/opt/ir_builder.h +++ b/3rdparty/spirv-tools/source/opt/ir_builder.h @@ -59,27 +59,43 @@ class InstructionBuilder { preserved_analyses) {} Instruction* AddNullaryOp(uint32_t type_id, SpvOp opcode) { - // TODO(1841): Handle id overflow. - std::unique_ptr newUnOp(new Instruction( - GetContext(), opcode, type_id, - opcode == SpvOpReturn ? 0 : GetContext()->TakeNextId(), {})); - return AddInstruction(std::move(newUnOp)); + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } + std::unique_ptr new_inst( + new Instruction(GetContext(), opcode, type_id, result_id, {})); + return AddInstruction(std::move(new_inst)); } Instruction* AddUnaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1) { - // TODO(1841): Handle id overflow. + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } std::unique_ptr newUnOp(new Instruction( - GetContext(), opcode, type_id, GetContext()->TakeNextId(), + GetContext(), opcode, type_id, result_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}})); return AddInstruction(std::move(newUnOp)); } Instruction* AddBinaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, uint32_t operand2) { - // TODO(1841): Handle id overflow. + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } std::unique_ptr newBinOp(new Instruction( - GetContext(), opcode, type_id, - opcode == SpvOpStore ? 0 : GetContext()->TakeNextId(), + GetContext(), opcode, type_id, opcode == SpvOpStore ? 0 : result_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}})); return AddInstruction(std::move(newBinOp)); @@ -87,9 +103,15 @@ class InstructionBuilder { Instruction* AddTernaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, uint32_t operand2, uint32_t operand3) { - // TODO(1841): Handle id overflow. + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } std::unique_ptr newTernOp(new Instruction( - GetContext(), opcode, type_id, GetContext()->TakeNextId(), + GetContext(), opcode, type_id, result_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand3}}})); @@ -99,9 +121,15 @@ class InstructionBuilder { Instruction* AddQuadOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, uint32_t operand2, uint32_t operand3, uint32_t operand4) { - // TODO(1841): Handle id overflow. + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } std::unique_ptr newQuadOp(new Instruction( - GetContext(), opcode, type_id, GetContext()->TakeNextId(), + GetContext(), opcode, type_id, result_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand3}}, @@ -111,9 +139,15 @@ class InstructionBuilder { Instruction* AddIdLiteralOp(uint32_t type_id, SpvOp opcode, uint32_t id, uint32_t uliteral) { - // TODO(1841): Handle id overflow. + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } std::unique_ptr newBinOp(new Instruction( - GetContext(), opcode, type_id, GetContext()->TakeNextId(), + GetContext(), opcode, type_id, result_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {uliteral}}})); return AddInstruction(std::move(newBinOp)); diff --git a/3rdparty/spirv-tools/source/opt/optimizer.cpp b/3rdparty/spirv-tools/source/opt/optimizer.cpp index 1ad88c0e1..1e7df9917 100644 --- a/3rdparty/spirv-tools/source/opt/optimizer.cpp +++ b/3rdparty/spirv-tools/source/opt/optimizer.cpp @@ -21,12 +21,12 @@ #include #include -#include #include "source/opt/build_module.h" #include "source/opt/graphics_robust_access_pass.h" #include "source/opt/log.h" #include "source/opt/pass_manager.h" #include "source/opt/passes.h" +#include "source/spirv_optimizer_options.h" #include "source/util/make_unique.h" #include "source/util/string_utils.h" diff --git a/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp b/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp index eb63bd7c3..fb32178e8 100644 --- a/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp +++ b/3rdparty/spirv-tools/source/opt/wrap_opkill.cpp @@ -59,7 +59,14 @@ bool WrapOpKill::ReplaceWithFunctionCall(Instruction* inst) { if (ir_builder.AddFunctionCall(GetVoidTypeId(), func_id, {}) == nullptr) { return false; } - ir_builder.AddUnreachable(); + + uint32_t return_type_id = GetOwningFunctionsReturnType(inst); + if (return_type_id != GetVoidTypeId()) { + Instruction* undef = ir_builder.AddNullaryOp(return_type_id, SpvOpUndef); + ir_builder.AddUnaryOp(0, SpvOpReturnValue, undef->result_id()); + } else { + ir_builder.AddNullaryOp(0, SpvOpReturn); + } context()->KillInst(inst); return true; } @@ -147,5 +154,15 @@ uint32_t WrapOpKill::GetOpKillFuncId() { return opkill_function_->result_id(); } +uint32_t WrapOpKill::GetOwningFunctionsReturnType(Instruction* inst) { + BasicBlock* bb = context()->get_instr_block(inst); + if (bb == nullptr) { + return 0; + } + + Function* func = bb->GetParent(); + return func->type_id(); +} + } // namespace opt } // namespace spvtools diff --git a/3rdparty/spirv-tools/source/opt/wrap_opkill.h b/3rdparty/spirv-tools/source/opt/wrap_opkill.h index 8b0328132..87a5d692c 100644 --- a/3rdparty/spirv-tools/source/opt/wrap_opkill.h +++ b/3rdparty/spirv-tools/source/opt/wrap_opkill.h @@ -56,6 +56,10 @@ class WrapOpKill : public Pass { // function could not be generated. uint32_t GetOpKillFuncId(); + // Returns the id of the return type for the function that contains |inst|. + // Returns 0 if |inst| is not in a function. + uint32_t GetOwningFunctionsReturnType(Instruction* inst); + // The id of the void type. If its value is 0, then the void type has not // been found or created yet. uint32_t void_type_id_; diff --git a/3rdparty/spirv-tools/source/spirv_fuzzer_options.cpp b/3rdparty/spirv-tools/source/spirv_fuzzer_options.cpp index 9a2cb9fda..ab8903e1e 100644 --- a/3rdparty/spirv-tools/source/spirv_fuzzer_options.cpp +++ b/3rdparty/spirv-tools/source/spirv_fuzzer_options.cpp @@ -22,6 +22,7 @@ const uint32_t kDefaultStepLimit = 250; spv_fuzzer_options_t::spv_fuzzer_options_t() : has_random_seed(false), random_seed(0), + replay_validation_enabled(false), shrinker_step_limit(kDefaultStepLimit) {} SPIRV_TOOLS_EXPORT spv_fuzzer_options spvFuzzerOptionsCreate() { @@ -32,6 +33,11 @@ SPIRV_TOOLS_EXPORT void spvFuzzerOptionsDestroy(spv_fuzzer_options options) { delete options; } +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableReplayValidation( + spv_fuzzer_options options) { + options->replay_validation_enabled = true; +} + SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetRandomSeed( spv_fuzzer_options options, uint32_t seed) { options->has_random_seed = true; diff --git a/3rdparty/spirv-tools/source/spirv_fuzzer_options.h b/3rdparty/spirv-tools/source/spirv_fuzzer_options.h index 3b8e15ca1..7bb16c738 100644 --- a/3rdparty/spirv-tools/source/spirv_fuzzer_options.h +++ b/3rdparty/spirv-tools/source/spirv_fuzzer_options.h @@ -29,6 +29,9 @@ struct spv_fuzzer_options_t { bool has_random_seed; uint32_t random_seed; + // See spvFuzzerOptionsEnableReplayValidation. + bool replay_validation_enabled; + // See spvFuzzerOptionsSetShrinkerStepLimit. uint32_t shrinker_step_limit; }; diff --git a/3rdparty/spirv-tools/source/val/validate.cpp b/3rdparty/spirv-tools/source/val/validate.cpp index 6f1a26c6e..e4123a4fb 100644 --- a/3rdparty/spirv-tools/source/val/validate.cpp +++ b/3rdparty/spirv-tools/source/val/validate.cpp @@ -272,6 +272,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( return error; } + std::vector visited_entry_points; for (auto& instruction : vstate->ordered_instructions()) { { // In order to do this work outside of Process Instruction we need to be @@ -293,6 +294,24 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( vstate->RegisterEntryPoint(entry_point, execution_model, std::move(desc)); + + if (visited_entry_points.size() > 0) { + for (const Instruction* check_inst : visited_entry_points) { + const auto check_execution_model = + check_inst->GetOperandAs(0); + const char* check_str = reinterpret_cast( + check_inst->words().data() + inst->operand(2).offset); + const std::string check_name(check_str); + + if (desc.name == check_name && + execution_model == check_execution_model) { + return vstate->diag(SPV_ERROR_INVALID_DATA, inst) + << "2 Entry points cannot share the same name and " + "ExecutionMode."; + } + } + } + visited_entry_points.push_back(inst); } if (inst->opcode() == SpvOpFunctionCall) { if (!vstate->in_function_body()) { diff --git a/3rdparty/spirv-tools/source/val/validate.h b/3rdparty/spirv-tools/source/val/validate.h index b6c4072ee..da3d0b831 100644 --- a/3rdparty/spirv-tools/source/val/validate.h +++ b/3rdparty/spirv-tools/source/val/validate.h @@ -208,7 +208,7 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst); spv_result_t ValidateExecutionLimitations(ValidationState_t& _, const Instruction* inst); -/// Validates restricted uses of 8- and 16-bit types. +/// Validates restricted uses of 8- and 16-bit types. /// /// Validates shaders that uses 8- or 16-bit storage capabilities, but not full /// capabilities only have appropriate uses of those types. diff --git a/3rdparty/spirv-tools/source/val/validate_conversion.cpp b/3rdparty/spirv-tools/source/val/validate_conversion.cpp index f7eb88110..0060d0b7b 100644 --- a/3rdparty/spirv-tools/source/val/validate_conversion.cpp +++ b/3rdparty/spirv-tools/source/val/validate_conversion.cpp @@ -18,6 +18,7 @@ #include "source/diagnostic.h" #include "source/opcode.h" +#include "source/spirv_constant.h" #include "source/val/instruction.h" #include "source/val/validation_state.h" @@ -467,15 +468,40 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected input to be a pointer or int or float vector " << "or scalar: " << spvOpcodeString(opcode); - if (result_is_pointer && !input_is_pointer && !input_is_int_scalar) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected input to be a pointer or int scalar if Result Type " - << "is pointer: " << spvOpcodeString(opcode); + if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 5) || + _.HasExtension(kSPV_KHR_physical_storage_buffer)) { + const bool result_is_int_vector = _.IsIntVectorType(result_type); + const bool result_has_int32 = + _.ContainsSizedIntOrFloatType(result_type, SpvOpTypeInt, 32); + const bool input_is_int_vector = _.IsIntVectorType(input_type); + const bool input_has_int32 = + _.ContainsSizedIntOrFloatType(input_type, SpvOpTypeInt, 32); + if (result_is_pointer && !input_is_pointer && !input_is_int_scalar && + !(input_is_int_vector && input_has_int32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer, int scalar or 32-bit int " + "vector if Result Type is pointer: " + << spvOpcodeString(opcode); - if (input_is_pointer && !result_is_pointer && !result_is_int_scalar) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Pointer can only be converted to another pointer or int " - << "scalar: " << spvOpcodeString(opcode); + if (input_is_pointer && !result_is_pointer && !result_is_int_scalar && + !(result_is_int_vector && result_has_int32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Pointer can only be converted to another pointer, int " + "scalar or 32-bit int vector: " + << spvOpcodeString(opcode); + } else { + if (result_is_pointer && !input_is_pointer && !input_is_int_scalar) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer or int scalar if Result " + "Type is pointer: " + << spvOpcodeString(opcode); + + if (input_is_pointer && !result_is_pointer && !result_is_int_scalar) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Pointer can only be converted to another pointer or int " + "scalar: " + << spvOpcodeString(opcode); + } if (!result_is_pointer && !input_is_pointer) { const uint32_t result_size = diff --git a/3rdparty/spirv-tools/source/val/validate_decorations.cpp b/3rdparty/spirv-tools/source/val/validate_decorations.cpp index 33239614a..0a6da465b 100644 --- a/3rdparty/spirv-tools/source/val/validate_decorations.cpp +++ b/3rdparty/spirv-tools/source/val/validate_decorations.cpp @@ -942,6 +942,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { id = id_inst->GetOperandAs(1u); id_inst = vstate.FindDef(id); } + // Struct requirement is checked on variables so just move on here. if (SpvOpTypeStruct != id_inst->opcode()) continue; MemberConstraints constraints; ComputeMemberConstraintsForStruct(&constraints, id, LayoutConstraints(), @@ -952,15 +953,18 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { : (push_constant ? "PushConstant" : "StorageBuffer"); if (spvIsVulkanEnv(vstate.context()->target_env)) { - if (storage_buffer && - hasDecoration(id, SpvDecorationBufferBlock, vstate)) { + const bool block = hasDecoration(id, SpvDecorationBlock, vstate); + const bool buffer_block = + hasDecoration(id, SpvDecorationBufferBlock, vstate); + if (storage_buffer && buffer_block) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << "Storage buffer id '" << var_id << " In Vulkan, BufferBlock is disallowed on variables in " "the StorageBuffer storage class"; } - // Vulkan 14.5.1: Check Block decoration for PushConstant variables. - if (push_constant && !hasDecoration(id, SpvDecorationBlock, vstate)) { + // Vulkan 14.5.1/2: Check Block decoration for PushConstant, Uniform + // and StorageBuffer variables. Uniform can also use BufferBlock. + if (push_constant && !block) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) << "PushConstant id '" << id << "' is missing Block decoration.\n" @@ -968,6 +972,22 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { << "Such variables must be identified with a Block " "decoration"; } + if (storage_buffer && !block) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "StorageBuffer id '" << id + << "' is missing Block decoration.\n" + << "From Vulkan spec, section 14.5.2:\n" + << "Such variables must be identified with a Block " + "decoration"; + } + if (uniform && !block && !buffer_block) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "Uniform id '" << id + << "' is missing Block or BufferBlock decoration.\n" + << "From Vulkan spec, section 14.5.2:\n" + << "Such variables must be identified with a Block or " + "BufferBlock decoration"; + } // Vulkan 14.5.2: Check DescriptorSet and Binding decoration for // Uniform and StorageBuffer variables. if (uniform || storage_buffer) { diff --git a/3rdparty/spirv-tools/source/val/validate_memory.cpp b/3rdparty/spirv-tools/source/val/validate_memory.cpp index f31c5a022..8e220971c 100644 --- a/3rdparty/spirv-tools/source/val/validate_memory.cpp +++ b/3rdparty/spirv-tools/source/val/validate_memory.cpp @@ -536,6 +536,19 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { << "this type"; } } + + if (storage_class == SpvStorageClassStorageBuffer) { + if (!IsAllowedTypeOrArrayOfSame(_, pointee, {SpvOpTypeStruct})) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "StorageBuffer OpVariable '" << _.getIdName(inst->id()) + << "' has illegal type.\n" + << "From Vulkan spec, section 14.5.2:\n" + << "Variables identified with the StorageBuffer storage class " + "are used to access transparent buffer backed resources. " + "Such variables must be typed as OpTypeStruct, or an array " + "of this type"; + } + } } // WebGPU & Vulkan Appendix A: Check that if contains initializer, then diff --git a/3rdparty/spirv-tools/source/val/validate_type.cpp b/3rdparty/spirv-tools/source/val/validate_type.cpp index 7129888a8..afc065676 100644 --- a/3rdparty/spirv-tools/source/val/validate_type.cpp +++ b/3rdparty/spirv-tools/source/val/validate_type.cpp @@ -191,7 +191,6 @@ spv_result_t ValidateTypeRuntimeArray(ValidationState_t& _, } bool ContainsOpaqueType(ValidationState_t& _, const Instruction* str) { -return false; const size_t elem_type_index = 1; uint32_t elem_type_id; Instruction* elem_type; diff --git a/3rdparty/spirv-tools/test/fuzz/CMakeLists.txt b/3rdparty/spirv-tools/test/fuzz/CMakeLists.txt index 6a101ddcd..1d9a8fd6b 100644 --- a/3rdparty/spirv-tools/test/fuzz/CMakeLists.txt +++ b/3rdparty/spirv-tools/test/fuzz/CMakeLists.txt @@ -17,8 +17,6 @@ if (${SPIRV_BUILD_FUZZER}) set(SOURCES fuzz_test_util.h - fuzzer_replayer_test.cpp - fuzzer_shrinker_test.cpp fact_manager_test.cpp fuzz_test_util.cpp fuzzer_pass_add_useful_constructs_test.cpp @@ -34,9 +32,21 @@ if (${SPIRV_BUILD_FUZZER}) transformation_move_block_down_test.cpp transformation_replace_boolean_constant_with_constant_binary_test.cpp transformation_replace_constant_with_uniform_test.cpp + transformation_replace_id_with_synonym_test.cpp transformation_split_block_test.cpp uniform_buffer_element_descriptor_test.cpp) + if (${SPIRV_ENABLE_LONG_FUZZER_TESTS}) + # These are long-running tests that depend on random seeds. We do not want + # to run them during regular whole-project CI because they may reveal + # spirv-fuzz bugs in changes that are totally unrelated to spirv-fuzz, + # which would be counfounding. Instead, they should be run regularly but + # separately. + set(SOURCES ${SOURCES} + fuzzer_replayer_test.cpp + fuzzer_shrinker_test.cpp) + endif() + add_spvtools_unittest(TARGET fuzz SRCS ${SOURCES} LIBS SPIRV-Tools-fuzz diff --git a/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.cpp b/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.cpp index e2b951899..bc6d4ee6e 100644 --- a/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.cpp +++ b/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.cpp @@ -16,6 +16,8 @@ #include +#include "tools/io.h" + namespace spvtools { namespace fuzz { @@ -89,5 +91,19 @@ std::string ToString(spv_target_env env, const std::vector& binary) { return result; } +void DumpShader(opt::IRContext* context, const char* filename) { + std::vector binary; + context->module()->ToBinary(&binary, false); + DumpShader(binary, filename); +} + +void DumpShader(const std::vector& binary, const char* filename) { + auto write_file_succeeded = + WriteFile(filename, "wb", &binary[0], binary.size()); + if (!write_file_succeeded) { + std::cerr << "Failed to dump shader" << std::endl; + } +} + } // namespace fuzz } // namespace spvtools diff --git a/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.h b/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.h index 88a0b205b..93f37e567 100644 --- a/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.h +++ b/3rdparty/spirv-tools/test/fuzz/fuzz_test_util.h @@ -93,6 +93,13 @@ const spvtools::MessageConsumer kConsoleMessageConsumer = } }; +// Dumps the SPIRV-V module in |context| to file |filename|. Useful for +// interactive debugging. +void DumpShader(opt::IRContext* context, const char* filename); + +// Dumps |binary| to file |filename|. Useful for interactive debugging. +void DumpShader(const std::vector& binary, const char* filename); + } // namespace fuzz } // namespace spvtools diff --git a/3rdparty/spirv-tools/test/fuzz/fuzzer_replayer_test.cpp b/3rdparty/spirv-tools/test/fuzz/fuzzer_replayer_test.cpp index 550c4fc8d..3c3660286 100644 --- a/3rdparty/spirv-tools/test/fuzz/fuzzer_replayer_test.cpp +++ b/3rdparty/spirv-tools/test/fuzz/fuzzer_replayer_test.cpp @@ -54,7 +54,7 @@ void RunFuzzerAndReplayer(const std::string& shader, std::vector replayer_binary_out; protobufs::TransformationSequence replayer_transformation_sequence_out; - Replayer replayer(env); + Replayer replayer(env, true); replayer.SetMessageConsumer(kSilentConsumer); auto replayer_result_status = replayer.Run( binary_in, initial_facts, fuzzer_transformation_sequence_out, diff --git a/3rdparty/spirv-tools/test/fuzz/fuzzer_shrinker_test.cpp b/3rdparty/spirv-tools/test/fuzz/fuzzer_shrinker_test.cpp index 85f41bc0a..933038dc6 100644 --- a/3rdparty/spirv-tools/test/fuzz/fuzzer_shrinker_test.cpp +++ b/3rdparty/spirv-tools/test/fuzz/fuzzer_shrinker_test.cpp @@ -125,7 +125,7 @@ void RunAndCheckShrinker( const std::vector& expected_binary_out, uint32_t expected_transformations_out_size, uint32_t step_limit) { // Run the shrinker. - Shrinker shrinker(target_env, step_limit); + Shrinker shrinker(target_env, step_limit, true); shrinker.SetMessageConsumer(kSilentConsumer); std::vector binary_out; @@ -158,6 +158,7 @@ void RunFuzzerAndShrinker(const std::string& shader, std::vector binary_in; SpirvTools t(env); + t.SetMessageConsumer(kConsoleMessageConsumer); ASSERT_TRUE(t.Assemble(shader, &binary_in, kFuzzAssembleOption)); ASSERT_TRUE(t.Validate(binary_in)); diff --git a/3rdparty/spirv-tools/test/fuzz/transformation_add_dead_continue_test.cpp b/3rdparty/spirv-tools/test/fuzz/transformation_add_dead_continue_test.cpp index e28af1dce..9f22679a6 100644 --- a/3rdparty/spirv-tools/test/fuzz/transformation_add_dead_continue_test.cpp +++ b/3rdparty/spirv-tools/test/fuzz/transformation_add_dead_continue_test.cpp @@ -1249,6 +1249,145 @@ TEST(TransformationAddDeadContinueTest, RespectDominanceRules3) { ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); } +TEST(TransformationAddDeadContinueTest, Miscellaneous1) { + // A miscellaneous test that exposed a bug in spirv-fuzz. + + std::string shader = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" %586 %623 + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpMemberDecorate %34 0 Offset 0 + OpDecorate %34 Block + OpDecorate %36 DescriptorSet 0 + OpDecorate %36 Binding 0 + OpDecorate %586 BuiltIn FragCoord + OpMemberDecorate %591 0 Offset 0 + OpDecorate %591 Block + OpDecorate %593 DescriptorSet 0 + OpDecorate %593 Binding 1 + OpDecorate %623 Location 0 + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeInt 32 1 + %7 = OpTypePointer Function %6 + %9 = OpConstant %6 0 + %16 = OpConstant %6 2 + %17 = OpTypeBool + %27 = OpTypeFloat 32 + %28 = OpTypeVector %27 2 + %29 = OpTypeMatrix %28 2 + %30 = OpTypePointer Private %29 + %31 = OpVariable %30 Private + %34 = OpTypeStruct %27 + %35 = OpTypePointer Uniform %34 + %36 = OpVariable %35 Uniform + %37 = OpTypePointer Uniform %27 + %40 = OpTypePointer Private %27 + %43 = OpConstant %6 1 + %62 = OpConstant %6 3 + %64 = OpTypeVector %27 3 + %65 = OpTypeMatrix %64 2 + %66 = OpTypePointer Private %65 + %67 = OpVariable %66 Private + %92 = OpConstant %6 4 + %94 = OpTypeVector %27 4 + %95 = OpTypeMatrix %94 2 + %96 = OpTypePointer Private %95 + %97 = OpVariable %96 Private + %123 = OpTypeMatrix %28 3 + %124 = OpTypePointer Private %123 + %125 = OpVariable %124 Private + %151 = OpTypeMatrix %64 3 + %152 = OpTypePointer Private %151 + %153 = OpVariable %152 Private + %179 = OpTypeMatrix %94 3 + %180 = OpTypePointer Private %179 + %181 = OpVariable %180 Private + %207 = OpTypeMatrix %28 4 + %208 = OpTypePointer Private %207 + %209 = OpVariable %208 Private + %235 = OpTypeMatrix %64 4 + %236 = OpTypePointer Private %235 + %237 = OpVariable %236 Private + %263 = OpTypeMatrix %94 4 + %264 = OpTypePointer Private %263 + %265 = OpVariable %264 Private + %275 = OpTypeInt 32 0 + %276 = OpConstant %275 9 + %277 = OpTypeArray %27 %276 + %278 = OpTypePointer Function %277 + %280 = OpConstant %27 0 + %281 = OpTypePointer Function %27 + %311 = OpConstant %27 16 + %448 = OpConstant %6 5 + %482 = OpConstant %6 6 + %516 = OpConstant %6 7 + %550 = OpConstant %6 8 + %585 = OpTypePointer Input %94 + %586 = OpVariable %585 Input + %587 = OpConstant %275 0 + %588 = OpTypePointer Input %27 + %591 = OpTypeStruct %28 + %592 = OpTypePointer Uniform %591 + %593 = OpVariable %592 Uniform + %596 = OpConstant %27 3 + %601 = OpConstant %275 1 + %617 = OpConstant %6 9 + %622 = OpTypePointer Output %94 + %623 = OpVariable %622 Output + %628 = OpConstant %27 1 + %634 = OpConstantComposite %94 %280 %280 %280 %628 + %635 = OpUndef %6 + %636 = OpUndef %17 + %637 = OpUndef %27 + %638 = OpUndef %64 + %639 = OpUndef %94 + %640 = OpConstantTrue %17 + %736 = OpConstantFalse %17 + %642 = OpVariable %37 Uniform + %643 = OpVariable %40 Private + %4 = OpFunction %2 None %3 + %5 = OpLabel + OpBranch %164 + %164 = OpLabel + OpLoopMerge %166 %167 None + OpBranch %165 + %165 = OpLabel + OpBranch %172 + %172 = OpLabel + OpSelectionMerge %174 None + OpBranchConditional %640 %174 %174 + %174 = OpLabel + %785 = OpCopyObject %6 %43 + OpBranch %167 + %167 = OpLabel + %190 = OpIAdd %6 %9 %785 + OpBranchConditional %640 %164 %166 + %166 = OpLabel + OpBranch %196 + %196 = OpLabel + OpBranch %194 + %194 = OpLabel + OpReturn + OpFunctionEnd + )"; + + const auto env = SPV_ENV_UNIVERSAL_1_3; + const auto consumer = nullptr; + const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); + ASSERT_TRUE(IsValid(env, context.get())); + + FactManager fact_manager; + + // This transformation would shortcut the part of the loop body that defines + // an id used in the continue target. + auto bad_transformation = TransformationAddDeadContinue(165, false, {}); + ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager)); +} + } // namespace } // namespace fuzz } // namespace spvtools diff --git a/3rdparty/spirv-tools/test/fuzz/transformation_replace_id_with_synonym_test.cpp b/3rdparty/spirv-tools/test/fuzz/transformation_replace_id_with_synonym_test.cpp new file mode 100644 index 000000000..d3a23449e --- /dev/null +++ b/3rdparty/spirv-tools/test/fuzz/transformation_replace_id_with_synonym_test.cpp @@ -0,0 +1,569 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/fuzz/transformation_replace_id_with_synonym.h" +#include "source/fuzz/data_descriptor.h" +#include "source/fuzz/id_use_descriptor.h" +#include "test/fuzz/fuzz_test_util.h" + +namespace spvtools { +namespace fuzz { +namespace { + +// The following shader was obtained from this GLSL, which was then optimized +// with spirv-opt -O and manually edited to include some uses of OpCopyObject +// (to introduce id synonyms). +// +// #version 310 es +// +// precision highp int; +// precision highp float; +// +// layout(set = 0, binding = 0) uniform buf { +// int a; +// int b; +// int c; +// }; +// +// layout(location = 0) out vec4 color; +// +// void main() { +// int x = a; +// float f = 0.0; +// while (x < b) { +// switch(x % 4) { +// case 0: +// color[0] = f; +// break; +// case 1: +// color[1] = f; +// break; +// case 2: +// color[2] = f; +// break; +// case 3: +// color[3] = f; +// break; +// default: +// break; +// } +// if (x > c) { +// x++; +// } else { +// x += 2; +// } +// } +// color[0] += color[1] + float(x); +// } +const std::string kComplexShader = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" %42 + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpName %4 "main" + OpName %9 "buf" + OpMemberName %9 0 "a" + OpMemberName %9 1 "b" + OpMemberName %9 2 "c" + OpName %11 "" + OpName %42 "color" + OpMemberDecorate %9 0 Offset 0 + OpMemberDecorate %9 1 Offset 4 + OpMemberDecorate %9 2 Offset 8 + OpDecorate %9 Block + OpDecorate %11 DescriptorSet 0 + OpDecorate %11 Binding 0 + OpDecorate %42 Location 0 + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeInt 32 1 + %9 = OpTypeStruct %6 %6 %6 + %10 = OpTypePointer Uniform %9 + %11 = OpVariable %10 Uniform + %12 = OpConstant %6 0 + %13 = OpTypePointer Uniform %6 + %16 = OpTypeFloat 32 + %19 = OpConstant %16 0 + %26 = OpConstant %6 1 + %29 = OpTypeBool + %32 = OpConstant %6 4 + %40 = OpTypeVector %16 4 + %41 = OpTypePointer Output %40 + %42 = OpVariable %41 Output + %44 = OpTypeInt 32 0 + %45 = OpConstant %44 0 + %46 = OpTypePointer Output %16 + %50 = OpConstant %44 1 + %54 = OpConstant %44 2 + %58 = OpConstant %44 3 + %64 = OpConstant %6 2 + %4 = OpFunction %2 None %3 + %5 = OpLabel + %209 = OpCopyObject %6 %12 + %14 = OpAccessChain %13 %11 %12 + %15 = OpLoad %6 %14 + %200 = OpCopyObject %6 %15 + OpBranch %20 + %20 = OpLabel + %84 = OpPhi %6 %15 %5 %86 %69 + %27 = OpAccessChain %13 %11 %26 + %28 = OpLoad %6 %27 + %207 = OpCopyObject %6 %84 + %201 = OpCopyObject %6 %15 + %30 = OpSLessThan %29 %84 %28 + OpLoopMerge %22 %69 None + OpBranchConditional %30 %21 %22 + %21 = OpLabel + %33 = OpSMod %6 %84 %32 + %208 = OpCopyObject %6 %33 + OpSelectionMerge %39 None + OpSwitch %33 %38 0 %34 1 %35 2 %36 3 %37 + %38 = OpLabel + %202 = OpCopyObject %6 %15 + OpBranch %39 + %34 = OpLabel + %210 = OpCopyObject %16 %19 + %47 = OpAccessChain %46 %42 %45 + OpStore %47 %19 + OpBranch %39 + %35 = OpLabel + %51 = OpAccessChain %46 %42 %50 + OpStore %51 %19 + OpBranch %39 + %36 = OpLabel + %204 = OpCopyObject %44 %54 + %55 = OpAccessChain %46 %42 %54 + %203 = OpCopyObject %46 %55 + OpStore %55 %19 + OpBranch %39 + %37 = OpLabel + %59 = OpAccessChain %46 %42 %58 + OpStore %59 %19 + OpBranch %39 + %39 = OpLabel + %300 = OpIAdd %6 %15 %15 + %65 = OpAccessChain %13 %11 %64 + %66 = OpLoad %6 %65 + %67 = OpSGreaterThan %29 %84 %66 + OpSelectionMerge %69 None + OpBranchConditional %67 %68 %72 + %68 = OpLabel + %71 = OpIAdd %6 %84 %26 + OpBranch %69 + %72 = OpLabel + %74 = OpIAdd %6 %84 %64 + %205 = OpCopyObject %6 %74 + OpBranch %69 + %69 = OpLabel + %86 = OpPhi %6 %71 %68 %74 %72 + %301 = OpPhi %6 %71 %68 %15 %72 + OpBranch %20 + %22 = OpLabel + %75 = OpAccessChain %46 %42 %50 + %76 = OpLoad %16 %75 + %78 = OpConvertSToF %16 %84 + %80 = OpAccessChain %46 %42 %45 + %206 = OpCopyObject %16 %78 + %81 = OpLoad %16 %80 + %79 = OpFAdd %16 %76 %78 + %82 = OpFAdd %16 %81 %79 + OpStore %80 %82 + OpReturn + OpFunctionEnd +)"; + +protobufs::Fact MakeFact(uint32_t id, uint32_t copy_id) { + protobufs::FactIdSynonym id_synonym_fact; + id_synonym_fact.set_id(id); + id_synonym_fact.mutable_data_descriptor()->set_object(copy_id); + protobufs::Fact result; + *result.mutable_id_synonym_fact() = id_synonym_fact; + return result; +} + +// Equips the fact manager with synonym facts for the above shader. +void SetUpIdSynonyms(FactManager* fact_manager, opt::IRContext* context) { + fact_manager->AddFact(MakeFact(15, 200), context); + fact_manager->AddFact(MakeFact(15, 201), context); + fact_manager->AddFact(MakeFact(15, 202), context); + fact_manager->AddFact(MakeFact(55, 203), context); + fact_manager->AddFact(MakeFact(54, 204), context); + fact_manager->AddFact(MakeFact(74, 205), context); + fact_manager->AddFact(MakeFact(78, 206), context); + fact_manager->AddFact(MakeFact(84, 207), context); + fact_manager->AddFact(MakeFact(33, 208), context); + fact_manager->AddFact(MakeFact(12, 209), context); + fact_manager->AddFact(MakeFact(19, 210), context); +} + +TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { + const auto env = SPV_ENV_UNIVERSAL_1_3; + const auto consumer = nullptr; + const auto context = + BuildModule(env, consumer, kComplexShader, kFuzzAssembleOption); + ASSERT_TRUE(IsValid(env, context.get())); + + FactManager fact_manager; + SetUpIdSynonyms(&fact_manager, context.get()); + + // %202 cannot replace %15 as in-operand 0 of %300, since %202 does not + // dominate %300. + auto synonym_does_not_dominate_use = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(15, SpvOpIAdd, 0, 300, 0), + MakeDataDescriptor(202, {}), 0); + ASSERT_FALSE( + synonym_does_not_dominate_use.IsApplicable(context.get(), fact_manager)); + + // %202 cannot replace %15 as in-operand 2 of %301, since this is the OpPhi's + // incoming value for block %72, and %202 does not dominate %72. + auto synonym_does_not_dominate_use_op_phi = + TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(15, SpvOpPhi, 2, 301, 0), + MakeDataDescriptor(202, {}), 0); + ASSERT_FALSE(synonym_does_not_dominate_use_op_phi.IsApplicable(context.get(), + fact_manager)); + + // %200 is not a synonym for %84 + auto id_in_use_is_not_synonymous = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(84, SpvOpSGreaterThan, 0, 67, 0), + MakeDataDescriptor(200, {}), 0); + ASSERT_FALSE( + id_in_use_is_not_synonymous.IsApplicable(context.get(), fact_manager)); + + // %86 is not a synonym for anything (and in particular not for %74) + auto id_has_no_synonyms = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(86, SpvOpPhi, 2, 84, 0), + MakeDataDescriptor(74, {}), 0); + ASSERT_FALSE(id_has_no_synonyms.IsApplicable(context.get(), fact_manager)); + + // This would lead to %207 = 'OpCopyObject %type %207' if it were allowed + auto synonym_use_is_in_synonym_definition = + TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(84, SpvOpCopyObject, 0, 207, 0), + MakeDataDescriptor(207, {}), 0); + ASSERT_FALSE(synonym_use_is_in_synonym_definition.IsApplicable(context.get(), + fact_manager)); + + // The id use descriptor does not lead to a use (%84 is not used in the + // definition of %207) + auto bad_id_use_descriptor = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(84, SpvOpCopyObject, 0, 200, 0), + MakeDataDescriptor(207, {}), 0); + ASSERT_FALSE(bad_id_use_descriptor.IsApplicable(context.get(), fact_manager)); + + // This replacement would lead to an access chain into a struct using a + // non-constant index. + auto bad_access_chain = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(12, SpvOpAccessChain, 1, 14, 0), + MakeDataDescriptor(209, {}), 0); + ASSERT_FALSE(bad_access_chain.IsApplicable(context.get(), fact_manager)); +} + +TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { + const auto env = SPV_ENV_UNIVERSAL_1_3; + const auto consumer = nullptr; + const auto context = + BuildModule(env, consumer, kComplexShader, kFuzzAssembleOption); + ASSERT_TRUE(IsValid(env, context.get())); + + FactManager fact_manager; + SetUpIdSynonyms(&fact_manager, context.get()); + + auto global_constant_synonym = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(19, SpvOpStore, 1, 47, 0), + MakeDataDescriptor(210, {}), 0); + ASSERT_TRUE( + global_constant_synonym.IsApplicable(context.get(), fact_manager)); + global_constant_synonym.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + auto replace_vector_access_chain_index = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(54, SpvOpAccessChain, 1, 55, 0), + MakeDataDescriptor(204, {}), 0); + ASSERT_TRUE(replace_vector_access_chain_index.IsApplicable(context.get(), + fact_manager)); + replace_vector_access_chain_index.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + // This is an interesting case because it replaces something that is being + // copied with something that is already a synonym. + auto regular_replacement = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(15, SpvOpCopyObject, 0, 202, 0), + MakeDataDescriptor(201, {}), 0); + ASSERT_TRUE(regular_replacement.IsApplicable(context.get(), fact_manager)); + regular_replacement.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + auto regular_replacement2 = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(55, SpvOpStore, 0, 203, 0), + MakeDataDescriptor(203, {}), 0); + ASSERT_TRUE(regular_replacement2.IsApplicable(context.get(), fact_manager)); + regular_replacement2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + auto good_op_phi = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(74, SpvOpPhi, 2, 86, 0), + MakeDataDescriptor(205, {}), 0); + ASSERT_TRUE(good_op_phi.IsApplicable(context.get(), fact_manager)); + good_op_phi.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + const std::string after_transformation = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" %42 + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpName %4 "main" + OpName %9 "buf" + OpMemberName %9 0 "a" + OpMemberName %9 1 "b" + OpMemberName %9 2 "c" + OpName %11 "" + OpName %42 "color" + OpMemberDecorate %9 0 Offset 0 + OpMemberDecorate %9 1 Offset 4 + OpMemberDecorate %9 2 Offset 8 + OpDecorate %9 Block + OpDecorate %11 DescriptorSet 0 + OpDecorate %11 Binding 0 + OpDecorate %42 Location 0 + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeInt 32 1 + %9 = OpTypeStruct %6 %6 %6 + %10 = OpTypePointer Uniform %9 + %11 = OpVariable %10 Uniform + %12 = OpConstant %6 0 + %13 = OpTypePointer Uniform %6 + %16 = OpTypeFloat 32 + %19 = OpConstant %16 0 + %26 = OpConstant %6 1 + %29 = OpTypeBool + %32 = OpConstant %6 4 + %40 = OpTypeVector %16 4 + %41 = OpTypePointer Output %40 + %42 = OpVariable %41 Output + %44 = OpTypeInt 32 0 + %45 = OpConstant %44 0 + %46 = OpTypePointer Output %16 + %50 = OpConstant %44 1 + %54 = OpConstant %44 2 + %58 = OpConstant %44 3 + %64 = OpConstant %6 2 + %4 = OpFunction %2 None %3 + %5 = OpLabel + %209 = OpCopyObject %6 %12 + %14 = OpAccessChain %13 %11 %12 + %15 = OpLoad %6 %14 + %200 = OpCopyObject %6 %15 + OpBranch %20 + %20 = OpLabel + %84 = OpPhi %6 %15 %5 %86 %69 + %27 = OpAccessChain %13 %11 %26 + %28 = OpLoad %6 %27 + %207 = OpCopyObject %6 %84 + %201 = OpCopyObject %6 %15 + %30 = OpSLessThan %29 %84 %28 + OpLoopMerge %22 %69 None + OpBranchConditional %30 %21 %22 + %21 = OpLabel + %33 = OpSMod %6 %84 %32 + %208 = OpCopyObject %6 %33 + OpSelectionMerge %39 None + OpSwitch %33 %38 0 %34 1 %35 2 %36 3 %37 + %38 = OpLabel + %202 = OpCopyObject %6 %201 + OpBranch %39 + %34 = OpLabel + %210 = OpCopyObject %16 %19 + %47 = OpAccessChain %46 %42 %45 + OpStore %47 %210 + OpBranch %39 + %35 = OpLabel + %51 = OpAccessChain %46 %42 %50 + OpStore %51 %19 + OpBranch %39 + %36 = OpLabel + %204 = OpCopyObject %44 %54 + %55 = OpAccessChain %46 %42 %204 + %203 = OpCopyObject %46 %55 + OpStore %203 %19 + OpBranch %39 + %37 = OpLabel + %59 = OpAccessChain %46 %42 %58 + OpStore %59 %19 + OpBranch %39 + %39 = OpLabel + %300 = OpIAdd %6 %15 %15 + %65 = OpAccessChain %13 %11 %64 + %66 = OpLoad %6 %65 + %67 = OpSGreaterThan %29 %84 %66 + OpSelectionMerge %69 None + OpBranchConditional %67 %68 %72 + %68 = OpLabel + %71 = OpIAdd %6 %84 %26 + OpBranch %69 + %72 = OpLabel + %74 = OpIAdd %6 %84 %64 + %205 = OpCopyObject %6 %74 + OpBranch %69 + %69 = OpLabel + %86 = OpPhi %6 %71 %68 %205 %72 + %301 = OpPhi %6 %71 %68 %15 %72 + OpBranch %20 + %22 = OpLabel + %75 = OpAccessChain %46 %42 %50 + %76 = OpLoad %16 %75 + %78 = OpConvertSToF %16 %84 + %80 = OpAccessChain %46 %42 %45 + %206 = OpCopyObject %16 %78 + %81 = OpLoad %16 %80 + %79 = OpFAdd %16 %76 %78 + %82 = OpFAdd %16 %81 %79 + OpStore %80 %82 + OpReturn + OpFunctionEnd + )"; + + ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); +} + +TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { + // The following SPIR-V comes from this GLSL, with object copies added: + // + // #version 310 es + // + // precision highp int; + // + // int g; + // + // void main() { + // int l; + // l = g; + // g = l; + // } + const std::string shader = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpName %4 "main" + OpName %8 "l" + OpName %10 "g" + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeInt 32 1 + %7 = OpTypePointer Function %6 + %9 = OpTypePointer Private %6 + %10 = OpVariable %9 Private + %4 = OpFunction %2 None %3 + %5 = OpLabel + %8 = OpVariable %7 Function + %100 = OpCopyObject %9 %10 + %101 = OpCopyObject %7 %8 + %11 = OpLoad %6 %10 + OpStore %8 %11 + %12 = OpLoad %6 %8 + OpStore %10 %12 + OpReturn + OpFunctionEnd + )"; + + const auto env = SPV_ENV_UNIVERSAL_1_3; + const auto consumer = nullptr; + const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); + ASSERT_TRUE(IsValid(env, context.get())); + + FactManager fact_manager; + + fact_manager.AddFact(MakeFact(10, 100), context.get()); + fact_manager.AddFact(MakeFact(8, 101), context.get()); + + // Replace %10 with %100 in: + // %11 = OpLoad %6 %10 + auto replacement1 = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(10, SpvOpLoad, 0, 11, 0), + MakeDataDescriptor(100, {}), 0); + ASSERT_TRUE(replacement1.IsApplicable(context.get(), fact_manager)); + replacement1.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + // Replace %8 with %101 in: + // OpStore %8 %11 + auto replacement2 = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(8, SpvOpStore, 0, 11, 0), + MakeDataDescriptor(101, {}), 0); + ASSERT_TRUE(replacement2.IsApplicable(context.get(), fact_manager)); + replacement2.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + // Replace %8 with %101 in: + // %12 = OpLoad %6 %8 + auto replacement3 = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(8, SpvOpLoad, 0, 12, 0), + MakeDataDescriptor(101, {}), 0); + ASSERT_TRUE(replacement3.IsApplicable(context.get(), fact_manager)); + replacement3.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + // Replace %10 with %100 in: + // OpStore %10 %12 + auto replacement4 = TransformationReplaceIdWithSynonym( + transformation::MakeIdUseDescriptor(10, SpvOpStore, 0, 12, 0), + MakeDataDescriptor(100, {}), 0); + ASSERT_TRUE(replacement4.IsApplicable(context.get(), fact_manager)); + replacement4.Apply(context.get(), &fact_manager); + ASSERT_TRUE(IsValid(env, context.get())); + + const std::string after_transformation = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpName %4 "main" + OpName %8 "l" + OpName %10 "g" + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeInt 32 1 + %7 = OpTypePointer Function %6 + %9 = OpTypePointer Private %6 + %10 = OpVariable %9 Private + %4 = OpFunction %2 None %3 + %5 = OpLabel + %8 = OpVariable %7 Function + %100 = OpCopyObject %9 %10 + %101 = OpCopyObject %7 %8 + %11 = OpLoad %6 %100 + OpStore %101 %11 + %12 = OpLoad %6 %101 + OpStore %100 %12 + OpReturn + OpFunctionEnd + )"; + + ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); +} + +} // namespace +} // namespace fuzz +} // namespace spvtools diff --git a/3rdparty/spirv-tools/test/opt/copy_prop_array_test.cpp b/3rdparty/spirv-tools/test/opt/copy_prop_array_test.cpp index 5c1366ae2..1afee9cf9 100644 --- a/3rdparty/spirv-tools/test/opt/copy_prop_array_test.cpp +++ b/3rdparty/spirv-tools/test/opt/copy_prop_array_test.cpp @@ -1571,6 +1571,57 @@ OpFunctionEnd SinglePassRunAndCheck(before, after, true, true); } +TEST_F(CopyPropArrayPassTest, IndexIsNullConstnat) { + const std::string text = R"( +; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Uniform +; CHECK: [[null:%\w+]] = OpConstantNull %uint +; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform__arr_uint_uint_1 [[var]] %uint_0 %uint_0 +; CHECK: OpAccessChain %_ptr_Uniform_uint [[ac1]] [[null]] +; CHECK-NEXT: OpReturn + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpSource HLSL 600 + OpDecorate %myCBuffer DescriptorSet 0 + OpDecorate %myCBuffer Binding 0 + OpDecorate %_arr_v4float_uint_1 ArrayStride 16 + OpMemberDecorate %MyConstantBuffer 0 Offset 0 + OpMemberDecorate %type_myCBuffer 0 Offset 0 + OpDecorate %type_myCBuffer Block + %uint = OpTypeInt 32 0 + %int_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 +%_arr_v4float_uint_1 = OpTypeArray %uint %uint_1 +%MyConstantBuffer = OpTypeStruct %_arr_v4float_uint_1 +%type_myCBuffer = OpTypeStruct %MyConstantBuffer +%_ptr_Uniform_type_myCBuffer = OpTypePointer Uniform %type_myCBuffer +%_arr_v4float_uint_1_0 = OpTypeArray %uint %uint_1 + %void = OpTypeVoid + %19 = OpTypeFunction %void +%_ptr_Function_v4float = OpTypePointer Function %uint +%_ptr_Uniform_MyConstantBuffer = OpTypePointer Uniform %MyConstantBuffer + %myCBuffer = OpVariable %_ptr_Uniform_type_myCBuffer Uniform +%_ptr_Function__arr_v4float_uint_1_0 = OpTypePointer Function %_arr_v4float_uint_1_0 + %23 = OpConstantNull %uint + %main = OpFunction %void None %19 + %24 = OpLabel + %25 = OpVariable %_ptr_Function__arr_v4float_uint_1_0 Function + %26 = OpAccessChain %_ptr_Uniform_MyConstantBuffer %myCBuffer %int_0 + %27 = OpLoad %MyConstantBuffer %26 + %28 = OpCompositeExtract %_arr_v4float_uint_1 %27 0 + %29 = OpCompositeExtract %uint %28 0 + %30 = OpCompositeConstruct %_arr_v4float_uint_1_0 %29 + OpStore %25 %30 + %31 = OpAccessChain %_ptr_Function_v4float %25 %23 + OpReturn + OpFunctionEnd +)"; + + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + } // namespace } // namespace opt } // namespace spvtools diff --git a/3rdparty/spirv-tools/test/opt/wrap_opkill_test.cpp b/3rdparty/spirv-tools/test/opt/wrap_opkill_test.cpp index 7162cc563..7e502be1f 100644 --- a/3rdparty/spirv-tools/test/opt/wrap_opkill_test.cpp +++ b/3rdparty/spirv-tools/test/opt/wrap_opkill_test.cpp @@ -31,7 +31,7 @@ TEST_F(WrapOpKillTest, SingleOpKill) { ; CHECK: [[orig_kill]] = OpFunction ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]] -; CHECK-NEXT: OpUnreachable +; CHECK-NEXT: OpReturn ; CHECK: [[new_kill]] = OpFunction ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpKill @@ -83,10 +83,10 @@ TEST_F(WrapOpKillTest, MultipleOpKillInSameFunc) { ; CHECK-NEXT: OpBranchConditional ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]] -; CHECK-NEXT: OpUnreachable +; CHECK-NEXT: OpReturn ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpFunctionCall %void [[new_kill]] -; CHECK-NEXT: OpUnreachable +; CHECK-NEXT: OpReturn ; CHECK: [[new_kill]] = OpFunction ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpKill @@ -143,11 +143,11 @@ TEST_F(WrapOpKillTest, MultipleOpKillInDifferentFunc) { ; CHECK: [[orig_kill1]] = OpFunction ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]] -; CHECK-NEXT: OpUnreachable +; CHECK-NEXT: OpReturn ; CHECK: [[orig_kill2]] = OpFunction ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpFunctionCall %void [[new_kill]] -; CHECK-NEXT: OpUnreachable +; CHECK-NEXT: OpReturn ; CHECK: [[new_kill]] = OpFunction ; CHECK-NEXT: OpLabel ; CHECK-NEXT: OpKill @@ -193,6 +193,58 @@ TEST_F(WrapOpKillTest, MultipleOpKillInDifferentFunc) { SinglePassRunAndMatch(text, true); } +TEST_F(WrapOpKillTest, FuncWithReturnValue) { + const std::string text = R"( +; CHECK: OpEntryPoint Fragment [[main:%\w+]] +; CHECK: [[main]] = OpFunction +; CHECK: OpFunctionCall %int [[orig_kill:%\w+]] +; CHECK: [[orig_kill]] = OpFunction +; CHECK-NEXT: OpLabel +; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]] +; CHECK-NEXT: [[undef:%\w+]] = OpUndef %int +; CHECK-NEXT: OpReturnValue [[undef]] +; CHECK: [[new_kill]] = OpFunction +; CHECK-NEXT: OpLabel +; CHECK-NEXT: OpKill +; CHECK-NEXT: OpFunctionEnd + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 330 + OpName %main "main" + %void = OpTypeVoid + %5 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %func_type = OpTypeFunction %int + %bool = OpTypeBool + %true = OpConstantTrue %bool + %main = OpFunction %void None %5 + %8 = OpLabel + OpBranch %9 + %9 = OpLabel + OpLoopMerge %10 %11 None + OpBranch %12 + %12 = OpLabel + OpBranchConditional %true %13 %10 + %13 = OpLabel + OpBranch %11 + %11 = OpLabel + %14 = OpFunctionCall %int %kill_ + OpBranch %9 + %10 = OpLabel + OpReturn + OpFunctionEnd + %kill_ = OpFunction %int None %func_type + %15 = OpLabel + OpKill + OpFunctionEnd + )"; + + SinglePassRunAndMatch(text, true); +} + TEST_F(WrapOpKillTest, IdBoundOverflow1) { const std::string text = R"( OpCapability GeometryStreams diff --git a/3rdparty/spirv-tools/test/val/CMakeLists.txt b/3rdparty/spirv-tools/test/val/CMakeLists.txt index b6937b110..d4bfe1d0c 100644 --- a/3rdparty/spirv-tools/test/val/CMakeLists.txt +++ b/3rdparty/spirv-tools/test/val/CMakeLists.txt @@ -35,6 +35,7 @@ add_spvtools_unittest(TARGET val_abcde val_data_test.cpp val_decoration_test.cpp val_derivatives_test.cpp + val_entry_point.cpp val_explicit_reserved_test.cpp val_extensions_test.cpp val_ext_inst_test.cpp diff --git a/3rdparty/spirv-tools/test/val/val_conversion_test.cpp b/3rdparty/spirv-tools/test/val/val_conversion_test.cpp index 8851af3f2..47e67938d 100644 --- a/3rdparty/spirv-tools/test/val/val_conversion_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_conversion_test.cpp @@ -248,6 +248,8 @@ OpMemoryModel Physical32 OpenCL %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3 %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4 +%u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1 + %true = OpConstantTrue %bool %false = OpConstantFalse %bool @@ -1206,6 +1208,49 @@ TEST_F(ValidateConversion, BitcastSuccess) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } +TEST_F(ValidateConversion, BitcastSuccessSPV1p5) { + const std::string body = R"( +%ptr = OpVariable %f32ptr_func Function +%val1 = OpBitcast %u32 %ptr +%val2 = OpBitcast %u64 %ptr +%val3 = OpBitcast %f32ptr_func %u32_1 +%val4 = OpBitcast %f32ptr_wg %u64_1 +%val5 = OpBitcast %f32 %u32_1 +%val6 = OpBitcast %f32vec2 %u32vec2_12 +%val7 = OpBitcast %f32vec2 %u64_1 +%val8 = OpBitcast %f64 %u32vec2_12 +%val9 = OpBitcast %f32vec4 %f64vec2_12 +%val10 = OpBitcast %u32ptr_func %u32vec2_01 +%val11 = OpBitcast %u32vec2 %ptr +)"; + + CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); +} + +TEST_F(ValidateConversion, BitcastSuccessPhysicalStorageBufferKHR) { + const std::string body = R"( +%ptr = OpVariable %f32ptr_func Function +%val1 = OpBitcast %u32 %ptr +%val2 = OpBitcast %u64 %ptr +%val3 = OpBitcast %f32ptr_func %u32_1 +%val4 = OpBitcast %f32ptr_wg %u64_1 +%val5 = OpBitcast %f32 %u32_1 +%val6 = OpBitcast %f32vec2 %u32vec2_12 +%val7 = OpBitcast %f32vec2 %u64_1 +%val8 = OpBitcast %f64 %u32vec2_12 +%val9 = OpBitcast %f32vec4 %f64vec2_12 +%val10 = OpBitcast %u32ptr_func %u32vec2_01 +%val11 = OpBitcast %u32vec2 %ptr +)"; + + CompileSuccessfully( + GenerateKernelCode(body, + "\nOpExtension \"SPV_KHR_physical_storage_buffer\"") + .c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + TEST_F(ValidateConversion, BitcastInputHasNoType) { const std::string body = R"( %val = OpBitcast %u32 %f32 @@ -1249,10 +1294,66 @@ TEST_F(ValidateConversion, BitcastPtrWrongInputType) { CompileSuccessfully(GenerateKernelCode(body).c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Expected input to be a pointer or int scalar if Result Type " - "is pointer: Bitcast")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected input to be a pointer or int scalar if " + "Result Type is pointer: Bitcast")); +} + +TEST_F(ValidateConversion, BitcastPtrWrongInputTypeSPV1p5) { + const std::string body = R"( +%val = OpBitcast %u32ptr_func %f32_1 +)"; + + CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected input to be a pointer, int scalar or 32-bit " + "int vector if Result Type is pointer: Bitcast")); +} + +TEST_F(ValidateConversion, BitcastPtrWrongInputTypePhysicalStorageBufferKHR) { + const std::string body = R"( +%val = OpBitcast %u32ptr_func %f32_1 +)"; + + CompileSuccessfully( + GenerateKernelCode(body, + "\nOpExtension \"SPV_KHR_physical_storage_buffer\"") + .c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected input to be a pointer, int scalar or 32-bit " + "int vector if Result Type is pointer: Bitcast")); +} + +TEST_F(ValidateConversion, BitcastPtrWrongInputTypeIntVectorSPV1p5) { + const std::string body = R"( +%val = OpBitcast %u32ptr_func %u64vec2_01 +)"; + + CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected input to be a pointer, int scalar or 32-bit " + "int vector if Result Type is pointer: Bitcast")); +} + +TEST_F(ValidateConversion, + BitcastPtrWrongInputTypeIntVectorPhysicalStorageBufferKHR) { + const std::string body = R"( +%val = OpBitcast %u32ptr_func %u64vec2_01 +)"; + + CompileSuccessfully( + GenerateKernelCode(body, + "\nOpExtension \"SPV_KHR_physical_storage_buffer\"") + .c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected input to be a pointer, int scalar or 32-bit " + "int vector if Result Type is pointer: Bitcast")); } TEST_F(ValidateConversion, BitcastPtrWrongResultType) { @@ -1262,11 +1363,66 @@ TEST_F(ValidateConversion, BitcastPtrWrongResultType) { CompileSuccessfully(GenerateKernelCode(body).c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Pointer can only be converted to another pointer or int scalar: " - "Bitcast")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Pointer can only be converted to another pointer or " + "int scalar: Bitcast")); +} + +TEST_F(ValidateConversion, BitcastPtrWrongResultTypeSPV1p5) { + const std::string body = R"( +%val = OpBitcast %f32 %f32inp +)"; + + CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Pointer can only be converted to another pointer, int " + "scalar or 32-bit int vector: Bitcast")); +} + +TEST_F(ValidateConversion, BitcastPtrWrongResultTypePhysicalStorageBufferKHR) { + const std::string body = R"( +%val = OpBitcast %f32 %f32inp +)"; + + CompileSuccessfully( + GenerateKernelCode(body, + "\nOpExtension \"SPV_KHR_physical_storage_buffer\"") + .c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Pointer can only be converted to another pointer, int " + "scalar or 32-bit int vector: Bitcast")); +} + +TEST_F(ValidateConversion, BitcastPtrWrongResultTypeIntVectorSPV1p5) { + const std::string body = R"( +%val = OpBitcast %u64vec2 %f32inp +)"; + + CompileSuccessfully(GenerateKernelCode(body).c_str(), SPV_ENV_UNIVERSAL_1_5); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Pointer can only be converted to another pointer, int " + "scalar or 32-bit int vector: Bitcast")); +} + +TEST_F(ValidateConversion, + BitcastPtrWrongResultTypeIntVectorPhysicalStorageBufferKHR) { + const std::string body = R"( +%val = OpBitcast %u64vec2 %f32inp +)"; + + CompileSuccessfully( + GenerateKernelCode(body, + "\nOpExtension \"SPV_KHR_physical_storage_buffer\"") + .c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Pointer can only be converted to another pointer, int " + "scalar or 32-bit int vector: Bitcast")); } TEST_F(ValidateConversion, BitcastDifferentTotalBitWidth) { diff --git a/3rdparty/spirv-tools/test/val/val_decoration_test.cpp b/3rdparty/spirv-tools/test/val/val_decoration_test.cpp index ef3a4eb02..431a4b778 100644 --- a/3rdparty/spirv-tools/test/val/val_decoration_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_decoration_test.cpp @@ -6691,6 +6691,245 @@ TEST_F(ValidateDecorations, ComponentDecorationFunctionParameter) { EXPECT_THAT(getDiagnosticString(), Eq("")); } +TEST_F(ValidateDecorations, VulkanStorageBufferBlock) { + const std::string spirv = R"( +OpCapability Shader +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +OpDecorate %struct Block +OpMemberDecorate %struct 0 Offset 0 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%struct = OpTypeStruct %uint +%ptr_ssbo = OpTypePointer StorageBuffer %struct +%var = OpVariable %ptr_ssbo StorageBuffer +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); +} + +TEST_F(ValidateDecorations, VulkanStorageBufferMissingBlock) { + const std::string spirv = R"( +OpCapability Shader +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%struct = OpTypeStruct %uint +%ptr_ssbo = OpTypePointer StorageBuffer %struct +%var = OpVariable %ptr_ssbo StorageBuffer +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables " + "must be identified with a Block decoration")); +} + +TEST_F(ValidateDecorations, VulkanStorageBufferArrayMissingBlock) { + const std::string spirv = R"( +OpCapability Shader +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%uint_4 = OpConstant %uint 4 +%struct = OpTypeStruct %uint +%array = OpTypeArray %struct %uint_4 +%ptr_ssbo = OpTypePointer StorageBuffer %array +%var = OpVariable %ptr_ssbo StorageBuffer +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables " + "must be identified with a Block decoration")); +} + +TEST_F(ValidateDecorations, VulkanStorageBufferRuntimeArrayMissingBlock) { + const std::string spirv = R"( +OpCapability Shader +OpCapability RuntimeDescriptorArrayEXT +OpExtension "SPV_EXT_descriptor_indexing" +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%struct = OpTypeStruct %uint +%array = OpTypeRuntimeArray %struct +%ptr_ssbo = OpTypePointer StorageBuffer %array +%var = OpVariable %ptr_ssbo StorageBuffer +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables " + "must be identified with a Block decoration")); +} + +TEST_F(ValidateDecorations, VulkanUniformBlock) { + const std::string spirv = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +OpDecorate %struct Block +OpMemberDecorate %struct 0 Offset 0 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%struct = OpTypeStruct %uint +%ptr_ubo = OpTypePointer Uniform %struct +%var = OpVariable %ptr_ubo Uniform +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); +} + +TEST_F(ValidateDecorations, VulkanUniformBufferBlock) { + const std::string spirv = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +OpDecorate %struct BufferBlock +OpMemberDecorate %struct 0 Offset 0 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%struct = OpTypeStruct %uint +%ptr_ubo = OpTypePointer Uniform %struct +%var = OpVariable %ptr_ubo Uniform +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); +} + +TEST_F(ValidateDecorations, VulkanUniformMissingBlock) { + const std::string spirv = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%struct = OpTypeStruct %uint +%ptr_ubo = OpTypePointer Uniform %struct +%var = OpVariable %ptr_ubo Uniform +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables must be " + "identified with a Block or BufferBlock decoration")); +} + +TEST_F(ValidateDecorations, VulkanUniformArrayMissingBlock) { + const std::string spirv = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%uint_4 = OpConstant %uint 4 +%struct = OpTypeStruct %uint +%array = OpTypeArray %struct %uint_4 +%ptr_ubo = OpTypePointer Uniform %array +%var = OpVariable %ptr_ubo Uniform +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables must be " + "identified with a Block or BufferBlock decoration")); +} + +TEST_F(ValidateDecorations, VulkanUniformRuntimeArrayMissingBlock) { + const std::string spirv = R"( +OpCapability Shader +OpCapability RuntimeDescriptorArrayEXT +OpExtension "SPV_EXT_descriptor_indexing" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%struct = OpTypeStruct %uint +%array = OpTypeRuntimeArray %struct +%ptr_ubo = OpTypePointer Uniform %array +%var = OpVariable %ptr_ubo Uniform +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables must be " + "identified with a Block or BufferBlock decoration")); +} + } // namespace } // namespace val } // namespace spvtools diff --git a/3rdparty/spirv-tools/test/val/val_entry_point.cpp b/3rdparty/spirv-tools/test/val/val_entry_point.cpp new file mode 100644 index 000000000..f28cf5d19 --- /dev/null +++ b/3rdparty/spirv-tools/test/val/val_entry_point.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2019 Samsung Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "gmock/gmock.h" +#include "test/unit_spirv.h" +#include "test/val/val_fixtures.h" + +namespace spvtools { +namespace { + +using ::testing::Eq; +using ::testing::HasSubstr; + +using ValidateEntryPoints = spvtest::ValidateBase; + +TEST_F(ValidateEntryPoints, DuplicateEntryPoints) { + const std::string body = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "foo" +OpEntryPoint GLCompute %4 "foo" +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%20 = OpLabel +OpReturn +OpFunctionEnd +%4 = OpFunction %1 None %2 +%21 = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(body); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Entry points cannot share the same name")); +} + +TEST_F(ValidateEntryPoints, UniqueEntryPoints) { + const std::string body = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "foo" +OpEntryPoint GLCompute %4 "foo2" +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%20 = OpLabel +OpReturn +OpFunctionEnd +%4 = OpFunction %1 None %2 +%21 = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(body); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +} // namespace +} // namespace spvtools diff --git a/3rdparty/spirv-tools/test/val/val_memory_test.cpp b/3rdparty/spirv-tools/test/val/val_memory_test.cpp index 5248c0668..858ef8ddc 100644 --- a/3rdparty/spirv-tools/test/val/val_memory_test.cpp +++ b/3rdparty/spirv-tools/test/val/val_memory_test.cpp @@ -2318,9 +2318,14 @@ OpExtension "SPV_EXT_descriptor_indexing" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %func "func" OpExecutionMode %func OriginUpperLeft +OpDecorate %struct Block +OpMemberDecorate %struct 0 Offset 0 %sampler_t = OpTypeSampler +%uint = OpTypeInt 32 0 %array_t = OpTypeRuntimeArray %sampler_t -%array_sb_ptr = OpTypePointer StorageBuffer %array_t +%struct = OpTypeStruct %uint +%sb_array_t = OpTypeRuntimeArray %struct +%array_sb_ptr = OpTypePointer StorageBuffer %sb_array_t %2 = OpVariable %array_sb_ptr StorageBuffer %array_uc_ptr = OpTypePointer UniformConstant %array_t %3 = OpVariable %array_uc_ptr UniformConstant @@ -4292,6 +4297,95 @@ OpMemberDecorate %block 0 Offset 0 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); } +TEST_F(ValidateMemory, VulkanStorageBufferNotAStruct) { + const std::string spirv = R"( +OpCapability Shader +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%ptr_ssbo = OpTypePointer StorageBuffer %uint +%var = OpVariable %ptr_ssbo StorageBuffer +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nVariables identified with " + "the StorageBuffer storage class are used to access " + "transparent buffer backed resources. Such variables must be " + "typed as OpTypeStruct, or an array of this type")); +} + +TEST_F(ValidateMemory, VulkanStorageBufferRuntimeArrayNotAStruct) { + const std::string spirv = R"( +OpCapability Shader +OpCapability RuntimeDescriptorArrayEXT +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpExtension "SPV_EXT_descriptor_indexing" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%array = OpTypeRuntimeArray %uint +%ptr_ssbo = OpTypePointer StorageBuffer %array +%var = OpVariable %ptr_ssbo StorageBuffer +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nVariables identified with " + "the StorageBuffer storage class are used to access " + "transparent buffer backed resources. Such variables must be " + "typed as OpTypeStruct, or an array of this type")); +} + +TEST_F(ValidateMemory, VulkanStorageBufferArrayNotAStruct) { + const std::string spirv = R"( +OpCapability Shader +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +%void = OpTypeVoid +%uint = OpTypeInt 32 0 +%uint_4 = OpConstant %uint 4 +%array = OpTypeArray %uint %uint_4 +%ptr_ssbo = OpTypePointer StorageBuffer %array +%var = OpVariable %ptr_ssbo StorageBuffer +%void_fn = OpTypeFunction %void +%main = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("From Vulkan spec, section 14.5.2:\nVariables identified with " + "the StorageBuffer storage class are used to access " + "transparent buffer backed resources. Such variables must be " + "typed as OpTypeStruct, or an array of this type")); +} + } // namespace } // namespace val } // namespace spvtools diff --git a/3rdparty/spirv-tools/tools/fuzz/fuzz.cpp b/3rdparty/spirv-tools/tools/fuzz/fuzz.cpp index 24e4ac683..fdea1af17 100644 --- a/3rdparty/spirv-tools/tools/fuzz/fuzz.cpp +++ b/3rdparty/spirv-tools/tools/fuzz/fuzz.cpp @@ -104,6 +104,11 @@ Options (in lexicographical order): Path to an interestingness function to guide shrinking: a script that returns 0 if and only if a given binary is interesting. Required if --shrink is provided; disallowed otherwise. + --replay-validation + Run the validator after applying each transformation during + replay (including the replay that occurs during shrinking). + Aborts if an invalid binary is created. Useful for debugging + spirv-fuzz. --version Display fuzzer version information. @@ -161,6 +166,9 @@ FuzzStatus ParseFlags(int argc, const char** argv, std::string* in_binary_file, sizeof("--interestingness=") - 1)) { const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg); *interestingness_function_file = std::string(split_flag.second); + } else if (0 == strncmp(cur_arg, "--replay-validation", + sizeof("--replay-validation") - 1)) { + fuzzer_options->enable_replay_validation(); } else if (0 == strncmp(cur_arg, "--shrink=", sizeof("--shrink=") - 1)) { const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg); *shrink_transformations_file = std::string(split_flag.second); @@ -221,6 +229,16 @@ FuzzStatus ParseFlags(int argc, const char** argv, std::string* in_binary_file, return {FuzzActions::STOP, 1}; } + if (replay_transformations_file->empty() && + shrink_transformations_file->empty() && + static_cast(*fuzzer_options) + ->replay_validation_enabled) { + spvtools::Error(FuzzDiagnostic, nullptr, {}, + "The --replay-validation argument can only be used with " + "one of the --replay or --shrink arguments."); + return {FuzzActions::STOP, 1}; + } + if (!replay_transformations_file->empty()) { // A replay transformations file was given, thus the tool is being invoked // in replay mode. @@ -278,6 +296,7 @@ bool ParseTransformations( } bool Replay(const spv_target_env& target_env, + spv_const_fuzzer_options fuzzer_options, const std::vector& binary_in, const spvtools::fuzz::protobufs::FactSequence& initial_facts, const std::string& replay_transformations_file, @@ -289,7 +308,8 @@ bool Replay(const spv_target_env& target_env, &transformation_sequence)) { return false; } - spvtools::fuzz::Replayer replayer(target_env); + spvtools::fuzz::Replayer replayer(target_env, + fuzzer_options->replay_validation_enabled); replayer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); auto replay_result_status = replayer.Run(binary_in, initial_facts, transformation_sequence, @@ -313,7 +333,8 @@ bool Shrink(const spv_target_env& target_env, return false; } spvtools::fuzz::Shrinker shrinker(target_env, - fuzzer_options->shrinker_step_limit); + fuzzer_options->shrinker_step_limit, + fuzzer_options->replay_validation_enabled); shrinker.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); spvtools::fuzz::Shrinker::InterestingnessFunction interestingness_function = @@ -362,6 +383,23 @@ bool Fuzz(const spv_target_env& target_env, } // namespace +// Dumps |binary| to file |filename|. Useful for interactive debugging. +void DumpShader(const std::vector& binary, const char* filename) { + auto write_file_succeeded = + WriteFile(filename, "wb", &binary[0], binary.size()); + if (!write_file_succeeded) { + std::cerr << "Failed to dump shader" << std::endl; + } +} + +// Dumps the SPIRV-V module in |context| to file |filename|. Useful for +// interactive debugging. +void DumpShader(spvtools::opt::IRContext* context, const char* filename) { + std::vector binary; + context->module()->ToBinary(&binary, false); + DumpShader(binary, filename); +} + const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3; int main(int argc, const char** argv) { @@ -418,7 +456,7 @@ int main(int argc, const char** argv) { } break; case FuzzActions::REPLAY: - if (!Replay(target_env, binary_in, initial_facts, + if (!Replay(target_env, fuzzer_options, binary_in, initial_facts, replay_transformations_file, &binary_out, &transformations_applied)) { return 1; diff --git a/3rdparty/spirv-tools/tools/sva/.eslintrc.json b/3rdparty/spirv-tools/tools/sva/.eslintrc.json new file mode 100644 index 000000000..2f0772678 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true, + "mocha": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "block-scoped-var": "error", + "consistent-return": "error", + "eqeqeq": ["error", "always"], + "indent": [ "error", 2 ], + "linebreak-style": [ "error", "unix" ], + "no-eval": "error", + "no-shadow": "error", + "no-shadow-restricted-names": "error", + "quotes": [ "error", "double" ], + "semi": [ "error", "always" ] + } +} diff --git a/3rdparty/spirv-tools/tools/sva/.gitignore b/3rdparty/spirv-tools/tools/sva/.gitignore new file mode 100644 index 000000000..88e64c381 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +node_modules +third_party/spirv-headers +o.sva +build +yarn-error.log diff --git a/3rdparty/spirv-tools/tools/sva/README.md b/3rdparty/spirv-tools/tools/sva/README.md new file mode 100644 index 000000000..d80b4d2c3 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/README.md @@ -0,0 +1,41 @@ +# SVA + +SPIR-V Assember for WebGPU. The SPIR-V Assembler is a JavaScript library to +convert SPIR-V assembly (as produced by spirv-dis in SPIR-V Tools) into a +SPIR-V binary. The assembler assumes it is generating WebGPU SPIR-V and thus has +the following limitations. + + * Only 32 bit integers and floats supported + * Only GLSL accepted as an extended instruction set + * Doesn't support ! syntax for integers + * Doesn't support hex encoding for float + +```shell +yarn install +yarn test +``` + +You can also use `yarn watch` to watch all of the files and re-run tests as +needed. + +## Webserver +Using `yarn serve` will start a webserver on localhost:5000. If you load the +`tests/index.html` file this will load the SVA files into browser. + +## Command Line +There is a simple assembler binary with can be executed from the command line. + +```shell +yarn sva tests/simple.spv_asm +``` + +The above will generate a `o.sva` file in the current directory. + +## Update spirv.data.json + +If there is a new spirv-headers release update the externals folder checkout +and then: + +```shell +./tools/process_grammar.rb > src/spirv.data.json +``` diff --git a/3rdparty/spirv-tools/tools/sva/bin/sva.js b/3rdparty/spirv-tools/tools/sva/bin/sva.js new file mode 100755 index 000000000..e2448d6ef --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/bin/sva.js @@ -0,0 +1,32 @@ +#!/usr/bin/env node +// +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +"use strict"; + +const fs = require("fs"); + +import SVA from "../src/sva.js"; + +let input = fs.readFileSync(process.argv[2], "utf-8"); +let u = SVA.assemble(input); + +if (typeof u === "string") { + console.log(u); +} else { + fs.writeFileSync("o.sva", new Buffer(u.buffer), (err) => { + console.log(["ERROR", err]); + }); +} diff --git a/3rdparty/spirv-tools/tools/sva/mocha.opts b/3rdparty/spirv-tools/tools/sva/mocha.opts new file mode 100644 index 000000000..4a5232017 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/mocha.opts @@ -0,0 +1 @@ +--recursive diff --git a/3rdparty/spirv-tools/tools/sva/package.json b/3rdparty/spirv-tools/tools/sva/package.json new file mode 100644 index 000000000..3072d4cc8 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/package.json @@ -0,0 +1,25 @@ +{ + "name": "sva", + "version": "0.1.0", + "description": "SPIR-V Assembler", + "main": "index.js", + "author": "dan sinclair ", + "license": "Apache-2.0", + "private": true, + "scripts": { + "sva": "node -r esm bin/sva.js", + "lint": "eslint --fix --ext .js .", + "test": "mocha --require esm src/**/*_test.js", + "watch": "mocha --require esm --watch --watch-extension js \"src/**/*_test.js\"", + "serve": "serve", + "bundle": "rollup -c" + }, + "devDependencies": { + "chai": "^4.2.0", + "eslint": "^6.3.0", + "esm": "^3.2.25", + "mocha": "^6.2.0", + "rollup": "^1.21.4", + "serve": "^11.1.0" + } +} diff --git a/3rdparty/spirv-tools/tools/sva/rollup.config.js b/3rdparty/spirv-tools/tools/sva/rollup.config.js new file mode 100644 index 000000000..2056e16e5 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/rollup.config.js @@ -0,0 +1,7 @@ +export default { + input: 'src/sva.js', + output: { + file: 'build/sva.js', + format: 'esm', + } +} diff --git a/3rdparty/spirv-tools/tools/sva/src/assembler.js b/3rdparty/spirv-tools/tools/sva/src/assembler.js new file mode 100644 index 000000000..7bc208ec1 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/assembler.js @@ -0,0 +1,98 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export default class Assembler { + static get GENERATOR_ID() { return 0; } + + /** + * @param {AST} the AST to build the SPIR-V from + */ + constructor(ast) { + this.ast_ = ast; + } + + /** + * Assembles the AST into binary SPIR-V. + * @return {Uint32Array} The SPIR-V binary data. + */ + assemble() { + let total_size = 5; + for (const inst of this.ast_.instructions()) { + total_size += 1; + for (const op of inst.operands()) { + total_size += op.length(); + } + } + + let u = new Uint32Array(total_size); + u[0] = 0x07230203; // Magic + u[1] = 0x00010500; // Version 1.5 + u[2] = Assembler.GENERATOR_ID; // Generator magic number + u[3] = this.ast_.getIdBounds(); // ID bounds + u[4] = 0; // Reserved + + let idx = 5; + for (const inst of this.ast_.instructions()) { + let op_size = 1; + for (const op of inst.operands()) { + op_size += op.length(); + } + + u[idx++] = op_size << 16 | inst.opcode(); + for (const op of inst.operands()) { + idx = this.processOp(u, idx, op); + } + } + + return u; + } + + processOp(u, idx, op) { + if (op.type() === "string") { + let len = 0; + let v = 0; + for (const ch of op.value()) { + v = v | (ch.charCodeAt(0) << (len * 8)); + len += 1; + + if (len === 4) { + u[idx++] = v; + len = 0; + v = 0; + } + } + // Make sure either the terminating 0 byte is written or the last + // partial word is written. + u[idx++] = v; + + } else if (op.type() === "float") { + // TODO(dsinclair): Handle 64 bit floats ... + let b = new ArrayBuffer(4); + let f = new Float32Array(b); + f[0] = op.value(); + + let u2 = new Uint32Array(b); + + u[idx++] = u2[0]; + } else { + u[idx++] = op.value(); + } + + for (const param of op.params()) { + idx = this.processOp(u, idx, param); + } + + return idx; + } +} diff --git a/3rdparty/spirv-tools/tools/sva/src/assembler_test.js b/3rdparty/spirv-tools/tools/sva/src/assembler_test.js new file mode 100644 index 000000000..a23d211da --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/assembler_test.js @@ -0,0 +1,165 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { assert } from "chai"; +import Lexer from "./lexer"; +import Parser from "./parser"; +import grammar from "./spirv.data.js"; +import Assembler from "./assembler"; + +describe("assembler", () => { + it("generates SPIR-V magic number", () => { + let input = `; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 7 +; Bound: 6 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 440 + OpName %main "main" + %void = OpTypeVoid + %3 = OpTypeFunction %void + %main = OpFunction %void None %3 + %5 = OpLabel + OpReturn + OpFunctionEnd`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + + let a = new Assembler(ast); + let res = a.assemble(); + assert.equal(res[0], 0x07230203); + }); + + it("assembles enumerant params", () => { + let input = "OpExecutionMode %main LocalSize 2 3 4"; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + + let a = new Assembler(ast); + let res = a.assemble(); + + assert.lengthOf(res, 11); + assert.equal(res[5], (6 /* word count */ << 16) | 16 /* opcode */); + assert.equal(res[6], 1 /* %main */); + assert.equal(res[7], 17 /* LocalSize */); + assert.equal(res[8], 2); + assert.equal(res[9], 3); + assert.equal(res[10], 4); + }); + + it("assembles float 32 values", () => { + let input = `%float = OpTypeFloat 32 + %float1 = OpConstant %float 0.400000006`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + + let a = new Assembler(ast); + let res = a.assemble(); + + assert.lengthOf(res, 12); + assert.equal(res[8], (4 /* word count */ << 16) | 43 /* opcode */); + assert.equal(res[9], 1 /* %float */); + assert.equal(res[10], 2 /* %float */); + assert.equal(res[11], 0x3ecccccd /* 0.400000006 */); + }); + + describe("strings", () => { + it("assembles 'abcd'", () => { + let input = `OpName %mains "abcd"`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + + let a = new Assembler(ast); + let res = a.assemble(); + + assert.lengthOf(res, 9); + assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); + assert.equal(res[6], 1 /* %mains */); + assert.equal(res[7], 0x64636261 /* food */); + assert.equal(res[8], 0x00000000 /* null byte */); + }); + + it("assembles 'abcde'", () => { + let input = `OpName %mains "abcde"`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + + let a = new Assembler(ast); + let res = a.assemble(); + + assert.lengthOf(res, 9); + assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); + assert.equal(res[6], 1 /* %mains */); + assert.equal(res[7], 0x64636261 /* abcd */); + assert.equal(res[8], 0x00000065 /* e */); + }); + + it("assembles 'abcdef'", () => { + let input = `OpName %mains "abcdef"`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + + let a = new Assembler(ast); + let res = a.assemble(); + + assert.lengthOf(res, 9); + assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); + assert.equal(res[6], 1 /* %mains */); + assert.equal(res[7], 0x64636261 /* abcd */); + assert.equal(res[8], 0x00006665 /* ef */); + }); + + it("assembles 'abcdefg'", () => { + let input = `OpName %mains "abcdefg"`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + + let a = new Assembler(ast); + let res = a.assemble(); + + assert.lengthOf(res, 9); + assert.equal(res[5], (4 /* word count */ << 16) | 5 /* opcode */); + assert.equal(res[6], 1 /* %mains */); + assert.equal(res[7], 0x64636261 /* abcd */); + assert.equal(res[8], 0x00676665 /* efg */); + }); + }); +}); diff --git a/3rdparty/spirv-tools/tools/sva/src/ast.js b/3rdparty/spirv-tools/tools/sva/src/ast.js new file mode 100644 index 000000000..d396d2fb6 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/ast.js @@ -0,0 +1,141 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +class Module { + constructor() { + this.instructions_ = []; + this.next_id_ = 1; + + /** + * Maps {string, hash} where the string is the type name and the hash is: + * type- 'float' or 'int' + * width- number of bits needed to store number + * signed- the sign of the number + */ + this.types_ = {}; + + /** + * Maps {string, number} where the string is the type name and the number is + * the id value. + */ + this.assigned_ids_ = {}; + } + + instructions() { return this.instructions_; } + + instruction(val) { return this.instructions_[val]; } + + addInstruction(inst) { + this.instructions_.push(inst); + + // Record type information + if (inst.name() === "OpTypeInt" || inst.name() === "OpTypeFloat") { + let is_int = inst.name() === "OpTypeInt"; + + this.types_[inst.operand(0).name()] = { + type: is_int ? "int" : "float", + width: inst.operand(1).value(), + signed: is_int ? inst.operand(2).value() : 1 + }; + } + + // Record operand result id's + inst.operands().forEach((op) => { + if (op.rawValue() !== undefined && op.type() === "result_id") { + this.next_id_ = Math.max(this.next_id_, op.rawValue() + 1); + } + }); + } + + getType(name) { return this.types_[name]; } + + getId(name) { + if (this.assigned_ids_[name] !== undefined) { + return this.assigned_ids_[name]; + } + + let next = this.next_id_; + this.assigned_ids_[name] = next; + + this.next_id_ += 1; + return next; + } + + getIdBounds() { return this.next_id_; } +} + +class Instruction { + constructor(name, opcode, operands) { + this.name_ = name; + this.opcode_ = opcode; + this.operands_ = operands; + } + + name() { return this.name_; } + + opcode() { return this.opcode_; } + + operands() { return this.operands_; } + + operand(val) { return this.operands_[val]; } +} + +class Operand { + constructor(mod, name, type, value, params) { + this.module_ = mod; + this.name_ = name; + this.type_ = type; + this.value_ = value; + this.params_ = params; + } + + name() { return this.name_; } + + length() { + // Get the value just to force it to be filled. + this.value(); + + if (this.type_ === "string") { + return Math.ceil((this.value_.length + 1) / 4); + } + + let size = 1; + for (const param of this.params_) { + size += param.length(); + } + return size; + } + + type() { return this.type_; } + + rawValue() { return this.value_; } + + // This method should only be called on ResultId's after the full parse is + // complete. This is because the AST will only have the maximum seen numeric + // ResultId when the parse is done. + value() { + if (this.value_ === undefined) { + this.value_ = this.module_.getId(this.name_); + } + return this.value_; + } + + params() { return this.params_; } +} + +export { + Module, + Instruction, + Operand +}; diff --git a/3rdparty/spirv-tools/tools/sva/src/lexer.js b/3rdparty/spirv-tools/tools/sva/src/lexer.js new file mode 100644 index 000000000..b39f93a02 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/lexer.js @@ -0,0 +1,363 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Token, TokenType } from "./token.js"; + +export default class Lexer { + /** + * @param {String} input The input string to tokenize. + */ + constructor(input) { + this.input_ = input; + this.len_ = input.length; + this.cur_pos_ = 0; + this.cur_line_ = 1; + + this.num_regex_ = /^[0-9]+$/; + this.alpha_regex_ = /^[a-zA-Z_]+$/; + this.op_regex_ = /^Op[A-Z][^\s]*$/; + this.hex_regex_ = /^[0-9a-fA-F]$/; + } + + /** + * Parses the next token from the input stream. + * @return {Token} the next token. + */ + next() { + this.skipWhitespace(); + this.skipComments(); + + if (this.cur_pos_ >= this.len_) + return new Token(TokenType.kEOF, this.cur_line_); + + let n = this.tryHexInteger(); + if (n !== undefined) + return n; + + n = this.tryFloat(); + if (n !== undefined) + return n; + + n = this.tryInteger(); + if (n !== undefined) + return n; + + n = this.tryString(); + if (n !== undefined) + return n; + + n = this.tryOp(); + if (n !== undefined) + return n; + + n = this.tryPunctuation(); + if (n !== undefined) + return n; + + n = this.tryResultId(); + if (n !== undefined) + return n; + + n = this.tryIdent(); + if (n !== undefined) + return n; + + return new Token(TokenType.kError, this.cur_line_, "Failed to match token"); + } + + is(str) { + if (this.len_ <= this.cur_pos_ + (str.length - 1)) + return false; + + for (let i = 0; i < str.length; ++i) { + if (this.input_[this.cur_pos_ + i] !== str[i]) + return false; + } + + return true; + } + + isNum(ch) { + return ch.match(this.num_regex_); + } + + isAlpha(ch) { + return ch.match(this.alpha_regex_); + } + + isAlphaNum(ch) { + return this.isNum(ch) || this.isAlpha(ch); + } + + isHex(char) { + return char.match(this.hex_regex_); + } + + isCurWhitespace() { + return this.is(" ") || this.is("\t") || this.is("\r") || this.is("\n"); + } + + skipWhitespace() { + for(;;) { + let cur_pos = this.cur_pos_; + while (this.cur_pos_ < this.len_ && + this.isCurWhitespace()) { + if (this.is("\n")) + this.cur_line_ += 1; + + this.cur_pos_ += 1; + } + + this.skipComments(); + + // Cursor didn't move so no whitespace matched. + if (cur_pos === this.cur_pos_) + break; + } + } + + skipComments() { + if (!this.is(";")) + return; + + while (this.cur_pos_ < this.len_ && !this.is("\n")) + this.cur_pos_ += 1; + } + + /** + * Attempt to parse the next part of the input as a float. + * @return {Token|undefined} returns a Token if a float is matched, + * undefined otherwise. + */ + tryFloat() { + let start = this.cur_pos_; + let end = start; + + if (this.cur_pos_ >= this.len_) + return undefined; + if (this.input_[end] === "-") + end += 1; + + while (end < this.len_ && this.isNum(this.input_[end])) + end += 1; + + // Must have a "." in a float + if (end >= this.len_ || this.input_[end] !== ".") + return undefined; + + end += 1; + while (end < this.len_ && this.isNum(this.input_[end])) + end += 1; + + let substr = this.input_.substr(start, end - start); + if (substr === "." || substr === "-.") + return undefined; + + this.cur_pos_ = end; + + return new Token(TokenType.kFloatLiteral, this.cur_line_, parseFloat(substr)); + } + + /** + * Attempt to parse a hex encoded integer. + * @return {Token|undefined} returns a Token if a Hex number is matched, + * undefined otherwise. + */ + tryHexInteger() { + let start = this.cur_pos_; + let end = start; + + if (this.cur_pos_ >= this.len_) + return undefined; + if (end + 2 >= this.len_ || this.input_[end] !== "0" || + this.input_[end + 1] !== "x") { + return undefined; + } + + end += 2; + + while (end < this.len_ && this.isHex(this.input_[end])) + end += 1; + + this.cur_pos_ = end; + + let val = parseInt(this.input_.substr(start, end - start), 16); + return new Token(TokenType.kIntegerLiteral, this.cur_line_, val); + } + + /** + * Attempt to parse an encoded integer. + * @return {Token|undefined} returns a Token if a number is matched, + * undefined otherwise. + */ + tryInteger() { + let start = this.cur_pos_; + let end = start; + + if (this.cur_pos_ >= this.len_) + return undefined; + if (this.input_[end] === "-") + end += 1; + + if (end >= this.len_ || !this.isNum(this.input_[end])) + return undefined; + + while (end < this.len_ && this.isNum(this.input_[end])) + end += 1; + + this.cur_pos_ = end; + + let val = parseInt(this.input_.substr(start, end - start), 10); + return new Token(TokenType.kIntegerLiteral, this.cur_line_, val); + } + + /** + * Attempt to parse a result id. + * @return {Token|undefined} returns a Token if a result id is matched, + * undefined otherwise. + */ + tryResultId() { + let start = this.cur_pos_; + if (start >= this.len_) + return undefined; + if (!this.is("%")) + return undefined; + + start += 1; + this.cur_pos_ += 1; + while (this.cur_pos_ < this.len_ && + (this.isAlphaNum(this.input_[this.cur_pos_]) || this.is("_"))) { + this.cur_pos_ += 1; + } + + let ident = this.input_.substr(start, this.cur_pos_ - start); + let value = undefined; + if (ident.match(this.num_regex_)) + value = parseInt(ident, 10); + + return new Token(TokenType.kResultId, this.cur_line_, { + name: ident, + val: value + }); + } + + /** + * Attempt to parse an identifier. + * @return {Token|undefined} returns a Token if an identifier is matched, + * undefined otherwise. + */ + tryIdent() { + let start = this.cur_pos_; + if (start >= this.len_) + return undefined; + + while (this.cur_pos_ < this.len_ && + (this.isAlphaNum(this.input_[this.cur_pos_]) || this.is("_"))) { + this.cur_pos_ += 1; + } + + let ident = this.input_.substr(start, this.cur_pos_ - start); + return new Token(TokenType.kIdentifier, this.cur_line_, ident); + } + + /** + * Attempt to parse an Op command. + * @return {Token|undefined} returns a Token if an Op command is matched, + * undefined otherwise. + */ + tryOp() { + let start = this.cur_pos_; + if (this.cur_pos_ >= this.len_ || (this.cur_pos_ + 1 >= this.len_)) + return undefined; + + if (this.input_[this.cur_pos_] !== "O" || + this.input_[this.cur_pos_ + 1] !== "p") { + return undefined; + } + + while (this.cur_pos_ < this.len_ && + !this.isCurWhitespace()) { + this.cur_pos_ += 1; + } + + return new Token(TokenType.kOp, this.cur_line_, { + name: this.input_.substr(start, this.cur_pos_ - start) + }); + } + + /** + * Attempts to match punctuation strings against the input + * @return {Token|undefined} Returns the Token for the punctuation or + * undefined if no matches found. + */ + tryPunctuation() { + let type = undefined; + if (this.is("=")) + type = TokenType.kEqual; + else if (this.is("|")) + type = TokenType.kPipe; + + if (type === undefined) + return undefined; + + this.cur_pos_ += type.length; + return new Token(type, this.cur_line_, type); + } + + /** + * Attempts to match strings against the input + * @return {Token|undefined} Returns the Token for the string or undefined + * if no match found. + */ + tryString() { + let start = this.cur_pos_; + + // Must have at least 2 chars for a string. + if (this.cur_pos_ >= this.len_ || (this.cur_pos_ + 1 >= this.len_)) + return undefined; + if (!this.is("\"")) + return undefined; + + this.cur_pos_ += 1; + let str = ""; + while (this.cur_pos_ <= this.len_) { + if (this.is("\"")) + break; + + if (this.is("\\")) { + this.cur_pos_ += 1; + if (this.cur_pos_ >= this.len_) + return undefined; + + if (this.is("\\")) { + str += "\\"; + } else if (this.is("\"")) { + str += '"'; + } else { + str += this.input_[this.cur_pos_]; + } + } else { + str += this.input_[this.cur_pos_]; + } + this.cur_pos_ += 1; + } + + if (this.cur_pos_ >= this.len_) + return undefined; + + this.cur_pos_ += 1; + + return new Token(TokenType.kStringLiteral, this.cur_line_, str); + } +} diff --git a/3rdparty/spirv-tools/tools/sva/src/lexer_test.js b/3rdparty/spirv-tools/tools/sva/src/lexer_test.js new file mode 100644 index 000000000..32b24c75a --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/lexer_test.js @@ -0,0 +1,191 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { assert } from "chai"; +import Lexer from "./lexer"; +import { TokenType } from "./token"; + +describe("lexer", () => { + describe("skipped content", () => { + it("skips whitespace", () => { + let input = " \t\r\n\t \tOpKill\t\n\t \r "; + let l = new Lexer(input); + + let t = l.next(); + assert.equal(t.type, TokenType.kOp); + assert.equal(t.line, 2); + assert.equal(t.data.name, "OpKill"); + + t = l.next(); + assert.equal(t.type, TokenType.kEOF); + assert.equal(t.line, 3); + }); + + it("skips ; comments", () => { + let input = `; start with comment +OpKill ; end of line comment +; another comment +%1`; + + let l = new Lexer(input); + let t = l.next(); + assert.equal(t.type, TokenType.kOp); + assert.equal(t.data.name, "OpKill"); + assert.equal(t.line, 2); + + t = l.next(); + assert.equal(t.type, TokenType.kResultId); + assert.equal(t.data.name, "1"); + assert.equal(t.data.val, 1); + assert.equal(t.line, 4); + }); + }); + + describe("numerics", () => { + it("parses floats", () => { + let input = ["0.0", "0.", ".0", "5.7", "5.", ".7", "-0.0", "-.0", + "-0.", "-5.7", "-5.", "-.7"]; + + let results = [0.0, 0.0, 0.0, 5.7, 5.0, 0.7, 0.0, 0.0, 0.0, -5.7, -5.0, + -0.7]; + input.forEach((val, idx) => { + let l = new Lexer(val); + let t = l.next(); + + assert.equal(t.type, TokenType.kFloatLiteral, + `expected ${val} to be a float got ${t.type}`); + assert.equal(t.data, results[idx], + `expected ${results[idx]} === ${t.data}`); + + t = l.next(); + assert.equal(t.type, TokenType.kEOF); + assert.equal(t.data, undefined); + }); + }); + + it("handles invalid floats", () => { + let input = [".", "-."]; + input.forEach((val) => { + let l = new Lexer(val); + let t = l.next(); + + assert.notEqual(t.type, TokenType.kFloatLiteral, + `expect ${val} to not match type float`); + }); + }); + + it("parses integers", () => { + let input = ["0", "-0", "123", "-123", "2147483647", "-2147483648", + "4294967295", "0x00", "0x24"]; + let results = [0, 0, 123, -123,2147483647, -2147483648, 4294967295, + 0x0, 0x24]; + + input.forEach((val, idx) => { + let l = new Lexer(val); + let t = l.next(); + + assert.equal(t.type, TokenType.kIntegerLiteral, + `expected ${val} to be an integer got ${t.type}`); + assert.equal(t.data, results[idx], + `expected ${results[idx]} === ${t.data}`); + + t = l.next(); + assert.equal(t.type, TokenType.kEOF); + assert.equal(t.data, undefined); + }); + }); + }); + + it("matches result_ids", () => { + let input = `%123 +%001 +%main +%_a_b_c`; + + let result = [ + {name: "123", val: 123}, + {name: "001", val: 1}, + {name: "main", val: undefined}, + {name: "_a_b_c", val: undefined} + ]; + + let l = new Lexer(input); + for (let i = 0; i < result.length; ++i) { + let t = l.next(); + assert.equal(t.type, TokenType.kResultId); + assert.equal(t.data.name, result[i].name); + assert.equal(t.data.val, result[i].val); + } + }); + + it("matches punctuation", () => { + let input = "="; + let results = [TokenType.kEqual]; + + let l = new Lexer(input); + for (let i = 0; i < results.length; ++i) { + let t = l.next(); + assert.equal(t.type, results[i]); + assert.equal(t.line, i + 1); + } + + let t = l.next(); + assert.equal(t.type, TokenType.kEOF); + }); + + describe("strings", () => { + it("matches strings", () => { + let input = "\"GLSL.std.450\""; + + let l = new Lexer(input); + let t = l.next(); + assert.equal(t.type, TokenType.kStringLiteral); + assert.equal(t.data, "GLSL.std.450"); + }); + + it("handles unfinished strings", () => { + let input = "\"GLSL.std.450"; + + let l = new Lexer(input); + let t = l.next(); + assert.equal(t.type, TokenType.kError); + }); + + it("handles escapes", () => { + let input = `"embedded\\"quote" +"embedded\\\\slash" +"embedded\\nchar"`; + let results = [`embedded\"quote`, `embedded\\slash`, `embeddednchar`]; + + let l = new Lexer(input); + for (let i = 0; i < results.length; ++i) { + let t = l.next(); + assert.equal(t.type, TokenType.kStringLiteral, results[i]); + assert.equal(t.data, results[i]); + } + }); + }); + + it("matches keywords", () => { + let input = "GLSL Function"; + let results = ["GLSL", "Function"]; + + let l = new Lexer(input); + for (let i = 0; i < results.length; ++i) { + let t = l.next(); + assert.equal(t.type, TokenType.kIdentifier, results[i]); + assert.equal(t.data, results[i]); + } + }); +}); diff --git a/3rdparty/spirv-tools/tools/sva/src/parser.js b/3rdparty/spirv-tools/tools/sva/src/parser.js new file mode 100644 index 000000000..3eee66190 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/parser.js @@ -0,0 +1,277 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { TokenType } from "./token.js"; +import * as AST from "./ast.js"; + +export default class Parser { + /** + * @param {Hash} The SPIR-V grammar + * @param {Lexer} The lexer + * @return {AST} Attempts to build an AST from the tokens returned by the + * given lexer + */ + constructor(grammar, lexer) { + this.grammar_ = grammar; + this.lexer_ = lexer; + + this.peek_ = []; + this.error_ = ""; + } + + get error() { return this.error_; } + + next() { + return this.peek_.shift() || this.lexer_.next(); + } + + peek(idx) { + while (this.peek_.length <= idx) { + this.peek_.push(this.lexer_.next()); + } + return this.peek_[idx]; + } + + /** + * Executes the parser. + * + * @return {AST|undefined} returns a parsed AST on success or undefined + * on error. The error message can be retrieved by + * calling error(). + */ + parse() { + let ast = new AST.Module(); + for(;;) { + let token = this.next(); + if (token === TokenType.kError) { + this.error_ = token.line() + ": " + token.data(); + return undefined; + } + if (token.type === TokenType.kEOF) + break; + + let result_id = undefined; + if (token.type === TokenType.kResultId) { + result_id = token; + + token = this.next(); + if (token.type !== TokenType.kEqual) { + this.error_ = token.line + ": expected = after result id"; + return undefined; + } + + token = this.next(); + } + + if (token.type !== TokenType.kOp) { + this.error_ = token.line + ": expected Op got " + token.type; + return undefined; + } + + let name = token.data.name; + let data = this.getInstructionData(name); + let operands = []; + let result_type = undefined; + + for (let operand of data.operands) { + if (operand.kind === "IdResult") { + if (result_id === undefined) { + this.error_ = token.line + ": expected result id"; + return undefined; + } + let o = new AST.Operand(ast, result_id.data.name, "result_id", + result_id.data.val, []); + if (o === undefined) { + return undefined; + } + operands.push(o); + } else { + if (operand.quantifier === "?") { + if (this.nextIsNewInstr()) { + break; + } + } else if (operand.quantifier === "*") { + while (!this.nextIsNewInstr()) { + let o = this.extractOperand(ast, result_type, operand); + if (o === undefined) { + return undefined; + } + operands.push(o); + } + break; + } + + let o = this.extractOperand(ast, result_type, operand); + if (o === undefined) { + return undefined; + } + + // Store the result type away so we can use it for context dependent + // numbers if needed. + if (operand.kind === "IdResultType") { + result_type = ast.getType(o.name()); + } + + operands.push(o); + } + } + + // Verify only GLSL extended instructions are used + if (name === "OpExtInstImport" && operands[1].value() !== "GLSL.std.450") { + this.error_ = token.line + ": Only GLSL.std.450 external instructions supported"; + return undefined; + } + + let inst = new AST.Instruction(name, data.opcode, operands); + + ast.addInstruction(inst); + } + return ast; + } + + getInstructionData(name) { + return this.grammar_["instructions"][name]; + } + + nextIsNewInstr() { + let n0 = this.peek(0); + if (n0.type === TokenType.kOp || n0.type === TokenType.kEOF) { + return true; + } + + let n1 = this.peek(1); + if (n1.type === TokenType.kEOF) { + return false; + } + if (n0.type === TokenType.kResultId && n1.type === TokenType.kEqual) + return true; + + return false; + } + + extractOperand(ast, result_type, data) { + let t = this.next(); + + let name = undefined; + let kind = undefined; + let value = undefined; + let params = []; + + // TODO(dsinclair): There are a bunch of missing types here. See + // https://github.com/KhronosGroup/SPIRV-Tools/blob/master/source/text.cpp#L210 + if (data.kind === "IdResult" || data.kind === "IdRef" + || data.kind === "IdResultType") { + if (t.type !== TokenType.kResultId) { + this.error_ = t.line + ": expected result id"; + return undefined; + } + + name = t.data.name; + kind = "result_id"; + value = t.data.val; + } else if (data.kind === "LiteralString") { + if (t.type !== TokenType.kStringLiteral) { + this.error_ = t.line + ": expected string not found"; + return undefined; + } + + name = t.data; + kind = "string"; + value = t.data; + } else if (data.kind === "LiteralInteger") { + if (t.type !== TokenType.kIntegerLiteral) { + this.error_ = t.line + ": expected integer not found"; + return undefined; + } + + name = "" + t.data; + kind = t.type; + value = t.data; + } else if (data.kind === "LiteralContextDependentNumber") { + if (result_type === undefined) { + this.error_ = t.line + + ": missing result type for context dependent number"; + return undefined; + } + if (t.type !== TokenType.kIntegerLiteral + && t.type !== TokenType.kFloatLiteral) { + this.error_ = t.line + ": expected number not found"; + return undefined; + } + + name = "" + t.data; + kind = result_type.type; + value = t.data; + + } else if (data.kind === "LiteralExtInstInteger") { + if (t.type !== TokenType.kIdentifier) { + this.error_ = t.line + ": expected instruction identifier"; + return undefined; + } + + if (this.grammar_.ext[t.data] === undefined) { + this.error_ = t.line + `: unable to find extended instruction (${t.data})`; + return undefined; + } + + name = t.data; + kind = "integer"; + value = this.grammar_.ext[t.data]; + + } else { + let d = this.grammar_.operand_kinds[data.kind]; + if (d === undefined) { + this.error_ = t.line + ": expected " + data.kind + " not found"; + return undefined; + } + + let val = d.values[t.data]["value"]; + let names = [t.data]; + if (d.type === "BitEnum") { + for(;;) { + let tmp = this.peek(0); + if (tmp.type !== TokenType.kPipe) { + break; + } + + this.next(); // skip pipe + tmp = this.next(); + + if (tmp.type !== TokenType.kIdentifier) { + this.error_ = tmp.line() + ": expected identifier"; + return undefined; + } + + val |= d.values[tmp.data]["value"]; + names.push(tmp.data); + } + } + + name = names.join("|"); + kind = d.type; + value = val; + + for (const op_name of names) { + if (d.values[op_name]['params'] === undefined) { + continue; + } + + for (const param of d.values[op_name]["params"]) { + params.push(this.extractOperand(ast, result_type, { kind: param })); + } + } + } + return new AST.Operand(ast, name, kind, value, params); + } +} diff --git a/3rdparty/spirv-tools/tools/sva/src/parser_test.js b/3rdparty/spirv-tools/tools/sva/src/parser_test.js new file mode 100644 index 000000000..e64aabd42 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/parser_test.js @@ -0,0 +1,464 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { assert } from "chai"; +import Lexer from "./lexer"; +import Parser from "./parser"; +import grammar from "./spirv.data.js"; + +describe("parser", () => { + it("parses an opcode", () => { + let input = "OpKill"; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpKill"); + assert.equal(inst.opcode(), 252); + assert.lengthOf(inst.operands, 0); + }); + + it("parses an opcode with an identifier", () => { + let input = "OpCapability Shader"; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpCapability"); + assert.equal(inst.opcode(), 17); + assert.lengthOf(inst.operands(), 1); + + let op = inst.operand(0); + assert.equal(op.name(), "Shader"); + assert.equal(op.type(), "ValueEnum"); + assert.equal(op.value(), 1); + }); + + it("parses an opcode with a result", () => { + let input = "%void = OpTypeVoid"; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpTypeVoid"); + assert.equal(inst.opcode(), 19); + assert.lengthOf(inst.operands(), 1); + + let op = inst.operand(0); + assert.equal(op.name(), "void"); + assert.equal(op.value(), 1); + }); + + it("sets module bounds based on numeric result", () => { + let input = "%3 = OpTypeVoid"; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.equal(ast.getId("next"), 4); + }); + + it("returns the same value for a named result_id", () => { + let input = "%3 = OpTypeFunction %int %int"; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + let op1 = inst.operand(1); + assert.equal(op1.name(), "int"); + assert.equal(op1.value(), 4); + + let op2 = inst.operand(2); + assert.equal(op2.name(), "int"); + assert.equal(op2.value(), 4); + }); + + it("parses an opcode with a string", () => { + let input = "OpEntryPoint Fragment %main \"main\""; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + let op = inst.operand(2); + assert.equal(op.name(), "main"); + assert.equal(op.value(), "main"); + }); + + describe("numerics", () => { + describe("integers", () => { + it("parses an opcode with an integer", () => { + let input = "OpSource GLSL 440"; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + let op0 = inst.operand(0); + assert.equal(op0.name(), "GLSL"); + assert.equal(op0.type(), "ValueEnum"); + assert.equal(op0.value(), 2); + + let op1 = inst.operand(1); + assert.equal(op1.name(), "440"); + assert.equal(op1.value(), 440); + }); + + it("parses an opcode with a hex integer", () => { + let input = "OpSource GLSL 0x440"; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + let op0 = inst.operand(0); + assert.equal(op0.name(), "GLSL"); + assert.equal(op0.type(), "ValueEnum"); + assert.equal(op0.value(), 2); + + let op1 = inst.operand(1); + assert.equal(op1.name(), "1088"); + assert.equal(op1.value(), 0x440); + }); + + it.skip("parses immediate integers", () => { + // TODO(dsinclair): Support or skip? + }); + }); + + describe("floats", () => { + it("parses floats", () => { + let input = `%float = OpTypeFloat 32 + %float1 = OpConstant %float 0.400000006`; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(1); + let op2 = inst.operand(2); + assert.equal(op2.value(), 0.400000006); + }); + + // TODO(dsinclair): Make hex encoded floats parse ... + it.skip("parses hex floats", () => { + let input = `%float = OpTypeFloat 32 + %nfloat = OpConstant %float -0.4p+2 + %pfloat = OpConstant %float 0.4p-2 + %inf = OpConstant %float32 0x1p+128 + %neginf = OpConstant %float32 -0x1p+128 + %aNaN = OpConstant %float32 0x1.8p+128 + %moreNaN = OpConstant %float32 -0x1.0002p+128`; + + let results = [-40.0, .004, 0x00000, 0x00000, 0x7fc00000, 0xff800100]; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + assert.lengthOf(ast.instructions(), 7); + + for (const idx in results) { + let inst = ast.instruction(idx); + let op2 = inst.operand(2); + assert.equal(op2.value(), results[idx]); + } + }); + + it("parses a float that looks like an int", () => { + let input = `%float = OpTypeFloat 32 + %float1 = OpConstant %float 1`; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(1); + let op2 = inst.operand(2); + assert.equal(op2.value(), 1); + assert.equal(op2.type(), "float"); + }); + }); + }); + + describe("enums", () => { + it("parses enum values", () => { + let input = `%1 = OpTypeFloat 32 + %30 = OpImageSampleExplicitLod %1 %20 %18 Grad|ConstOffset %22 %24 %29`; + + let vals = [{val: 1, name: "1"}, + {val: 30, name: "30"}, + {val: 20, name: "20"}, + {val: 18, name: "18"}, + {val: 12, name: "Grad|ConstOffset"}]; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(1); + for (let idx in vals) { + let op = inst.operand(idx); + assert.equal(op.name(), vals[idx].name); + assert.equal(op.value(), vals[idx].val); + } + + // BitEnum + let params = inst.operand(4).params(); + assert.lengthOf(params, 3); + assert.equal(params[0].name(), "22"); + assert.equal(params[0].value(), 22); + assert.equal(params[1].name(), "24"); + assert.equal(params[1].value(), 24); + assert.equal(params[2].name(), "29"); + assert.equal(params[2].value(), 29); + }); + + it("parses enumerants with parameters", () => { + let input ="OpExecutionMode %main LocalSize 2 3 4"; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpExecutionMode"); + assert.lengthOf(inst.operands(), 2); + assert.equal(inst.operand(0).name(), "main"); + assert.equal(inst.operand(1).name(), "LocalSize"); + + let params = inst.operand(1).params(); + assert.lengthOf(params, 3); + assert.equal(params[0].name(), "2"); + assert.equal(params[1].name(), "3"); + assert.equal(params[2].name(), "4"); + }); + }); + + it("parses result into second operand if needed", () => { + let input = `%int = OpTypeInt 32 1 + %int_3 = OpConstant %int 3`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(1); + assert.equal(inst.name(), "OpConstant"); + assert.equal(inst.opcode(), 43); + assert.lengthOf(inst.operands(), 3); + + let op0 = inst.operand(0); + assert.equal(op0.name(), "int"); + assert.equal(op0.value(), 1); + + let op1 = inst.operand(1); + assert.equal(op1.name(), "int_3"); + assert.equal(op1.value(), 2); + + let op2 = inst.operand(2); + assert.equal(op2.name(), "3"); + assert.equal(op2.value(), 3); + }); + + describe("quantifiers", () => { + describe("?", () => { + it("skips if missing", () => { + let input = `OpImageWrite %1 %2 %3 +OpKill`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpImageWrite"); + assert.lengthOf(inst.operands(), 3); + }); + + it("skips if missing at EOF", () => { + let input = "OpImageWrite %1 %2 %3"; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 1); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpImageWrite"); + assert.lengthOf(inst.operands(), 3); + }); + + it("extracts if available", () => { + let input = `OpImageWrite %1 %2 %3 ConstOffset %2 +OpKill`; + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpImageWrite"); + assert.lengthOf(inst.operands(), 4); + assert.equal(inst.operand(3).name(), "ConstOffset"); + }); + }); + + describe("*", () => { + it("skips if missing", () => { + let input = `OpEntryPoint Fragment %main "main" +OpKill`; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpEntryPoint"); + assert.lengthOf(inst.operands(), 3); + assert.equal(inst.operand(2).name(), "main"); + }); + + it("extracts one if available", () => { + let input = `OpEntryPoint Fragment %main "main" %2 +OpKill`; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpEntryPoint"); + assert.lengthOf(inst.operands(), 4); + assert.equal(inst.operand(3).name(), "2"); + }); + + it("extracts multiple if available", () => { + let input = `OpEntryPoint Fragment %main "main" %2 %3 %4 %5 +OpKill`; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(0); + assert.equal(inst.name(), "OpEntryPoint"); + assert.lengthOf(inst.operands(), 7); + assert.equal(inst.operand(3).name(), "2"); + assert.equal(inst.operand(4).name(), "3"); + assert.equal(inst.operand(5).name(), "4"); + assert.equal(inst.operand(6).name(), "5"); + }); + }); + }); + + describe("extended instructions", () => { + it("errors on non-glsl extensions", () => { + let input = "%1 = OpExtInstImport \"OpenCL.std.100\""; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + assert.isUndefined(p.parse()); + }); + + it("handles extended instructions", () => { + let input = `%1 = OpExtInstImport "GLSL.std.450" + %44 = OpExtInst %7 %1 Sqrt %43`; + + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + assert.exists(ast, p.error); + assert.lengthOf(ast.instructions(), 2); + + let inst = ast.instruction(1); + assert.lengthOf(inst.operands(), 5); + assert.equal(inst.operand(3).value(), 31); + assert.equal(inst.operand(3).name(), "Sqrt"); + assert.equal(inst.operand(4).value(), 43); + assert.equal(inst.operand(4).name(), "43"); + }); + }); + + it.skip("handles spec constant ops", () => { + // let input = "%sum = OpSpecConstantOp %i32 IAdd %a %b"; + }); + + it.skip("handles OpCopyMemory", () => { + // let input = "OpCopyMemory %1 %2 " + + // "Volatile|Nontemporal|MakePointerVisible %3 " + + // "Aligned|MakePointerAvailable|NonPrivatePointer 16 %4"; + }); +}); diff --git a/3rdparty/spirv-tools/tools/sva/src/spirv.data.js b/3rdparty/spirv-tools/tools/sva/src/spirv.data.js new file mode 100644 index 000000000..ba969d86b --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/spirv.data.js @@ -0,0 +1,4567 @@ +/*Copyright (c) 2014-2016 The Khronos Group Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and/or associated documentation files (the "Materials"), +to deal in the Materials without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Materials, and to permit persons to whom the +Materials are furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Materials. + +MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ + +THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +IN THE MATERIALS.*/ + +// THIS FILE IS GENERATED WITH tools/process_grammar.rb + +export default { + "magic": "0x07230203", + "version": [ + 1, + 5 + ], + "instructions": { + "OpNop": { + "opcode": 0, + "operands": [ + + ] + }, + "OpUndef": { + "opcode": 1, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + } + ] + }, + "OpSourceContinued": { + "opcode": 2, + "operands": [ + { + "kind": "LiteralString" + } + ] + }, + "OpSource": { + "opcode": 3, + "operands": [ + { + "kind": "SourceLanguage" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "IdRef", + "quantifier": "?" + }, + { + "kind": "LiteralString", + "quantifier": "?" + } + ] + }, + "OpSourceExtension": { + "opcode": 4, + "operands": [ + { + "kind": "LiteralString" + } + ] + }, + "OpName": { + "opcode": 5, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "LiteralString" + } + ] + }, + "OpMemberName": { + "opcode": 6, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "LiteralString" + } + ] + }, + "OpString": { + "opcode": 7, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralString" + } + ] + }, + "OpLine": { + "opcode": 8, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "LiteralInteger" + } + ] + }, + "OpExtension": { + "opcode": 10, + "operands": [ + { + "kind": "LiteralString" + } + ] + }, + "OpExtInstImport": { + "opcode": 11, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralString" + } + ] + }, + "OpExtInst": { + "opcode": 12, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralExtInstInteger" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpMemoryModel": { + "opcode": 14, + "operands": [ + { + "kind": "AddressingModel" + }, + { + "kind": "MemoryModel" + } + ] + }, + "OpEntryPoint": { + "opcode": 15, + "operands": [ + { + "kind": "ExecutionModel" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralString" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpExecutionMode": { + "opcode": 16, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "ExecutionMode" + } + ] + }, + "OpCapability": { + "opcode": 17, + "operands": [ + { + "kind": "Capability" + } + ] + }, + "OpTypeVoid": { + "opcode": 19, + "operands": [ + { + "kind": "IdResult" + } + ] + }, + "OpTypeBool": { + "opcode": 20, + "operands": [ + { + "kind": "IdResult" + } + ] + }, + "OpTypeInt": { + "opcode": 21, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "LiteralInteger" + } + ] + }, + "OpTypeFloat": { + "opcode": 22, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralInteger" + } + ] + }, + "OpTypeVector": { + "opcode": 23, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + } + ] + }, + "OpTypeMatrix": { + "opcode": 24, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + } + ] + }, + "OpTypeImage": { + "opcode": 25, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "Dim" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "ImageFormat" + }, + { + "kind": "AccessQualifier", + "quantifier": "?" + } + ] + }, + "OpTypeSampler": { + "opcode": 26, + "operands": [ + { + "kind": "IdResult" + } + ] + }, + "OpTypeSampledImage": { + "opcode": 27, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpTypeArray": { + "opcode": 28, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpTypeRuntimeArray": { + "opcode": 29, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpTypeStruct": { + "opcode": 30, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpTypePointer": { + "opcode": 32, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "StorageClass" + }, + { + "kind": "IdRef" + } + ] + }, + "OpTypeFunction": { + "opcode": 33, + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpConstantTrue": { + "opcode": 41, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + } + ] + }, + "OpConstantFalse": { + "opcode": 42, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + } + ] + }, + "OpConstant": { + "opcode": 43, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "LiteralContextDependentNumber" + } + ] + }, + "OpConstantComposite": { + "opcode": 44, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpConstantNull": { + "opcode": 46, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + } + ] + }, + "OpSpecConstantTrue": { + "opcode": 48, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + } + ] + }, + "OpSpecConstantFalse": { + "opcode": 49, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + } + ] + }, + "OpSpecConstant": { + "opcode": 50, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "LiteralContextDependentNumber" + } + ] + }, + "OpSpecConstantComposite": { + "opcode": 51, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpSpecConstantOp": { + "opcode": 52, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "LiteralSpecConstantOpInteger" + } + ] + }, + "OpFunction": { + "opcode": 54, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "FunctionControl" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFunctionParameter": { + "opcode": 55, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + } + ] + }, + "OpFunctionEnd": { + "opcode": 56, + "operands": [ + + ] + }, + "OpFunctionCall": { + "opcode": 57, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpVariable": { + "opcode": 59, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "StorageClass" + }, + { + "kind": "IdRef", + "quantifier": "?" + } + ] + }, + "OpImageTexelPointer": { + "opcode": 60, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpLoad": { + "opcode": 61, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "MemoryAccess", + "quantifier": "?" + } + ] + }, + "OpStore": { + "opcode": 62, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "MemoryAccess", + "quantifier": "?" + } + ] + }, + "OpCopyMemory": { + "opcode": 63, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "MemoryAccess", + "quantifier": "?" + }, + { + "kind": "MemoryAccess", + "quantifier": "?" + } + ] + }, + "OpAccessChain": { + "opcode": 65, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpInBoundsAccessChain": { + "opcode": 66, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpArrayLength": { + "opcode": 68, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + } + ] + }, + "OpDecorate": { + "opcode": 71, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "Decoration" + } + ] + }, + "OpMemberDecorate": { + "opcode": 72, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "Decoration" + } + ] + }, + "OpDecorationGroup": { + "opcode": 73, + "operands": [ + { + "kind": "IdResult" + } + ] + }, + "OpGroupDecorate": { + "opcode": 74, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpGroupMemberDecorate": { + "opcode": 75, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "PairIdRefLiteralInteger", + "quantifier": "*" + } + ] + }, + "OpVectorExtractDynamic": { + "opcode": 77, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpVectorInsertDynamic": { + "opcode": 78, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpVectorShuffle": { + "opcode": 79, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger", + "quantifier": "*" + } + ] + }, + "OpCompositeConstruct": { + "opcode": 80, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef", + "quantifier": "*" + } + ] + }, + "OpCompositeExtract": { + "opcode": 81, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger", + "quantifier": "*" + } + ] + }, + "OpCompositeInsert": { + "opcode": 82, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger", + "quantifier": "*" + } + ] + }, + "OpCopyObject": { + "opcode": 83, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpTranspose": { + "opcode": 84, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSampledImage": { + "opcode": 86, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpImageSampleImplicitLod": { + "opcode": 87, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageSampleExplicitLod": { + "opcode": 88, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands" + } + ] + }, + "OpImageSampleDrefImplicitLod": { + "opcode": 89, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageSampleDrefExplicitLod": { + "opcode": 90, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands" + } + ] + }, + "OpImageSampleProjImplicitLod": { + "opcode": 91, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageSampleProjExplicitLod": { + "opcode": 92, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands" + } + ] + }, + "OpImageSampleProjDrefImplicitLod": { + "opcode": 93, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageSampleProjDrefExplicitLod": { + "opcode": 94, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands" + } + ] + }, + "OpImageFetch": { + "opcode": 95, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageGather": { + "opcode": 96, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageDrefGather": { + "opcode": 97, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageRead": { + "opcode": 98, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImageWrite": { + "opcode": 99, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "ImageOperands", + "quantifier": "?" + } + ] + }, + "OpImage": { + "opcode": 100, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpImageQuerySizeLod": { + "opcode": 103, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpImageQuerySize": { + "opcode": 104, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpImageQueryLod": { + "opcode": 105, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpImageQueryLevels": { + "opcode": 106, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpImageQuerySamples": { + "opcode": 107, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpConvertFToU": { + "opcode": 109, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpConvertFToS": { + "opcode": 110, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpConvertSToF": { + "opcode": 111, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpConvertUToF": { + "opcode": 112, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpUConvert": { + "opcode": 113, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSConvert": { + "opcode": 114, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFConvert": { + "opcode": 115, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpQuantizeToF16": { + "opcode": 116, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitcast": { + "opcode": 124, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSNegate": { + "opcode": 126, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFNegate": { + "opcode": 127, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpIAdd": { + "opcode": 128, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFAdd": { + "opcode": 129, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpISub": { + "opcode": 130, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFSub": { + "opcode": 131, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpIMul": { + "opcode": 132, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFMul": { + "opcode": 133, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpUDiv": { + "opcode": 134, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSDiv": { + "opcode": 135, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFDiv": { + "opcode": 136, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpUMod": { + "opcode": 137, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSRem": { + "opcode": 138, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSMod": { + "opcode": 139, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFRem": { + "opcode": 140, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFMod": { + "opcode": 141, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpVectorTimesScalar": { + "opcode": 142, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpMatrixTimesScalar": { + "opcode": 143, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpVectorTimesMatrix": { + "opcode": 144, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpMatrixTimesVector": { + "opcode": 145, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpMatrixTimesMatrix": { + "opcode": 146, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpOuterProduct": { + "opcode": 147, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDot": { + "opcode": 148, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpIAddCarry": { + "opcode": 149, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpISubBorrow": { + "opcode": 150, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpUMulExtended": { + "opcode": 151, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSMulExtended": { + "opcode": 152, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAny": { + "opcode": 154, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAll": { + "opcode": 155, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpIsNan": { + "opcode": 156, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpIsInf": { + "opcode": 157, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpLogicalEqual": { + "opcode": 164, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpLogicalNotEqual": { + "opcode": 165, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpLogicalOr": { + "opcode": 166, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpLogicalAnd": { + "opcode": 167, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpLogicalNot": { + "opcode": 168, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSelect": { + "opcode": 169, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpIEqual": { + "opcode": 170, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpINotEqual": { + "opcode": 171, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpUGreaterThan": { + "opcode": 172, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSGreaterThan": { + "opcode": 173, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpUGreaterThanEqual": { + "opcode": 174, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSGreaterThanEqual": { + "opcode": 175, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpULessThan": { + "opcode": 176, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSLessThan": { + "opcode": 177, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpULessThanEqual": { + "opcode": 178, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpSLessThanEqual": { + "opcode": 179, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFOrdEqual": { + "opcode": 180, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFUnordEqual": { + "opcode": 181, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFOrdNotEqual": { + "opcode": 182, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFUnordNotEqual": { + "opcode": 183, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFOrdLessThan": { + "opcode": 184, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFUnordLessThan": { + "opcode": 185, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFOrdGreaterThan": { + "opcode": 186, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFUnordGreaterThan": { + "opcode": 187, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFOrdLessThanEqual": { + "opcode": 188, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFUnordLessThanEqual": { + "opcode": 189, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFOrdGreaterThanEqual": { + "opcode": 190, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFUnordGreaterThanEqual": { + "opcode": 191, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpShiftRightLogical": { + "opcode": 194, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpShiftRightArithmetic": { + "opcode": 195, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpShiftLeftLogical": { + "opcode": 196, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitwiseOr": { + "opcode": 197, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitwiseXor": { + "opcode": 198, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitwiseAnd": { + "opcode": 199, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpNot": { + "opcode": 200, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitFieldInsert": { + "opcode": 201, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitFieldSExtract": { + "opcode": 202, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitFieldUExtract": { + "opcode": 203, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitReverse": { + "opcode": 204, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpBitCount": { + "opcode": 205, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDPdx": { + "opcode": 207, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDPdy": { + "opcode": 208, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFwidth": { + "opcode": 209, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDPdxFine": { + "opcode": 210, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDPdyFine": { + "opcode": 211, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFwidthFine": { + "opcode": 212, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDPdxCoarse": { + "opcode": 213, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDPdyCoarse": { + "opcode": 214, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpFwidthCoarse": { + "opcode": 215, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpControlBarrier": { + "opcode": 224, + "operands": [ + { + "kind": "IdScope" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + } + ] + }, + "OpMemoryBarrier": { + "opcode": 225, + "operands": [ + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + } + ] + }, + "OpAtomicLoad": { + "opcode": 227, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + } + ] + }, + "OpAtomicStore": { + "opcode": 228, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicExchange": { + "opcode": 229, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicCompareExchange": { + "opcode": 230, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicIIncrement": { + "opcode": 232, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + } + ] + }, + "OpAtomicIDecrement": { + "opcode": 233, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + } + ] + }, + "OpAtomicIAdd": { + "opcode": 234, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicISub": { + "opcode": 235, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicSMin": { + "opcode": 236, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicUMin": { + "opcode": 237, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicSMax": { + "opcode": 238, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicUMax": { + "opcode": 239, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicAnd": { + "opcode": 240, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicOr": { + "opcode": 241, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpAtomicXor": { + "opcode": 242, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdScope" + }, + { + "kind": "IdMemorySemantics" + }, + { + "kind": "IdRef" + } + ] + }, + "OpPhi": { + "opcode": 245, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "PairIdRefIdRef", + "quantifier": "*" + } + ] + }, + "OpLoopMerge": { + "opcode": 246, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "LoopControl" + } + ] + }, + "OpSelectionMerge": { + "opcode": 247, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "SelectionControl" + } + ] + }, + "OpLabel": { + "opcode": 248, + "operands": [ + { + "kind": "IdResult" + } + ] + }, + "OpBranch": { + "opcode": 249, + "operands": [ + { + "kind": "IdRef" + } + ] + }, + "OpBranchConditional": { + "opcode": 250, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger", + "quantifier": "*" + } + ] + }, + "OpSwitch": { + "opcode": 251, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + }, + { + "kind": "PairLiteralIntegerIdRef", + "quantifier": "*" + } + ] + }, + "OpKill": { + "opcode": 252, + "operands": [ + + ] + }, + "OpReturn": { + "opcode": 253, + "operands": [ + + ] + }, + "OpReturnValue": { + "opcode": 254, + "operands": [ + { + "kind": "IdRef" + } + ] + }, + "OpUnreachable": { + "opcode": 255, + "operands": [ + + ] + }, + "OpNoLine": { + "opcode": 317, + "operands": [ + + ] + }, + "OpModuleProcessed": { + "opcode": 330, + "operands": [ + { + "kind": "LiteralString" + } + ] + }, + "OpExecutionModeId": { + "opcode": 331, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "ExecutionMode" + } + ] + }, + "OpDecorateId": { + "opcode": 332, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "Decoration" + } + ] + }, + "OpCopyLogical": { + "opcode": 400, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + } + ] + }, + "OpPtrEqual": { + "opcode": 401, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpPtrNotEqual": { + "opcode": 402, + "operands": [ + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "IdRef" + }, + { + "kind": "IdRef" + } + ] + }, + "OpDecorateString": { + "opcode": 5632, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "Decoration" + } + ] + }, + "OpDecorateStringGOOGLE": { + "opcode": 5632, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "Decoration" + } + ] + }, + "OpMemberDecorateString": { + "opcode": 5633, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "Decoration" + } + ] + }, + "OpMemberDecorateStringGOOGLE": { + "opcode": 5633, + "operands": [ + { + "kind": "IdRef" + }, + { + "kind": "LiteralInteger" + }, + { + "kind": "Decoration" + } + ] + } + }, + "operand_kinds": { + "ImageOperands": { + "type": "BitEnum", + "values": { + "None": { + "value": 0 + }, + "Bias": { + "value": 1, + "params": [ + "IdRef" + ] + }, + "Lod": { + "value": 2, + "params": [ + "IdRef" + ] + }, + "Grad": { + "value": 4, + "params": [ + "IdRef", + "IdRef" + ] + }, + "ConstOffset": { + "value": 8, + "params": [ + "IdRef" + ] + }, + "Sample": { + "value": 64, + "params": [ + "IdRef" + ] + }, + "MakeTexelAvailable": { + "value": 256, + "params": [ + "IdScope" + ] + }, + "MakeTexelAvailableKHR": { + "value": 256, + "params": [ + "IdScope" + ] + }, + "MakeTexelVisible": { + "value": 512, + "params": [ + "IdScope" + ] + }, + "MakeTexelVisibleKHR": { + "value": 512, + "params": [ + "IdScope" + ] + }, + "NonPrivateTexel": { + "value": 1024 + }, + "NonPrivateTexelKHR": { + "value": 1024 + }, + "VolatileTexel": { + "value": 2048 + }, + "VolatileTexelKHR": { + "value": 2048 + }, + "SignExtend": { + "value": 4096 + }, + "ZeroExtend": { + "value": 8192 + } + } + }, + "FPFastMathMode": { + "type": "BitEnum", + "values": { + "None": { + "value": 0 + } + } + }, + "SelectionControl": { + "type": "BitEnum", + "values": { + "None": { + "value": 0 + }, + "Flatten": { + "value": 1 + }, + "DontFlatten": { + "value": 2 + } + } + }, + "LoopControl": { + "type": "BitEnum", + "values": { + "None": { + "value": 0 + }, + "Unroll": { + "value": 1 + }, + "DontUnroll": { + "value": 2 + }, + "DependencyInfinite": { + "value": 4 + }, + "DependencyLength": { + "value": 8, + "params": [ + "LiteralInteger" + ] + }, + "MinIterations": { + "value": 16, + "params": [ + "LiteralInteger" + ] + }, + "MaxIterations": { + "value": 32, + "params": [ + "LiteralInteger" + ] + }, + "IterationMultiple": { + "value": 64, + "params": [ + "LiteralInteger" + ] + }, + "PeelCount": { + "value": 128, + "params": [ + "LiteralInteger" + ] + }, + "PartialCount": { + "value": 256, + "params": [ + "LiteralInteger" + ] + } + } + }, + "FunctionControl": { + "type": "BitEnum", + "values": { + "None": { + "value": 0 + }, + "Inline": { + "value": 1 + }, + "DontInline": { + "value": 2 + }, + "Pure": { + "value": 4 + }, + "Const": { + "value": 8 + } + } + }, + "MemorySemantics": { + "type": "BitEnum", + "values": { + "Relaxed": { + "value": 0 + }, + "None": { + "value": 0 + }, + "Acquire": { + "value": 2 + }, + "Release": { + "value": 4 + }, + "AcquireRelease": { + "value": 8 + }, + "SequentiallyConsistent": { + "value": 16 + }, + "UniformMemory": { + "value": 64 + }, + "SubgroupMemory": { + "value": 128 + }, + "WorkgroupMemory": { + "value": 256 + }, + "CrossWorkgroupMemory": { + "value": 512 + }, + "ImageMemory": { + "value": 2048 + }, + "OutputMemory": { + "value": 4096 + }, + "OutputMemoryKHR": { + "value": 4096 + }, + "MakeAvailable": { + "value": 8192 + }, + "MakeAvailableKHR": { + "value": 8192 + }, + "MakeVisible": { + "value": 16384 + }, + "MakeVisibleKHR": { + "value": 16384 + }, + "Volatile": { + "value": 32768 + } + } + }, + "MemoryAccess": { + "type": "BitEnum", + "values": { + "None": { + "value": 0 + }, + "Volatile": { + "value": 1 + }, + "Aligned": { + "value": 2, + "params": [ + "LiteralInteger" + ] + }, + "Nontemporal": { + "value": 4 + }, + "MakePointerAvailable": { + "value": 8, + "params": [ + "IdScope" + ] + }, + "MakePointerAvailableKHR": { + "value": 8, + "params": [ + "IdScope" + ] + }, + "MakePointerVisible": { + "value": 16, + "params": [ + "IdScope" + ] + }, + "MakePointerVisibleKHR": { + "value": 16, + "params": [ + "IdScope" + ] + }, + "NonPrivatePointer": { + "value": 32 + }, + "NonPrivatePointerKHR": { + "value": 32 + } + } + }, + "KernelProfilingInfo": { + "type": "BitEnum", + "values": { + "None": { + "value": 0 + } + } + }, + "SourceLanguage": { + "type": "ValueEnum", + "values": { + "Unknown": { + "value": 0 + }, + "ESSL": { + "value": 1 + }, + "GLSL": { + "value": 2 + }, + "OpenCL_C": { + "value": 3 + }, + "OpenCL_CPP": { + "value": 4 + }, + "HLSL": { + "value": 5 + } + } + }, + "ExecutionModel": { + "type": "ValueEnum", + "values": { + "Vertex": { + "value": 0 + }, + "Fragment": { + "value": 4 + }, + "GLCompute": { + "value": 5 + } + } + }, + "AddressingModel": { + "type": "ValueEnum", + "values": { + "Logical": { + "value": 0 + } + } + }, + "MemoryModel": { + "type": "ValueEnum", + "values": { + "Simple": { + "value": 0 + }, + "GLSL450": { + "value": 1 + }, + "Vulkan": { + "value": 3 + }, + "VulkanKHR": { + "value": 3 + } + } + }, + "ExecutionMode": { + "type": "ValueEnum", + "values": { + "PixelCenterInteger": { + "value": 6 + }, + "OriginUpperLeft": { + "value": 7 + }, + "OriginLowerLeft": { + "value": 8 + }, + "EarlyFragmentTests": { + "value": 9 + }, + "DepthReplacing": { + "value": 12 + }, + "DepthGreater": { + "value": 14 + }, + "DepthLess": { + "value": 15 + }, + "DepthUnchanged": { + "value": 16 + }, + "LocalSize": { + "value": 17, + "params": [ + "LiteralInteger", + "LiteralInteger", + "LiteralInteger" + ] + }, + "LocalSizeId": { + "value": 38, + "params": [ + "IdRef", + "IdRef", + "IdRef" + ] + } + } + }, + "StorageClass": { + "type": "ValueEnum", + "values": { + "UniformConstant": { + "value": 0 + }, + "Input": { + "value": 1 + }, + "Uniform": { + "value": 2 + }, + "Output": { + "value": 3 + }, + "Workgroup": { + "value": 4 + }, + "CrossWorkgroup": { + "value": 5 + }, + "Private": { + "value": 6 + }, + "Function": { + "value": 7 + }, + "PushConstant": { + "value": 9 + }, + "Image": { + "value": 11 + }, + "StorageBuffer": { + "value": 12 + } + } + }, + "Dim": { + "type": "ValueEnum", + "values": { + "1D": { + "value": 0 + }, + "2D": { + "value": 1 + }, + "3D": { + "value": 2 + }, + "Cube": { + "value": 3 + } + } + }, + "ImageFormat": { + "type": "ValueEnum", + "values": { + "Unknown": { + "value": 0 + }, + "Rgba32f": { + "value": 1 + }, + "Rgba16f": { + "value": 2 + }, + "R32f": { + "value": 3 + }, + "Rgba8": { + "value": 4 + }, + "Rgba8Snorm": { + "value": 5 + }, + "Rgba32i": { + "value": 21 + }, + "Rgba16i": { + "value": 22 + }, + "Rgba8i": { + "value": 23 + }, + "R32i": { + "value": 24 + }, + "Rgba32ui": { + "value": 30 + }, + "Rgba16ui": { + "value": 31 + }, + "Rgba8ui": { + "value": 32 + }, + "R32ui": { + "value": 33 + } + } + }, + "FPRoundingMode": { + "type": "ValueEnum", + "values": { + "RTE": { + "value": 0 + }, + "RTZ": { + "value": 1 + }, + "RTP": { + "value": 2 + }, + "RTN": { + "value": 3 + } + } + }, + "Decoration": { + "type": "ValueEnum", + "values": { + "RelaxedPrecision": { + "value": 0 + }, + "SpecId": { + "value": 1, + "params": [ + "LiteralInteger" + ] + }, + "Block": { + "value": 2 + }, + "BufferBlock": { + "value": 3 + }, + "RowMajor": { + "value": 4 + }, + "ColMajor": { + "value": 5 + }, + "ArrayStride": { + "value": 6, + "params": [ + "LiteralInteger" + ] + }, + "MatrixStride": { + "value": 7, + "params": [ + "LiteralInteger" + ] + }, + "GLSLShared": { + "value": 8 + }, + "GLSLPacked": { + "value": 9 + }, + "BuiltIn": { + "value": 11, + "params": [ + "BuiltIn" + ] + }, + "NoPerspective": { + "value": 13 + }, + "Flat": { + "value": 14 + }, + "Centroid": { + "value": 16 + }, + "Invariant": { + "value": 18 + }, + "Restrict": { + "value": 19 + }, + "Aliased": { + "value": 20 + }, + "Volatile": { + "value": 21 + }, + "Coherent": { + "value": 23 + }, + "NonWritable": { + "value": 24 + }, + "NonReadable": { + "value": 25 + }, + "Uniform": { + "value": 26 + }, + "UniformId": { + "value": 27, + "params": [ + "IdScope" + ] + }, + "Location": { + "value": 30, + "params": [ + "LiteralInteger" + ] + }, + "Component": { + "value": 31, + "params": [ + "LiteralInteger" + ] + }, + "Index": { + "value": 32, + "params": [ + "LiteralInteger" + ] + }, + "Binding": { + "value": 33, + "params": [ + "LiteralInteger" + ] + }, + "DescriptorSet": { + "value": 34, + "params": [ + "LiteralInteger" + ] + }, + "Offset": { + "value": 35, + "params": [ + "LiteralInteger" + ] + }, + "FPRoundingMode": { + "value": 39, + "params": [ + "FPRoundingMode" + ] + }, + "NoContraction": { + "value": 42 + }, + "NoSignedWrap": { + "value": 4469 + }, + "NoUnsignedWrap": { + "value": 4470 + }, + "ExplicitInterpAMD": { + "value": 4999 + }, + "CounterBuffer": { + "value": 5634, + "params": [ + "IdRef" + ] + }, + "HlslCounterBufferGOOGLE": { + "value": 5634, + "params": [ + "IdRef" + ] + }, + "UserSemantic": { + "value": 5635, + "params": [ + "LiteralString" + ] + }, + "HlslSemanticGOOGLE": { + "value": 5635, + "params": [ + "LiteralString" + ] + }, + "UserTypeGOOGLE": { + "value": 5636, + "params": [ + "LiteralString" + ] + } + } + }, + "BuiltIn": { + "type": "ValueEnum", + "values": { + "Position": { + "value": 0 + }, + "PointSize": { + "value": 1 + }, + "VertexId": { + "value": 5 + }, + "InstanceId": { + "value": 6 + }, + "FragCoord": { + "value": 15 + }, + "PointCoord": { + "value": 16 + }, + "FrontFacing": { + "value": 17 + }, + "SampleMask": { + "value": 20 + }, + "FragDepth": { + "value": 22 + }, + "HelperInvocation": { + "value": 23 + }, + "NumWorkgroups": { + "value": 24 + }, + "WorkgroupSize": { + "value": 25 + }, + "WorkgroupId": { + "value": 26 + }, + "LocalInvocationId": { + "value": 27 + }, + "GlobalInvocationId": { + "value": 28 + }, + "LocalInvocationIndex": { + "value": 29 + }, + "VertexIndex": { + "value": 42 + }, + "InstanceIndex": { + "value": 43 + }, + "BaryCoordNoPerspAMD": { + "value": 4992 + }, + "BaryCoordNoPerspCentroidAMD": { + "value": 4993 + }, + "BaryCoordNoPerspSampleAMD": { + "value": 4994 + }, + "BaryCoordSmoothAMD": { + "value": 4995 + }, + "BaryCoordSmoothCentroidAMD": { + "value": 4996 + }, + "BaryCoordSmoothSampleAMD": { + "value": 4997 + }, + "BaryCoordPullModelAMD": { + "value": 4998 + } + } + }, + "Scope": { + "type": "ValueEnum", + "values": { + "CrossDevice": { + "value": 0 + }, + "Device": { + "value": 1 + }, + "Workgroup": { + "value": 2 + }, + "Subgroup": { + "value": 3 + }, + "Invocation": { + "value": 4 + }, + "QueueFamily": { + "value": 5 + }, + "QueueFamilyKHR": { + "value": 5 + } + } + }, + "Capability": { + "type": "ValueEnum", + "values": { + "Matrix": { + "value": 0 + }, + "Shader": { + "value": 1 + }, + "Geometry": { + "value": 2 + }, + "Tessellation": { + "value": 3 + }, + "Addresses": { + "value": 4 + }, + "Linkage": { + "value": 5 + }, + "Kernel": { + "value": 6 + }, + "Float16": { + "value": 9 + }, + "Float64": { + "value": 10 + }, + "Int64": { + "value": 11 + }, + "Groups": { + "value": 18 + }, + "AtomicStorage": { + "value": 21 + }, + "Int16": { + "value": 22 + }, + "ImageGatherExtended": { + "value": 25 + }, + "StorageImageMultisample": { + "value": 27 + }, + "UniformBufferArrayDynamicIndexing": { + "value": 28 + }, + "SampledImageArrayDynamicIndexing": { + "value": 29 + }, + "StorageBufferArrayDynamicIndexing": { + "value": 30 + }, + "StorageImageArrayDynamicIndexing": { + "value": 31 + }, + "ClipDistance": { + "value": 32 + }, + "CullDistance": { + "value": 33 + }, + "SampleRateShading": { + "value": 35 + }, + "SampledRect": { + "value": 37 + }, + "Int8": { + "value": 39 + }, + "InputAttachment": { + "value": 40 + }, + "SparseResidency": { + "value": 41 + }, + "MinLod": { + "value": 42 + }, + "Sampled1D": { + "value": 43 + }, + "Image1D": { + "value": 44 + }, + "SampledCubeArray": { + "value": 45 + }, + "SampledBuffer": { + "value": 46 + }, + "ImageMSArray": { + "value": 48 + }, + "StorageImageExtendedFormats": { + "value": 49 + }, + "ImageQuery": { + "value": 50 + }, + "DerivativeControl": { + "value": 51 + }, + "InterpolationFunction": { + "value": 52 + }, + "TransformFeedback": { + "value": 53 + }, + "StorageImageReadWithoutFormat": { + "value": 55 + }, + "StorageImageWriteWithoutFormat": { + "value": 56 + }, + "GroupNonUniform": { + "value": 61 + }, + "ShaderLayer": { + "value": 69 + }, + "ShaderViewportIndex": { + "value": 70 + }, + "SubgroupBallotKHR": { + "value": 4423 + }, + "DrawParameters": { + "value": 4427 + }, + "SubgroupVoteKHR": { + "value": 4431 + }, + "StorageBuffer16BitAccess": { + "value": 4433 + }, + "StorageUniformBufferBlock16": { + "value": 4433 + }, + "StoragePushConstant16": { + "value": 4435 + }, + "StorageInputOutput16": { + "value": 4436 + }, + "DeviceGroup": { + "value": 4437 + }, + "MultiView": { + "value": 4439 + }, + "VariablePointersStorageBuffer": { + "value": 4441 + }, + "AtomicStorageOps": { + "value": 4445 + }, + "SampleMaskPostDepthCoverage": { + "value": 4447 + }, + "StorageBuffer8BitAccess": { + "value": 4448 + }, + "StoragePushConstant8": { + "value": 4450 + }, + "DenormPreserve": { + "value": 4464 + }, + "DenormFlushToZero": { + "value": 4465 + }, + "SignedZeroInfNanPreserve": { + "value": 4466 + }, + "RoundingModeRTE": { + "value": 4467 + }, + "RoundingModeRTZ": { + "value": 4468 + }, + "Float16ImageAMD": { + "value": 5008 + }, + "ImageGatherBiasLodAMD": { + "value": 5009 + }, + "FragmentMaskAMD": { + "value": 5010 + }, + "StencilExportEXT": { + "value": 5013 + }, + "ImageReadWriteLodAMD": { + "value": 5015 + }, + "ShaderClockKHR": { + "value": 5055 + }, + "FragmentFullyCoveredEXT": { + "value": 5265 + }, + "MeshShadingNV": { + "value": 5266 + }, + "ImageFootprintNV": { + "value": 5282 + }, + "FragmentBarycentricNV": { + "value": 5284 + }, + "ComputeDerivativeGroupQuadsNV": { + "value": 5288 + }, + "FragmentDensityEXT": { + "value": 5291 + }, + "ShadingRateNV": { + "value": 5291 + }, + "GroupNonUniformPartitionedNV": { + "value": 5297 + }, + "ShaderNonUniform": { + "value": 5301 + }, + "ShaderNonUniformEXT": { + "value": 5301 + }, + "RuntimeDescriptorArray": { + "value": 5302 + }, + "RuntimeDescriptorArrayEXT": { + "value": 5302 + }, + "RayTracingNV": { + "value": 5340 + }, + "VulkanMemoryModel": { + "value": 5345 + }, + "VulkanMemoryModelKHR": { + "value": 5345 + }, + "VulkanMemoryModelDeviceScope": { + "value": 5346 + }, + "VulkanMemoryModelDeviceScopeKHR": { + "value": 5346 + }, + "PhysicalStorageBufferAddresses": { + "value": 5347 + }, + "PhysicalStorageBufferAddressesEXT": { + "value": 5347 + }, + "ComputeDerivativeGroupLinearNV": { + "value": 5350 + }, + "CooperativeMatrixNV": { + "value": 5357 + }, + "FragmentShaderSampleInterlockEXT": { + "value": 5363 + }, + "FragmentShaderShadingRateInterlockEXT": { + "value": 5372 + }, + "ShaderSMBuiltinsNV": { + "value": 5373 + }, + "FragmentShaderPixelInterlockEXT": { + "value": 5378 + }, + "DemoteToHelperInvocationEXT": { + "value": 5379 + }, + "SubgroupShuffleINTEL": { + "value": 5568 + }, + "SubgroupBufferBlockIOINTEL": { + "value": 5569 + }, + "SubgroupImageBlockIOINTEL": { + "value": 5570 + }, + "SubgroupImageMediaBlockIOINTEL": { + "value": 5579 + }, + "IntegerFunctions2INTEL": { + "value": 5584 + }, + "SubgroupAvcMotionEstimationINTEL": { + "value": 5696 + }, + "SubgroupAvcMotionEstimationIntraINTEL": { + "value": 5697 + }, + "SubgroupAvcMotionEstimationChromaINTEL": { + "value": 5698 + } + } + } + }, + "ext": { + "Round": 1, + "RoundEven": 2, + "Trunc": 3, + "FAbs": 4, + "SAbs": 5, + "FSign": 6, + "SSign": 7, + "Floor": 8, + "Ceil": 9, + "Fract": 10, + "Radians": 11, + "Degrees": 12, + "Sin": 13, + "Cos": 14, + "Tan": 15, + "Asin": 16, + "Acos": 17, + "Atan": 18, + "Sinh": 19, + "Cosh": 20, + "Tanh": 21, + "Asinh": 22, + "Acosh": 23, + "Atanh": 24, + "Atan2": 25, + "Pow": 26, + "Exp": 27, + "Log": 28, + "Exp2": 29, + "Log2": 30, + "Sqrt": 31, + "InverseSqrt": 32, + "Determinant": 33, + "MatrixInverse": 34, + "Modf": 35, + "ModfStruct": 36, + "FMin": 37, + "UMin": 38, + "SMin": 39, + "FMax": 40, + "UMax": 41, + "SMax": 42, + "FClamp": 43, + "UClamp": 44, + "SClamp": 45, + "FMix": 46, + "IMix": 47, + "Step": 48, + "SmoothStep": 49, + "Fma": 50, + "Frexp": 51, + "FrexpStruct": 52, + "Ldexp": 53, + "PackSnorm4x8": 54, + "PackUnorm4x8": 55, + "PackSnorm2x16": 56, + "PackUnorm2x16": 57, + "PackHalf2x16": 58, + "PackDouble2x32": 59, + "UnpackSnorm2x16": 60, + "UnpackUnorm2x16": 61, + "UnpackHalf2x16": 62, + "UnpackSnorm4x8": 63, + "UnpackUnorm4x8": 64, + "UnpackDouble2x32": 65, + "Length": 66, + "Distance": 67, + "Cross": 68, + "Normalize": 69, + "FaceForward": 70, + "Reflect": 71, + "Refract": 72, + "FindILsb": 73, + "FindSMsb": 74, + "FindUMsb": 75, + "InterpolateAtCentroid": 76, + "InterpolateAtSample": 77, + "InterpolateAtOffset": 78, + "NMin": 79, + "NMax": 80, + "NClamp": 81 + } +} diff --git a/3rdparty/spirv-tools/tools/sva/src/sva.js b/3rdparty/spirv-tools/tools/sva/src/sva.js new file mode 100644 index 000000000..c76ed296e --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/sva.js @@ -0,0 +1,40 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Parser from "./parser.js"; +import Lexer from "./lexer.js"; +import Assembler from "./assembler.js"; + +import grammar from "./spirv.data.js"; + +export default class SVA { + /** + * Attempts to convert |input| SPIR-V assembly into SPIR-V binary. + * + * @param {String} the input string containing the assembly + * @return {Uint32Array|string} returns a Uint32Array containing the binary + * SPIR-V or a string on error. + */ + static assemble(input) { + let l = new Lexer(input); + let p = new Parser(grammar, l); + + let ast = p.parse(); + if (ast === undefined) + return p.error; + + let a = new Assembler(ast); + return a.assemble(); + } +} diff --git a/3rdparty/spirv-tools/tools/sva/src/token.js b/3rdparty/spirv-tools/tools/sva/src/token.js new file mode 100644 index 000000000..3813191dc --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/src/token.js @@ -0,0 +1,55 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const TokenType = { + kEOF: "end of file", + kError: "error", + + kIdentifier: "identifier", + + kIntegerLiteral: "integer_literal", + kFloatLiteral: "float_literal", + kStringLiteral: "string_literal", + kResultId: "result_id", + + kOp: "Op", + kEqual: "=", + kPipe: "|", +}; + +class Token { + /** + * @param {TokenType} type The type of token + * @param {Integer} line The line number this token was on + * @param {Any} data Data attached to the token + * @param {Integer} bits If the type is a float or integer the bit width + */ + constructor(type, line, data) { + this.type_ = type; + this.line_ = line; + this.data_ = data; + this.bits_ = 0; + } + + get type() { return this.type_; } + get line() { return this.line_; } + + get data() { return this.data_; } + set data(val) { this.data_ = val; } + + get bits() { return this.bits_; } + set bits(val) { this.bits_ = val; } +} + +export {Token, TokenType}; diff --git a/3rdparty/spirv-tools/tools/sva/tests/empty_main.spv_asm b/3rdparty/spirv-tools/tools/sva/tests/empty_main.spv_asm new file mode 100644 index 000000000..ad6e64b4f --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/tests/empty_main.spv_asm @@ -0,0 +1,18 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 7 +; Bound: 6 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 440 + OpName %main "main" + %void = OpTypeVoid + %3 = OpTypeFunction %void + %main = OpFunction %void None %3 + %5 = OpLabel + OpReturn + OpFunctionEnd diff --git a/3rdparty/spirv-tools/tools/sva/tests/index.html b/3rdparty/spirv-tools/tools/sva/tests/index.html new file mode 100644 index 000000000..dd028479b --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/tests/index.html @@ -0,0 +1,23 @@ + + + + + + +
+ + + + diff --git a/3rdparty/spirv-tools/tools/sva/tests/simple.spv_asm b/3rdparty/spirv-tools/tools/sva/tests/simple.spv_asm new file mode 100644 index 000000000..b4b3f6757 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/tests/simple.spv_asm @@ -0,0 +1,30 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 7 +; Bound: 14 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %gl_FragColor + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 330 + OpName %main "main" + OpName %gl_FragColor "gl_FragColor" + OpDecorate %gl_FragColor Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%gl_FragColor = OpVariable %_ptr_Output_v4float Output +%float_0_400000006 = OpConstant %float 0.400000006 +%float_0_800000012 = OpConstant %float 0.800000012 + %float_1 = OpConstant %float 1 + %13 = OpConstantComposite %v4float %float_0_400000006 %float_0_400000006 %float_0_800000012 %float_1 + %main = OpFunction %void None %3 + %5 = OpLabel + OpStore %gl_FragColor %13 + OpReturn + OpFunctionEnd + diff --git a/3rdparty/spirv-tools/tools/sva/tools/process_grammar.rb b/3rdparty/spirv-tools/tools/sva/tools/process_grammar.rb new file mode 100755 index 000000000..1bbff6862 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/tools/process_grammar.rb @@ -0,0 +1,119 @@ +#!/usr/bin/env ruby + +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'json' + +GRAMMAR = "../../external/spirv-headers/include/spirv/unified1/spirv.core.grammar.json" +GLSL = "../../external/spirv-headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json" + +CAPABILITIES = %w( + Matrix + Shader + Sampled1D + Image1D + DerivativeControl + ImageQuery + VulkanMemoryModel +) + +g = JSON.parse(File.open(GRAMMAR).read) +magic = g['magic_number'] +vers = [g['major_version'], g['minor_version']] +instructions = {} + +g['instructions'].each do |inst| + if (inst.has_key?('capabilities')) + skip = true + inst['capabilities'].each do |cap| + if CAPABILITIES.include?(cap) + skip = false + break + end + end + next if skip + end + + op = { + opcode: inst['opcode'], + operands: [] + } + + if !inst['operands'].nil? + inst['operands'].each do |operand| + operand.delete('name') + op[:operands] << operand + end + end + + instructions[inst['opname']] = op +end + +operand_kinds = {} +g['operand_kinds'].each do |op_kind| + next if op_kind['category'] !~ /Enum/ + + kind = { + type: op_kind['category'], + values: {} + } + + op_kind['enumerants'].each do |enum| + if (enum.has_key?('capabilities')) + skip = true + enum['capabilities'].each do |cap| + if CAPABILITIES.include?(cap) + skip = false + break + end + end + next if skip + end + + v = if op_kind['category'] == 'BitEnum' + enum['value'].to_i(16) + else + enum['value'].to_i + end + params = [] + if enum.has_key?('parameters') + enum['parameters'].each do |param| + params << param['kind'] + end + end + kind[:values][enum['enumerant']] = {value: v} + kind[:values][enum['enumerant']][:params] = params unless params.empty? + end + + next if kind[:values].empty? + operand_kinds[op_kind['kind']] = kind +end + +# We only support GLSL extensions at the moment. +ext = {} +glsl = JSON.parse(File.open(GLSL).read) +glsl['instructions'].each do |inst| + ext[inst['opname']] = inst['opcode'] +end + +puts "/*#{g['copyright'].join("\n")}*/" +puts "\n// THIS FILE IS GENERATED WITH tools/process_grammar.rb\n\n" +puts "export default " + JSON.pretty_generate({ + magic: magic, + version: vers, + instructions: instructions, + operand_kinds: operand_kinds, + ext: ext +}) diff --git a/3rdparty/spirv-tools/tools/sva/yarn.lock b/3rdparty/spirv-tools/tools/sva/yarn.lock new file mode 100644 index 000000000..be19e7ca6 --- /dev/null +++ b/3rdparty/spirv-tools/tools/sva/yarn.lock @@ -0,0 +1,1778 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" + integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/node@^12.7.5": + version "12.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" + integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== + +"@zeit/schemas@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.6.0.tgz#004e8e553b4cd53d538bd38eac7bcbf58a867fe3" + integrity sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg== + +accepts@~1.3.5: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-jsx@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" + integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== + +acorn@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.0.0.tgz#26b8d1cd9a9b700350b71c0905546f64d1284e7a" + integrity sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ== + +ajv@6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9" + integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^6.10.0, ajv@^6.10.2: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-colors@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +arch@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" + integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== + +arg@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arg/-/arg-2.0.0.tgz#c06e7ff69ab05b3a4a03ebe0407fac4cba657545" + integrity sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +boxen@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + +chalk@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +clipboardy@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-1.2.3.tgz#0526361bf78724c1f20be248d428e365433c07ef" + integrity sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA== + dependencies: + arch "^2.1.0" + execa "^0.8.0" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +compressible@~2.0.14: + version "2.0.17" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" + integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== + dependencies: + mime-db ">= 1.40.0 < 2" + +compression@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" + integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.14" + debug "2.6.9" + on-headers "~1.0.1" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +es-abstract@^1.5.1: + version "1.14.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497" + integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.0" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-inspect "^1.6.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.0.0" + string.prototype.trimright "^2.0.0" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" + integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== + dependencies: + eslint-visitor-keys "^1.0.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.3.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" + integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.2" + eslint-visitor-keys "^1.1.0" + espree "^6.1.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.4.1" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +espree@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" + integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== + dependencies: + acorn "^7.0.0" + acorn-jsx "^5.0.2" + eslint-visitor-keys "^1.1.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-url-parser@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" + integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0= + dependencies: + punycode "^1.3.2" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flat@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" + integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== + dependencies: + is-buffer "~2.0.3" + +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +glob-parent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" + integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== + dependencies: + is-glob "^4.0.1" + +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-fresh@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" + integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@^6.4.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +is-buffer@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.13.1, js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +log-symbols@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +"mime-db@>= 1.40.0 < 2": + version "1.41.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.41.0.tgz#9110408e1f6aa1b34aef51f2c9df3caddf46b6a0" + integrity sha512-B5gxBI+2K431XW8C2rcc/lhppbuji67nf9v39eH8pkWoZDxnAL0PxdpH32KYRScniF8qDHBDlI+ipgg5WrCUYw== + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== + +mime-types@2.1.18: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== + dependencies: + mime-db "~1.33.0" + +mime-types@~2.1.24: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + dependencies: + mime-db "1.40.0" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +mkdirp@0.5.1, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.0.tgz#f896b642843445d1bb8bca60eabd9206b8916e56" + integrity sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ== + dependencies: + ansi-colors "3.2.3" + browser-stdout "1.3.1" + debug "3.2.6" + diff "3.5.0" + escape-string-regexp "1.0.5" + find-up "3.0.0" + glob "7.1.3" + growl "1.10.5" + he "1.2.0" + js-yaml "3.13.1" + log-symbols "2.2.0" + minimatch "3.0.4" + mkdirp "0.5.1" + ms "2.1.1" + node-environment-flags "1.0.5" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "13.2.2" + yargs-parser "13.0.0" + yargs-unparser "1.5.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-environment-flags@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" + integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-inspect@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +on-headers@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-locale@^3.0.0, os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-to-regexp@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" + integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== + +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +range-parser@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +rc@^1.0.1, rc@^1.1.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +registry-auth-token@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rollup@^1.21.4: + version "1.21.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.21.4.tgz#00a41a30f90095db890301b226cbe2918e4cf54d" + integrity sha512-Pl512XVCmVzgcBz5h/3Li4oTaoDcmpuFZ+kdhS/wLreALz//WuDAMfomD3QEYl84NkDu6Z6wV9twlcREb4qQsw== + dependencies: + "@types/estree" "0.0.39" + "@types/node" "^12.7.5" + acorn "^7.0.0" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +rxjs@^6.4.0: + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.0.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.5.0, semver@^5.7.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.1.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +serve-handler@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.0.tgz#f1606dc6ff8f9029a1ee042c11dfe7903a5cb92e" + integrity sha512-63N075Tn3PsFYcu0NVV7tb367UbiW3gnC+/50ohL4oqOhAG6bmbaWqiRcXQgbzqc0ALBjSAzg7VTfa0Qw4E3hA== + dependencies: + bytes "3.0.0" + content-disposition "0.5.2" + fast-url-parser "1.1.3" + mime-types "2.1.18" + minimatch "3.0.4" + path-is-inside "1.0.2" + path-to-regexp "2.2.1" + range-parser "1.2.0" + +serve@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/serve/-/serve-11.1.0.tgz#1bfe2f4a08d0130cbf44711cdb7996cb742172e0" + integrity sha512-+4wpDtOSS+4ZLyDWMxThutA3iOTawX2+yDovOI8cjOUOmemyvNlHyFAsezBlSgbZKTYChI3tzA1Mh0z6XZ62qA== + dependencies: + "@zeit/schemas" "2.6.0" + ajv "6.5.3" + arg "2.0.0" + boxen "1.3.0" + chalk "2.4.1" + clipboardy "1.2.3" + compression "1.7.3" + serve-handler "6.1.0" + update-check "1.5.2" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.trimleft@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-json-comments@2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== + dependencies: + has-flag "^3.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tslib@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +update-check@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.2.tgz#2fe09f725c543440b3d7dabe8971f2d5caaedc28" + integrity sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ== + dependencies: + registry-auth-token "3.3.2" + registry-url "3.1.0" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1.3.1, which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yargs-parser@13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" + integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^13.0.0: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-unparser@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" + integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== + dependencies: + flat "^4.1.0" + lodash "^4.17.11" + yargs "^12.0.5" + +yargs@13.2.2: + version "13.2.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" + integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== + dependencies: + cliui "^4.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.0.0" + +yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" diff --git a/3rdparty/spirv-tools/tools/util/cli_consumer.h b/3rdparty/spirv-tools/tools/util/cli_consumer.h index ca3d91b95..64a5e46b8 100644 --- a/3rdparty/spirv-tools/tools/util/cli_consumer.h +++ b/3rdparty/spirv-tools/tools/util/cli_consumer.h @@ -15,7 +15,7 @@ #ifndef SOURCE_UTIL_CLI_CONSUMMER_H_ #define SOURCE_UTIL_CLI_CONSUMMER_H_ -#include +#include "include/spirv-tools/libspirv.h" namespace spvtools { namespace utils { diff --git a/3rdparty/spirv-tools/utils/check_copyright.py b/3rdparty/spirv-tools/utils/check_copyright.py index 5a95e3228..cfeef80a6 100755 --- a/3rdparty/spirv-tools/utils/check_copyright.py +++ b/3rdparty/spirv-tools/utils/check_copyright.py @@ -30,7 +30,8 @@ AUTHORS = ['The Khronos Group Inc.', 'LunarG Inc.', 'Google Inc.', 'Google LLC', - 'Pierre Moreau'] + 'Pierre Moreau', + 'Samsung Inc'] CURRENT_YEAR='2019' YEARS = '(2014-2016|2015-2016|2016|2016-2017|2017|2018|2019)'