mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated spirv-tools.
This commit is contained in:
@@ -1 +1 @@
|
||||
"v2020.6", "SPIRV-Tools v2020.6 25b32b391d8d2cf07c95edd7d164911cb00b4bc5"
|
||||
"v2020.6", "SPIRV-Tools v2020.6 fecfd7c6d825bb09bd025cbd64db0ecbef420f9a"
|
||||
|
||||
@@ -34,6 +34,8 @@ const char* ExtensionToString(Extension extension) {
|
||||
return "SPV_EXT_physical_storage_buffer";
|
||||
case Extension::kSPV_EXT_shader_atomic_float_add:
|
||||
return "SPV_EXT_shader_atomic_float_add";
|
||||
case Extension::kSPV_EXT_shader_image_int64:
|
||||
return "SPV_EXT_shader_image_int64";
|
||||
case Extension::kSPV_EXT_shader_stencil_export:
|
||||
return "SPV_EXT_shader_stencil_export";
|
||||
case Extension::kSPV_EXT_shader_viewport_index_layer:
|
||||
@@ -74,6 +76,8 @@ const char* ExtensionToString(Extension extension) {
|
||||
return "SPV_KHR_device_group";
|
||||
case Extension::kSPV_KHR_float_controls:
|
||||
return "SPV_KHR_float_controls";
|
||||
case Extension::kSPV_KHR_fragment_shading_rate:
|
||||
return "SPV_KHR_fragment_shading_rate";
|
||||
case Extension::kSPV_KHR_multiview:
|
||||
return "SPV_KHR_multiview";
|
||||
case Extension::kSPV_KHR_no_integer_wrap_decoration:
|
||||
@@ -143,8 +147,8 @@ const char* ExtensionToString(Extension extension) {
|
||||
|
||||
|
||||
bool GetExtensionFromString(const char* str, Extension* extension) {
|
||||
static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float_add", "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_blocking_pipes", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_kernel_attributes", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "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_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "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_atomic_float_add, 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_blocking_pipes, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, 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_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, 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_atomic_float_add", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_blocking_pipes", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_kernel_attributes", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_fragment_shading_rate", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "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_atomic_float_add, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, 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(
|
||||
@@ -298,6 +302,8 @@ const char* CapabilityToString(SpvCapability capability) {
|
||||
return "ShaderLayer";
|
||||
case SpvCapabilityShaderViewportIndex:
|
||||
return "ShaderViewportIndex";
|
||||
case SpvCapabilityFragmentShadingRateKHR:
|
||||
return "FragmentShadingRateKHR";
|
||||
case SpvCapabilitySubgroupBallotKHR:
|
||||
return "SubgroupBallotKHR";
|
||||
case SpvCapabilityDrawParameters:
|
||||
@@ -354,6 +360,8 @@ const char* CapabilityToString(SpvCapability capability) {
|
||||
return "StencilExportEXT";
|
||||
case SpvCapabilityImageReadWriteLodAMD:
|
||||
return "ImageReadWriteLodAMD";
|
||||
case SpvCapabilityInt64ImageEXT:
|
||||
return "Int64ImageEXT";
|
||||
case SpvCapabilityShaderClockKHR:
|
||||
return "ShaderClockKHR";
|
||||
case SpvCapabilitySampleMaskOverrideCoverageNV:
|
||||
|
||||
@@ -15,6 +15,7 @@ kSPV_EXT_fragment_invocation_density,
|
||||
kSPV_EXT_fragment_shader_interlock,
|
||||
kSPV_EXT_physical_storage_buffer,
|
||||
kSPV_EXT_shader_atomic_float_add,
|
||||
kSPV_EXT_shader_image_int64,
|
||||
kSPV_EXT_shader_stencil_export,
|
||||
kSPV_EXT_shader_viewport_index_layer,
|
||||
kSPV_GOOGLE_decorate_string,
|
||||
@@ -35,6 +36,7 @@ kSPV_KHR_16bit_storage,
|
||||
kSPV_KHR_8bit_storage,
|
||||
kSPV_KHR_device_group,
|
||||
kSPV_KHR_float_controls,
|
||||
kSPV_KHR_fragment_shading_rate,
|
||||
kSPV_KHR_multiview,
|
||||
kSPV_KHR_no_integer_wrap_decoration,
|
||||
kSPV_KHR_non_semantic_info,
|
||||
|
||||
@@ -19,6 +19,7 @@ static const SpvCapability pygen_variable_caps_FragmentFullyCoveredEXT[] = {SpvC
|
||||
static const SpvCapability pygen_variable_caps_FragmentShaderPixelInterlockEXT[] = {SpvCapabilityFragmentShaderPixelInterlockEXT};
|
||||
static const SpvCapability pygen_variable_caps_FragmentShaderSampleInterlockEXT[] = {SpvCapabilityFragmentShaderSampleInterlockEXT};
|
||||
static const SpvCapability pygen_variable_caps_FragmentShaderShadingRateInterlockEXT[] = {SpvCapabilityFragmentShaderShadingRateInterlockEXT};
|
||||
static const SpvCapability pygen_variable_caps_FragmentShadingRateKHR[] = {SpvCapabilityFragmentShadingRateKHR};
|
||||
static const SpvCapability pygen_variable_caps_FunctionPointersINTEL[] = {SpvCapabilityFunctionPointersINTEL};
|
||||
static const SpvCapability pygen_variable_caps_GenericPointer[] = {SpvCapabilityGenericPointer};
|
||||
static const SpvCapability pygen_variable_caps_Geometry[] = {SpvCapabilityGeometry};
|
||||
@@ -40,6 +41,7 @@ static const SpvCapability pygen_variable_caps_IndirectReferencesINTEL[] = {SpvC
|
||||
static const SpvCapability pygen_variable_caps_InputAttachment[] = {SpvCapabilityInputAttachment};
|
||||
static const SpvCapability pygen_variable_caps_InputAttachmentShaderNonUniform[] = {SpvCapabilityInputAttachment, SpvCapabilityShaderNonUniform};
|
||||
static const SpvCapability pygen_variable_caps_Int64[] = {SpvCapabilityInt64};
|
||||
static const SpvCapability pygen_variable_caps_Int64ImageEXT[] = {SpvCapabilityInt64ImageEXT};
|
||||
static const SpvCapability pygen_variable_caps_Kernel[] = {SpvCapabilityKernel};
|
||||
static const SpvCapability pygen_variable_caps_KernelGroupNonUniform[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniform};
|
||||
static const SpvCapability pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniform, SpvCapabilitySubgroupBallotKHR};
|
||||
@@ -109,6 +111,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_invocation
|
||||
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_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_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_image_int64[] = {spvtools::Extension::kSPV_EXT_shader_image_int64};
|
||||
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};
|
||||
@@ -128,6 +131,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_16bit_storage[] = {
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_8bit_storage[] = {spvtools::Extension::kSPV_KHR_8bit_storage};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_device_group[] = {spvtools::Extension::kSPV_KHR_device_group};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_float_controls[] = {spvtools::Extension::kSPV_KHR_float_controls};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_fragment_shading_rate[] = {spvtools::Extension::kSPV_KHR_fragment_shading_rate};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_multiview[] = {spvtools::Extension::kSPV_KHR_multiview};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration[] = {spvtools::Extension::kSPV_KHR_no_integer_wrap_decoration};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_post_depth_coverage[] = {spvtools::Extension::kSPV_KHR_post_depth_coverage};
|
||||
@@ -279,6 +283,13 @@ static const spv_operand_desc_t pygen_variable_RayFlagsEntries[] = {
|
||||
{"SkipAABBsKHR", 0x0200, 1, pygen_variable_caps_RayTraversalPrimitiveCullingProvisionalKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_FragmentShadingRateEntries[] = {
|
||||
{"Vertical2Pixels", 0x0001, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"Vertical4Pixels", 0x0002, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"Horizontal2Pixels", 0x0004, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"Horizontal4Pixels", 0x0008, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_SourceLanguageEntries[] = {
|
||||
{"Unknown", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"ESSL", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
@@ -485,7 +496,9 @@ static const spv_operand_desc_t pygen_variable_ImageFormatEntries[] = {
|
||||
{"Rg16ui", 36, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Rg8ui", 37, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"R16ui", 38, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"R8ui", 39, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"R8ui", 39, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"R64ui", 40, 1, pygen_variable_caps_Int64ImageEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"R64i", 41, 1, pygen_variable_caps_Int64ImageEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_ImageChannelOrderEntries[] = {
|
||||
@@ -700,8 +713,10 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
|
||||
{"BaseVertex", 4424, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
{"BaseInstance", 4425, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
{"DrawIndex", 4426, 2, pygen_variable_caps_DrawParametersMeshShadingNV, 2, pygen_variable_exts_SPV_KHR_shader_draw_parametersSPV_NV_mesh_shader, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
{"PrimitiveShadingRateKHR", 4432, 1, pygen_variable_caps_FragmentShadingRateKHR, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"DeviceIndex", 4438, 1, pygen_variable_caps_DeviceGroup, 1, pygen_variable_exts_SPV_KHR_device_group, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
{"ViewIndex", 4440, 1, pygen_variable_caps_MultiView, 1, pygen_variable_exts_SPV_KHR_multiview, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
{"ShadingRateKHR", 4444, 1, pygen_variable_caps_FragmentShadingRateKHR, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"BaryCoordNoPerspAMD", 4992, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"BaryCoordNoPerspCentroidAMD", 4993, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"BaryCoordNoPerspSampleAMD", 4994, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu},
|
||||
@@ -862,6 +877,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
|
||||
{"GroupNonUniformQuad", 68, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
{"ShaderLayer", 69, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
|
||||
{"ShaderViewportIndex", 70, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
|
||||
{"FragmentShadingRateKHR", 4422, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
{"SubgroupVoteKHR", 4431, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, {}, 0xffffffffu, 0xffffffffu},
|
||||
@@ -892,6 +908,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
|
||||
{"FragmentMaskAMD", 5010, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"StencilExportEXT", 5013, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ImageReadWriteLodAMD", 5015, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_image_load_store_lod, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"Int64ImageEXT", 5016, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_image_int64, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ShaderClockKHR", 5055, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_clock, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SampleMaskOverrideCoverageNV", 5249, 1, pygen_variable_caps_SampleRateShading, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"GeometryShaderPassthroughNV", 5251, 1, pygen_variable_caps_Geometry, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu},
|
||||
@@ -1110,6 +1127,7 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = {
|
||||
{SPV_OPERAND_TYPE_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries},
|
||||
{SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, ARRAY_SIZE(pygen_variable_KernelProfilingInfoEntries), pygen_variable_KernelProfilingInfoEntries},
|
||||
{SPV_OPERAND_TYPE_RAY_FLAGS, ARRAY_SIZE(pygen_variable_RayFlagsEntries), pygen_variable_RayFlagsEntries},
|
||||
{SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, ARRAY_SIZE(pygen_variable_FragmentShadingRateEntries), pygen_variable_FragmentShadingRateEntries},
|
||||
{SPV_OPERAND_TYPE_SOURCE_LANGUAGE, ARRAY_SIZE(pygen_variable_SourceLanguageEntries), pygen_variable_SourceLanguageEntries},
|
||||
{SPV_OPERAND_TYPE_EXECUTION_MODEL, ARRAY_SIZE(pygen_variable_ExecutionModelEntries), pygen_variable_ExecutionModelEntries},
|
||||
{SPV_OPERAND_TYPE_ADDRESSING_MODEL, ARRAY_SIZE(pygen_variable_AddressingModelEntries), pygen_variable_AddressingModelEntries},
|
||||
|
||||
@@ -176,12 +176,13 @@ typedef enum spv_operand_type_t {
|
||||
|
||||
// Set 5: Operands that are a single word bitmask.
|
||||
// Sometimes a set bit indicates the instruction requires still more operands.
|
||||
SPV_OPERAND_TYPE_IMAGE, // SPIR-V Sec 3.14
|
||||
SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, // SPIR-V Sec 3.15
|
||||
SPV_OPERAND_TYPE_SELECTION_CONTROL, // SPIR-V Sec 3.22
|
||||
SPV_OPERAND_TYPE_LOOP_CONTROL, // SPIR-V Sec 3.23
|
||||
SPV_OPERAND_TYPE_FUNCTION_CONTROL, // SPIR-V Sec 3.24
|
||||
SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26
|
||||
SPV_OPERAND_TYPE_IMAGE, // SPIR-V Sec 3.14
|
||||
SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, // SPIR-V Sec 3.15
|
||||
SPV_OPERAND_TYPE_SELECTION_CONTROL, // SPIR-V Sec 3.22
|
||||
SPV_OPERAND_TYPE_LOOP_CONTROL, // SPIR-V Sec 3.23
|
||||
SPV_OPERAND_TYPE_FUNCTION_CONTROL, // SPIR-V Sec 3.24
|
||||
SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26
|
||||
SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, // SPIR-V Sec 3.FSR
|
||||
|
||||
// The remaining operand types are only used internally by the assembler.
|
||||
// There are two categories:
|
||||
|
||||
@@ -536,28 +536,16 @@ Optimizer::PassToken CreateDeadInsertElimPass();
|
||||
// eliminated with standard dead code elimination.
|
||||
Optimizer::PassToken CreateAggressiveDCEPass();
|
||||
|
||||
// Create line propagation pass
|
||||
// This pass propagates line information based on the rules for OpLine and
|
||||
// OpNoline and clones an appropriate line instruction into every instruction
|
||||
// which does not already have debug line instructions.
|
||||
//
|
||||
// This pass is intended to maximize preservation of source line information
|
||||
// through passes which delete, move and clone instructions. Ideally it should
|
||||
// be run before any such pass. It is a bookend pass with EliminateDeadLines
|
||||
// which can be used to remove redundant line instructions at the end of a
|
||||
// run of such passes and reduce final output file size.
|
||||
// Creates an empty pass.
|
||||
// This is deprecated and will be removed.
|
||||
// TODO(jaebaek): remove this pass after handling glslang's broken unit tests.
|
||||
// https://github.com/KhronosGroup/glslang/pull/2440
|
||||
Optimizer::PassToken CreatePropagateLineInfoPass();
|
||||
|
||||
// Create dead line elimination pass
|
||||
// This pass eliminates redundant line instructions based on the rules for
|
||||
// OpLine and OpNoline. Its main purpose is to reduce the size of the file
|
||||
// need to store the SPIR-V without losing line information.
|
||||
//
|
||||
// This is a bookend pass with PropagateLines which attaches line instructions
|
||||
// to every instruction to preserve line information during passes which
|
||||
// delete, move and clone instructions. DeadLineElim should be run after
|
||||
// PropagateLines and all such subsequent passes. Normally it would be one
|
||||
// of the last passes to be run.
|
||||
// Creates an empty pass.
|
||||
// This is deprecated and will be removed.
|
||||
// TODO(jaebaek): remove this pass after handling glslang's broken unit tests.
|
||||
// https://github.com/KhronosGroup/glslang/pull/2440
|
||||
Optimizer::PassToken CreateRedundantLineInfoElimPass();
|
||||
|
||||
// Creates a compact ids pass.
|
||||
|
||||
70
3rdparty/spirv-tools/source/CMakeLists.txt
vendored
70
3rdparty/spirv-tools/source/CMakeLists.txt
vendored
@@ -346,58 +346,64 @@ set_source_files_properties(
|
||||
|
||||
spvtools_pch(SPIRV_SOURCES pch_source)
|
||||
|
||||
add_library(${SPIRV_TOOLS}-static STATIC ${SPIRV_SOURCES})
|
||||
spvtools_default_compile_options(${SPIRV_TOOLS}-static)
|
||||
target_include_directories(${SPIRV_TOOLS}-static
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE ${spirv-tools_BINARY_DIR}
|
||||
PRIVATE ${SPIRV_HEADER_INCLUDE_DIR}
|
||||
# spirv_tools_default_target_options() sets the target options that are common
|
||||
# for all ${SPIRV_TOOLS} targets.
|
||||
function(spirv_tools_default_target_options target)
|
||||
spvtools_default_compile_options(${target})
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE ${spirv-tools_BINARY_DIR}
|
||||
PRIVATE ${SPIRV_HEADER_INCLUDE_DIR}
|
||||
)
|
||||
set_property(TARGET ${SPIRV_TOOLS}-static PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||
spvtools_check_symbol_exports(${SPIRV_TOOLS}-static)
|
||||
add_dependencies(${SPIRV_TOOLS}-static core_tables enum_string_mapping extinst_tables)
|
||||
|
||||
# The static target does not have the '-static' suffix.
|
||||
set_target_properties(${SPIRV_TOOLS}-static PROPERTIES OUTPUT_NAME "${SPIRV_TOOLS}")
|
||||
set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||
spvtools_check_symbol_exports(${target})
|
||||
add_dependencies(${target} core_tables enum_string_mapping extinst_tables)
|
||||
endfunction()
|
||||
|
||||
# Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and
|
||||
# unlike the other SPIRV_TOOLS target, defaults to hidden symbol visibility.
|
||||
add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
|
||||
spvtools_default_compile_options(${SPIRV_TOOLS}-shared)
|
||||
target_include_directories(${SPIRV_TOOLS}-shared
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE ${spirv-tools_BINARY_DIR}
|
||||
PRIVATE ${SPIRV_HEADER_INCLUDE_DIR}
|
||||
)
|
||||
spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
|
||||
set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
set_property(TARGET ${SPIRV_TOOLS}-shared PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||
spvtools_check_symbol_exports(${SPIRV_TOOLS}-shared)
|
||||
target_compile_definitions(${SPIRV_TOOLS}-shared
|
||||
PRIVATE SPIRV_TOOLS_IMPLEMENTATION
|
||||
PUBLIC SPIRV_TOOLS_SHAREDLIB
|
||||
)
|
||||
add_dependencies(${SPIRV_TOOLS}-shared core_tables enum_string_mapping extinst_tables)
|
||||
|
||||
# Create the "${SPIRV_TOOLS}" target as an alias to either "${SPIRV_TOOLS}-static"
|
||||
# or "${SPIRV_TOOLS}-shared" depending on the value of BUILD_SHARED_LIBS.
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(SPIRV_TOOLS_BUILD_STATIC)
|
||||
add_library(${SPIRV_TOOLS}-static STATIC ${SPIRV_SOURCES})
|
||||
spirv_tools_default_target_options(${SPIRV_TOOLS}-static)
|
||||
# The static target does not have the '-static' suffix.
|
||||
set_target_properties(${SPIRV_TOOLS}-static PROPERTIES OUTPUT_NAME "${SPIRV_TOOLS}")
|
||||
|
||||
# Create the "${SPIRV_TOOLS}" target as an alias to either "${SPIRV_TOOLS}-static"
|
||||
# or "${SPIRV_TOOLS}-shared" depending on the value of BUILD_SHARED_LIBS.
|
||||
if(BUILD_SHARED_LIBS)
|
||||
add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-shared)
|
||||
else()
|
||||
else()
|
||||
add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-static)
|
||||
endif()
|
||||
|
||||
set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared)
|
||||
else()
|
||||
add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES})
|
||||
spirv_tools_default_target_options(${SPIRV_TOOLS})
|
||||
set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
find_library(LIBRT rt)
|
||||
if(LIBRT)
|
||||
target_link_libraries(${SPIRV_TOOLS}-static ${LIBRT})
|
||||
target_link_libraries(${SPIRV_TOOLS}-shared ${LIBRT})
|
||||
foreach(target ${SPIRV_TOOLS_TARGETS})
|
||||
target_link_libraries(${target} ${LIBRT})
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_SPIRV_TOOLS_INSTALL)
|
||||
install(TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared EXPORT ${SPIRV_TOOLS}Targets
|
||||
install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
2
3rdparty/spirv-tools/source/cfa.h
vendored
2
3rdparty/spirv-tools/source/cfa.h
vendored
@@ -127,7 +127,7 @@ class CFA {
|
||||
template <class BB>
|
||||
bool CFA<BB>::FindInWorkList(const std::vector<block_info>& work_list,
|
||||
uint32_t id) {
|
||||
for (auto& b : work_list) {
|
||||
for (const auto& b : work_list) {
|
||||
if (b.block->id() == id) return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# 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.
|
||||
add_library(SPIRV-Tools-link STATIC
|
||||
add_library(SPIRV-Tools-link ${SPIRV_TOOLS_LIBRARY_TYPE}
|
||||
linker.cpp
|
||||
)
|
||||
|
||||
|
||||
3
3rdparty/spirv-tools/source/operand.cpp
vendored
3
3rdparty/spirv-tools/source/operand.cpp
vendored
@@ -208,6 +208,8 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
|
||||
case SPV_OPERAND_TYPE_MEMORY_ACCESS:
|
||||
case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
|
||||
return "memory access";
|
||||
case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
|
||||
return "shading rate";
|
||||
case SPV_OPERAND_TYPE_SCOPE_ID:
|
||||
return "scope ID";
|
||||
case SPV_OPERAND_TYPE_GROUP_OPERATION:
|
||||
@@ -360,6 +362,7 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) {
|
||||
case SPV_OPERAND_TYPE_LOOP_CONTROL:
|
||||
case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
|
||||
case SPV_OPERAND_TYPE_MEMORY_ACCESS:
|
||||
case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
|
||||
case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
|
||||
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
|
||||
return true;
|
||||
|
||||
@@ -43,6 +43,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
|
||||
eliminate_dead_functions_pass.h
|
||||
eliminate_dead_functions_util.h
|
||||
eliminate_dead_members_pass.h
|
||||
empty_pass.h
|
||||
feature_manager.h
|
||||
fix_storage_class.h
|
||||
flatten_decoration_pass.h
|
||||
@@ -89,7 +90,6 @@ set(SPIRV_TOOLS_OPT_SOURCES
|
||||
pass.h
|
||||
pass_manager.h
|
||||
private_to_local_pass.h
|
||||
process_lines_pass.h
|
||||
propagator.h
|
||||
reduce_load_size.h
|
||||
redundancy_elimination.h
|
||||
@@ -196,7 +196,6 @@ set(SPIRV_TOOLS_OPT_SOURCES
|
||||
pass.cpp
|
||||
pass_manager.cpp
|
||||
private_to_local_pass.cpp
|
||||
process_lines_pass.cpp
|
||||
propagator.cpp
|
||||
reduce_load_size.cpp
|
||||
redundancy_elimination.cpp
|
||||
@@ -233,7 +232,7 @@ endif()
|
||||
|
||||
spvtools_pch(SPIRV_TOOLS_OPT_SOURCES pch_source_opt)
|
||||
|
||||
add_library(SPIRV-Tools-opt STATIC ${SPIRV_TOOLS_OPT_SOURCES})
|
||||
add_library(SPIRV-Tools-opt ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_OPT_SOURCES})
|
||||
|
||||
spvtools_default_compile_options(SPIRV-Tools-opt)
|
||||
target_include_directories(SPIRV-Tools-opt
|
||||
@@ -245,7 +244,7 @@ target_include_directories(SPIRV-Tools-opt
|
||||
)
|
||||
# We need the assembling and disassembling functionalities in the main library.
|
||||
target_link_libraries(SPIRV-Tools-opt
|
||||
PUBLIC ${SPIRV_TOOLS}-static)
|
||||
PUBLIC ${SPIRV_TOOLS_FULL_VISIBILITY})
|
||||
|
||||
set_property(TARGET SPIRV-Tools-opt PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||
spvtools_check_symbol_exports(SPIRV-Tools-opt)
|
||||
|
||||
25
3rdparty/spirv-tools/source/opt/ccp_pass.cpp
vendored
25
3rdparty/spirv-tools/source/opt/ccp_pass.cpp
vendored
@@ -135,23 +135,15 @@ SSAPropagator::PropStatus CCPPass::VisitAssignment(Instruction* instr) {
|
||||
}
|
||||
return it->second;
|
||||
};
|
||||
uint32_t next_id = context()->module()->IdBound();
|
||||
Instruction* folded_inst =
|
||||
context()->get_instruction_folder().FoldInstructionToConstant(instr,
|
||||
map_func);
|
||||
|
||||
if (folded_inst != nullptr) {
|
||||
// We do not want to change the body of the function by adding new
|
||||
// instructions. When folding we can only generate new constants.
|
||||
assert(folded_inst->IsConstant() && "CCP is only interested in constant.");
|
||||
values_[instr->result_id()] = folded_inst->result_id();
|
||||
|
||||
// If the folded instruction has just been created, its result ID will
|
||||
// match the previous ID bound. When this happens, we need to indicate
|
||||
// that CCP has modified the IR, independently of whether the constant is
|
||||
// actually propagated. See
|
||||
// https://github.com/KhronosGroup/SPIRV-Tools/issues/3636 for details.
|
||||
if (folded_inst->result_id() >= next_id) created_new_constant_ = true;
|
||||
|
||||
return SSAPropagator::kInteresting;
|
||||
}
|
||||
|
||||
@@ -278,10 +270,14 @@ bool CCPPass::ReplaceValues() {
|
||||
// Even if we make no changes to the function's IR, propagation may have
|
||||
// created new constants. Even if those constants cannot be replaced in
|
||||
// the IR, the constant definition itself is a change. To reflect this,
|
||||
// we initialize the IR changed indicator with the value of the
|
||||
// created_new_constant_ indicator. For an example, see the bug reported
|
||||
// in https://github.com/KhronosGroup/SPIRV-Tools/issues/3636.
|
||||
bool changed_ir = created_new_constant_;
|
||||
// we check whether the next ID to be given by the module is different than
|
||||
// the original bound ID. If that happens, new instructions were added to the
|
||||
// module during propagation.
|
||||
//
|
||||
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/3636 and
|
||||
// https://github.com/KhronosGroup/SPIRV-Tools/issues/3991 for details.
|
||||
bool changed_ir = (context()->module()->IdBound() > original_id_bound_);
|
||||
|
||||
for (const auto& it : values_) {
|
||||
uint32_t id = it.first;
|
||||
uint32_t cst_id = it.second;
|
||||
@@ -290,6 +286,7 @@ bool CCPPass::ReplaceValues() {
|
||||
changed_ir |= context()->ReplaceAllUsesWith(id, cst_id);
|
||||
}
|
||||
}
|
||||
|
||||
return changed_ir;
|
||||
}
|
||||
|
||||
@@ -329,7 +326,7 @@ void CCPPass::Initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
created_new_constant_ = false;
|
||||
original_id_bound_ = context()->module()->IdBound();
|
||||
}
|
||||
|
||||
Pass::Status CCPPass::Process() {
|
||||
|
||||
5
3rdparty/spirv-tools/source/opt/ccp_pass.h
vendored
5
3rdparty/spirv-tools/source/opt/ccp_pass.h
vendored
@@ -106,8 +106,9 @@ class CCPPass : public MemPass {
|
||||
// Propagator engine used.
|
||||
std::unique_ptr<SSAPropagator> propagator_;
|
||||
|
||||
// True if the pass created new constant instructions during propagation.
|
||||
bool created_new_constant_;
|
||||
// Value for the module's ID bound before running CCP. Used to detect whether
|
||||
// propagation created new instructions.
|
||||
uint32_t original_id_bound_;
|
||||
};
|
||||
|
||||
} // namespace opt
|
||||
|
||||
@@ -40,7 +40,6 @@ static const uint32_t kDebugLocalVariableOperandParentIndex = 9;
|
||||
static const uint32_t kExtInstInstructionInIdx = 1;
|
||||
static const uint32_t kDebugGlobalVariableOperandFlagsIndex = 12;
|
||||
static const uint32_t kDebugLocalVariableOperandFlagsIndex = 10;
|
||||
static const uint32_t kDebugLocalVariableOperandArgNumberIndex = 11;
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
@@ -441,32 +440,40 @@ bool DebugInfoManager::IsAncestorOfScope(uint32_t scope, uint32_t ancestor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Instruction* DebugInfoManager::GetDebugLocalVariableFromDeclare(
|
||||
Instruction* dbg_declare) {
|
||||
assert(dbg_declare);
|
||||
bool DebugInfoManager::IsDeclareVisibleToInstr(Instruction* dbg_declare,
|
||||
Instruction* scope) {
|
||||
assert(dbg_declare != nullptr);
|
||||
assert(scope != nullptr);
|
||||
|
||||
std::vector<uint32_t> scope_ids;
|
||||
if (scope->opcode() == SpvOpPhi) {
|
||||
scope_ids.push_back(scope->GetDebugScope().GetLexicalScope());
|
||||
for (uint32_t i = 0; i < scope->NumInOperands(); i += 2) {
|
||||
auto* value = context()->get_def_use_mgr()->GetDef(
|
||||
scope->GetSingleWordInOperand(i));
|
||||
if (value != nullptr)
|
||||
scope_ids.push_back(value->GetDebugScope().GetLexicalScope());
|
||||
}
|
||||
} else {
|
||||
scope_ids.push_back(scope->GetDebugScope().GetLexicalScope());
|
||||
}
|
||||
|
||||
uint32_t dbg_local_var_id =
|
||||
dbg_declare->GetSingleWordOperand(kDebugDeclareOperandLocalVariableIndex);
|
||||
auto dbg_local_var_itr = id_to_dbg_inst_.find(dbg_local_var_id);
|
||||
assert(dbg_local_var_itr != id_to_dbg_inst_.end());
|
||||
return dbg_local_var_itr->second;
|
||||
}
|
||||
|
||||
bool DebugInfoManager::IsFunctionParameter(Instruction* dbg_local_var) const {
|
||||
// If a DebugLocalVariable has ArgNumber operand, it is a function parameter.
|
||||
return dbg_local_var->NumOperands() >
|
||||
kDebugLocalVariableOperandArgNumberIndex;
|
||||
}
|
||||
|
||||
bool DebugInfoManager::IsLocalVariableVisibleToInstr(Instruction* dbg_local_var,
|
||||
uint32_t instr_scope_id) {
|
||||
if (instr_scope_id == kNoDebugScope) return false;
|
||||
|
||||
uint32_t decl_scope_id = dbg_local_var->GetSingleWordOperand(
|
||||
uint32_t decl_scope_id = dbg_local_var_itr->second->GetSingleWordOperand(
|
||||
kDebugLocalVariableOperandParentIndex);
|
||||
|
||||
// If the scope of DebugDeclare is an ancestor scope of the instruction's
|
||||
// scope, the local variable is visible to the instruction.
|
||||
return IsAncestorOfScope(instr_scope_id, decl_scope_id);
|
||||
for (uint32_t scope_id : scope_ids) {
|
||||
if (scope_id != kNoDebugScope &&
|
||||
IsAncestorOfScope(scope_id, decl_scope_id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Instruction* DebugInfoManager::AddDebugValueWithIndex(
|
||||
@@ -509,26 +516,21 @@ Instruction* DebugInfoManager::AddDebugValueWithIndex(
|
||||
|
||||
void DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
|
||||
Instruction* scope_and_line, uint32_t variable_id, uint32_t value_id,
|
||||
Instruction* insert_pos) {
|
||||
Instruction* insert_pos,
|
||||
std::unordered_set<Instruction*>* invisible_decls) {
|
||||
auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id);
|
||||
if (dbg_decl_itr == var_id_to_dbg_decl_.end()) return;
|
||||
|
||||
uint32_t instr_scope_id = scope_and_line->GetDebugScope().GetLexicalScope();
|
||||
for (auto* dbg_decl_or_val : dbg_decl_itr->second) {
|
||||
// If it declares a function parameter, the store instruction for the
|
||||
// function parameter can exist out of the function parameter's scope
|
||||
// because of the function inlining. We always add DebugValue for a
|
||||
// function parameter next to the DebugDeclare regardless of the scope.
|
||||
auto* dbg_local_var = GetDebugLocalVariableFromDeclare(dbg_decl_or_val);
|
||||
bool is_function_param = IsFunctionParameter(dbg_local_var);
|
||||
if (!is_function_param &&
|
||||
!IsLocalVariableVisibleToInstr(dbg_local_var, instr_scope_id))
|
||||
if (scope_and_line &&
|
||||
!IsDeclareVisibleToInstr(dbg_decl_or_val, scope_and_line)) {
|
||||
if (invisible_decls) invisible_decls->insert(dbg_decl_or_val);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Avoid inserting the new DebugValue between OpPhi or OpVariable
|
||||
// instructions.
|
||||
Instruction* insert_before = is_function_param ? dbg_decl_or_val->NextNode()
|
||||
: insert_pos->NextNode();
|
||||
Instruction* insert_before = insert_pos->NextNode();
|
||||
while (insert_before->opcode() == SpvOpPhi ||
|
||||
insert_before->opcode() == SpvOpVariable) {
|
||||
insert_before = insert_before->NextNode();
|
||||
@@ -545,12 +547,36 @@ void DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
|
||||
kDebugValueOperandLocalVariableIndex),
|
||||
value_id, 0, index_id, insert_before);
|
||||
assert(added_dbg_value != nullptr);
|
||||
added_dbg_value->UpdateDebugInfoFrom(is_function_param ? dbg_decl_or_val
|
||||
: scope_and_line);
|
||||
added_dbg_value->UpdateDebugInfoFrom(scope_and_line ? scope_and_line
|
||||
: dbg_decl_or_val);
|
||||
AnalyzeDebugInst(added_dbg_value);
|
||||
}
|
||||
}
|
||||
|
||||
bool DebugInfoManager::AddDebugValueForDecl(Instruction* dbg_decl,
|
||||
uint32_t value_id) {
|
||||
if (dbg_decl == nullptr || !IsDebugDeclare(dbg_decl)) return false;
|
||||
|
||||
std::unique_ptr<Instruction> dbg_val(dbg_decl->Clone(context()));
|
||||
dbg_val->SetResultId(context()->TakeNextId());
|
||||
dbg_val->SetInOperand(kExtInstInstructionInIdx,
|
||||
{OpenCLDebugInfo100DebugValue});
|
||||
dbg_val->SetOperand(kDebugDeclareOperandVariableIndex, {value_id});
|
||||
dbg_val->SetOperand(kDebugValueOperandExpressionIndex,
|
||||
{GetEmptyDebugExpression()->result_id()});
|
||||
|
||||
auto* added_dbg_val = dbg_decl->InsertBefore(std::move(dbg_val));
|
||||
AnalyzeDebugInst(added_dbg_val);
|
||||
if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse))
|
||||
context()->get_def_use_mgr()->AnalyzeInstDefUse(added_dbg_val);
|
||||
if (context()->AreAnalysesValid(
|
||||
IRContext::Analysis::kAnalysisInstrToBlockMapping)) {
|
||||
auto insert_blk = context()->get_instr_block(dbg_decl);
|
||||
context()->set_instr_block(added_dbg_val, insert_blk);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare(
|
||||
Instruction* inst) {
|
||||
if (inst->GetOpenCL100DebugOpcode() != OpenCLDebugInfo100DebugValue) return 0;
|
||||
|
||||
@@ -144,9 +144,11 @@ class DebugInfoManager {
|
||||
// Generates a DebugValue instruction with value |value_id| for every local
|
||||
// variable that is in the scope of |scope_and_line| and whose memory is
|
||||
// |variable_id| and inserts it after the instruction |insert_pos|.
|
||||
void AddDebugValueIfVarDeclIsVisible(Instruction* scope_and_line,
|
||||
uint32_t variable_id, uint32_t value_id,
|
||||
Instruction* insert_pos);
|
||||
// |invisible_decls| returns DebugDeclares invisible to |scope_and_line|.
|
||||
void AddDebugValueIfVarDeclIsVisible(
|
||||
Instruction* scope_and_line, uint32_t variable_id, uint32_t value_id,
|
||||
Instruction* insert_pos,
|
||||
std::unordered_set<Instruction*>* invisible_decls);
|
||||
|
||||
// Generates a DebugValue instruction with |dbg_local_var_id|, |value_id|,
|
||||
// |expr_id|, |index_id| operands and inserts it before |insert_before|.
|
||||
@@ -155,6 +157,11 @@ class DebugInfoManager {
|
||||
uint32_t index_id,
|
||||
Instruction* insert_before);
|
||||
|
||||
// Adds DebugValue for DebugDeclare |dbg_decl|. The new DebugValue has the
|
||||
// same line, scope, and operands but it uses |value_id| for value. Returns
|
||||
// weather it succeeds or not.
|
||||
bool AddDebugValueForDecl(Instruction* dbg_decl, uint32_t value_id);
|
||||
|
||||
// Erases |instr| from data structures of this class.
|
||||
void ClearDebugInfo(Instruction* instr);
|
||||
|
||||
@@ -215,17 +222,9 @@ class DebugInfoManager {
|
||||
// of |scope|.
|
||||
bool IsAncestorOfScope(uint32_t scope, uint32_t ancestor);
|
||||
|
||||
// Returns the DebugLocalVariable declared by |dbg_declare|.
|
||||
Instruction* GetDebugLocalVariableFromDeclare(Instruction* dbg_declare);
|
||||
|
||||
// Returns true if the DebugLocalVariable |dbg_local_var| is a function
|
||||
// parameter.
|
||||
bool IsFunctionParameter(Instruction* dbg_local_var) const;
|
||||
|
||||
// Returns true if the DebugLocalVariable |dbg_local_var| is visible
|
||||
// in the scope of an instruction |instr_scope_id|.
|
||||
bool IsLocalVariableVisibleToInstr(Instruction* dbg_local_var,
|
||||
uint32_t instr_scope_id);
|
||||
// Returns true if the declaration of a local variable |dbg_declare|
|
||||
// is visible in the scope of an instruction |instr_scope_id|.
|
||||
bool IsDeclareVisibleToInstr(Instruction* dbg_declare, Instruction* scope);
|
||||
|
||||
// Returns the parent scope of the scope |child_scope|.
|
||||
uint32_t GetParentScope(uint32_t child_scope);
|
||||
|
||||
36
3rdparty/spirv-tools/source/opt/empty_pass.h
vendored
Normal file
36
3rdparty/spirv-tools/source/opt/empty_pass.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2020 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_OPT_EMPTY_PASS_H_
|
||||
#define SOURCE_OPT_EMPTY_PASS_H_
|
||||
|
||||
#include "source/opt/pass.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
// Documented in optimizer.hpp
|
||||
class EmptyPass : public Pass {
|
||||
public:
|
||||
EmptyPass() {}
|
||||
|
||||
const char* name() const override { return "empty-pass"; }
|
||||
|
||||
Status Process() override { return Status::SuccessWithoutChange; }
|
||||
};
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_OPT_EMPTY_PASS_H_
|
||||
3
3rdparty/spirv-tools/source/opt/function.h
vendored
3
3rdparty/spirv-tools/source/opt/function.h
vendored
@@ -94,6 +94,9 @@ class Function {
|
||||
// Returns function's return type id
|
||||
inline uint32_t type_id() const { return def_inst_->type_id(); }
|
||||
|
||||
// Returns the function's control mask
|
||||
inline uint32_t control_mask() const { return def_inst_->GetSingleWordInOperand(0); }
|
||||
|
||||
// Returns the entry basic block for this function.
|
||||
const std::unique_ptr<BasicBlock>& entry() const { return blocks_.front(); }
|
||||
|
||||
|
||||
@@ -727,6 +727,12 @@ void InlinePass::AnalyzeReturns(Function* func) {
|
||||
bool InlinePass::IsInlinableFunction(Function* func) {
|
||||
// We can only inline a function if it has blocks.
|
||||
if (func->cbegin() == func->cend()) return false;
|
||||
|
||||
// Do not inline functions with DontInline flag.
|
||||
if (func->control_mask() & SpvFunctionControlDontInlineMask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do not inline functions with returns in loops. Currently early return
|
||||
// functions are inlined by wrapping them in a one trip loop and implementing
|
||||
// the returns as a branch to the loop's merge block. However, this can only
|
||||
|
||||
@@ -349,8 +349,9 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(ref_analysis* ref,
|
||||
: SpvDecorationArrayStride;
|
||||
uint32_t arr_stride = FindStride(curr_ty_id, stride_deco);
|
||||
uint32_t arr_stride_id = builder->GetUintConstantId(arr_stride);
|
||||
uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder);
|
||||
Instruction* curr_offset_inst = builder->AddBinaryOp(
|
||||
GetUintId(), SpvOpIMul, arr_stride_id, curr_idx_id);
|
||||
GetUintId(), SpvOpIMul, arr_stride_id, curr_idx_32b_id);
|
||||
curr_offset_id = curr_offset_inst->result_id();
|
||||
// Get element type for next step
|
||||
curr_ty_id = curr_ty_inst->GetSingleWordInOperand(0);
|
||||
@@ -360,8 +361,9 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(ref_analysis* ref,
|
||||
uint32_t comp_ty_id = curr_ty_inst->GetSingleWordInOperand(0u);
|
||||
uint32_t vec_stride = ByteSize(comp_ty_id);
|
||||
uint32_t vec_stride_id = builder->GetUintConstantId(vec_stride);
|
||||
uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder);
|
||||
Instruction* curr_offset_inst = builder->AddBinaryOp(
|
||||
GetUintId(), SpvOpIMul, vec_stride_id, curr_idx_id);
|
||||
GetUintId(), SpvOpIMul, vec_stride_id, curr_idx_32b_id);
|
||||
curr_offset_id = curr_offset_inst->result_id();
|
||||
// Get element type for next step
|
||||
curr_ty_id = comp_ty_id;
|
||||
@@ -434,18 +436,27 @@ void InstBindlessCheckPass::GenCheckCode(
|
||||
new_blk_ptr.reset(new BasicBlock(std::move(invalid_label)));
|
||||
builder.SetInsertPoint(&*new_blk_ptr);
|
||||
uint32_t u_index_id = GenUintCastCode(ref->desc_idx_id, &builder);
|
||||
if (offset_id != 0)
|
||||
if (offset_id != 0) {
|
||||
// Buffer OOB
|
||||
uint32_t u_offset_id = GenUintCastCode(offset_id, &builder);
|
||||
uint32_t u_length_id = GenUintCastCode(length_id, &builder);
|
||||
GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx,
|
||||
{error_id, u_index_id, offset_id, length_id}, &builder);
|
||||
else if (buffer_bounds_enabled_)
|
||||
// So all error modes will use same debug stream write function
|
||||
{error_id, u_index_id, u_offset_id, u_length_id},
|
||||
&builder);
|
||||
} else if (buffer_bounds_enabled_) {
|
||||
// Uninitialized Descriptor - Return additional unused zero so all error
|
||||
// modes will use same debug stream write function
|
||||
uint32_t u_length_id = GenUintCastCode(length_id, &builder);
|
||||
GenDebugStreamWrite(
|
||||
uid2offset_[ref->ref_inst->unique_id()], stage_idx,
|
||||
{error_id, u_index_id, length_id, builder.GetUintConstantId(0)},
|
||||
{error_id, u_index_id, u_length_id, builder.GetUintConstantId(0)},
|
||||
&builder);
|
||||
else
|
||||
} else {
|
||||
// Uninitialized Descriptor - Normal error return
|
||||
uint32_t u_length_id = GenUintCastCode(length_id, &builder);
|
||||
GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx,
|
||||
{error_id, u_index_id, length_id}, &builder);
|
||||
{error_id, u_index_id, u_length_id}, &builder);
|
||||
}
|
||||
// Remember last invalid block id
|
||||
uint32_t last_invalid_blk_id = new_blk_ptr->GetLabelInst()->result_id();
|
||||
// Gen zero for invalid reference
|
||||
@@ -516,8 +527,11 @@ void InstBindlessCheckPass::GenDescIdxCheckCode(
|
||||
// Generate full runtime bounds test code with true branch
|
||||
// being full reference and false branch being debug output and zero
|
||||
// for the referenced value.
|
||||
uint32_t desc_idx_32b_id = Gen32BitCvtCode(ref.desc_idx_id, &builder);
|
||||
uint32_t length_32b_id = Gen32BitCvtCode(length_id, &builder);
|
||||
Instruction* ult_inst = builder.AddBinaryOp(GetBoolId(), SpvOpULessThan,
|
||||
ref.desc_idx_id, length_id);
|
||||
desc_idx_32b_id, length_32b_id);
|
||||
ref.desc_idx_id = desc_idx_32b_id;
|
||||
GenCheckCode(ult_inst->result_id(), error_id, 0u, length_id, stage_idx, &ref,
|
||||
new_blocks);
|
||||
// Move original block's remaining code into remainder/merge block and add
|
||||
|
||||
@@ -527,7 +527,7 @@ void Instruction::UpdateDebugInfoFrom(const Instruction* from) {
|
||||
if (from == nullptr) return;
|
||||
clear_dbg_line_insts();
|
||||
if (!from->dbg_line_insts().empty())
|
||||
dbg_line_insts().push_back(from->dbg_line_insts()[0]);
|
||||
dbg_line_insts().push_back(from->dbg_line_insts().back());
|
||||
SetDebugScope(from->GetDebugScope());
|
||||
if (!IsDebugLineInst(opcode()) &&
|
||||
context()->AreAnalysesValid(IRContext::kAnalysisDebugInfo)) {
|
||||
|
||||
@@ -88,12 +88,36 @@ std::unique_ptr<Instruction> InstrumentPass::NewLabel(uint32_t label_id) {
|
||||
return newLabel;
|
||||
}
|
||||
|
||||
uint32_t InstrumentPass::Gen32BitCvtCode(uint32_t val_id,
|
||||
InstructionBuilder* builder) {
|
||||
// Convert integer value to 32-bit if necessary
|
||||
analysis::TypeManager* type_mgr = context()->get_type_mgr();
|
||||
uint32_t val_ty_id = get_def_use_mgr()->GetDef(val_id)->type_id();
|
||||
analysis::Integer* val_ty = type_mgr->GetType(val_ty_id)->AsInteger();
|
||||
if (val_ty->width() == 32) return val_id;
|
||||
bool is_signed = val_ty->IsSigned();
|
||||
analysis::Integer val_32b_ty(32, is_signed);
|
||||
analysis::Type* val_32b_reg_ty = type_mgr->GetRegisteredType(&val_32b_ty);
|
||||
uint32_t val_32b_reg_ty_id = type_mgr->GetId(val_32b_reg_ty);
|
||||
if (is_signed)
|
||||
return builder->AddUnaryOp(val_32b_reg_ty_id, SpvOpSConvert, val_id)
|
||||
->result_id();
|
||||
else
|
||||
return builder->AddUnaryOp(val_32b_reg_ty_id, SpvOpUConvert, val_id)
|
||||
->result_id();
|
||||
}
|
||||
|
||||
uint32_t InstrumentPass::GenUintCastCode(uint32_t val_id,
|
||||
InstructionBuilder* builder) {
|
||||
// Cast value to 32-bit unsigned if necessary
|
||||
if (get_def_use_mgr()->GetDef(val_id)->type_id() == GetUintId())
|
||||
return val_id;
|
||||
return builder->AddUnaryOp(GetUintId(), SpvOpBitcast, val_id)->result_id();
|
||||
// Convert value to 32-bit if necessary
|
||||
uint32_t val_32b_id = Gen32BitCvtCode(val_id, builder);
|
||||
// Cast value to unsigned if necessary
|
||||
analysis::TypeManager* type_mgr = context()->get_type_mgr();
|
||||
uint32_t val_ty_id = get_def_use_mgr()->GetDef(val_32b_id)->type_id();
|
||||
analysis::Integer* val_ty = type_mgr->GetType(val_ty_id)->AsInteger();
|
||||
if (!val_ty->IsSigned()) return val_32b_id;
|
||||
return builder->AddUnaryOp(GetUintId(), SpvOpBitcast, val_32b_id)
|
||||
->result_id();
|
||||
}
|
||||
|
||||
void InstrumentPass::GenDebugOutputFieldCode(uint32_t base_offset_id,
|
||||
|
||||
@@ -213,8 +213,12 @@ class InstrumentPass : public Pass {
|
||||
uint32_t GenDebugDirectRead(const std::vector<uint32_t>& offset_ids,
|
||||
InstructionBuilder* builder);
|
||||
|
||||
// Generate code to cast |value_id| to unsigned, if needed. Return
|
||||
// an id to the unsigned equivalent.
|
||||
// Generate code to convert integer |value_id| to 32bit, if needed. Return
|
||||
// an id to the 32bit equivalent.
|
||||
uint32_t Gen32BitCvtCode(uint32_t value_id, InstructionBuilder* builder);
|
||||
|
||||
// Generate code to cast integer |value_id| to 32bit unsigned, if needed.
|
||||
// Return an id to the Uint equivalent.
|
||||
uint32_t GenUintCastCode(uint32_t value_id, InstructionBuilder* builder);
|
||||
|
||||
// Return new label.
|
||||
|
||||
14
3rdparty/spirv-tools/source/opt/ir_loader.cpp
vendored
14
3rdparty/spirv-tools/source/opt/ir_loader.cpp
vendored
@@ -41,6 +41,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
++inst_index_;
|
||||
const auto opcode = static_cast<SpvOp>(inst->opcode);
|
||||
if (IsDebugLineInst(opcode)) {
|
||||
last_line_inst_.reset();
|
||||
dbg_line_info_.push_back(
|
||||
Instruction(module()->context(), *inst, last_dbg_scope_));
|
||||
return true;
|
||||
@@ -90,7 +91,16 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
|
||||
std::unique_ptr<Instruction> spv_inst(
|
||||
new Instruction(module()->context(), *inst, std::move(dbg_line_info_)));
|
||||
dbg_line_info_.clear();
|
||||
if (!spv_inst->dbg_line_insts().empty()) {
|
||||
if (spv_inst->dbg_line_insts().back().opcode() != SpvOpNoLine) {
|
||||
last_line_inst_ = std::unique_ptr<Instruction>(
|
||||
spv_inst->dbg_line_insts().back().Clone(module()->context()));
|
||||
}
|
||||
dbg_line_info_.clear();
|
||||
} else if (last_line_inst_ != nullptr) {
|
||||
last_line_inst_->SetDebugScope(last_dbg_scope_);
|
||||
spv_inst->dbg_line_insts().push_back(*last_line_inst_);
|
||||
}
|
||||
|
||||
const char* src = source_.c_str();
|
||||
spv_position_t loc = {inst_index_, 0, 0};
|
||||
@@ -141,6 +151,8 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
function_->AddBasicBlock(std::move(block_));
|
||||
block_ = nullptr;
|
||||
last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt);
|
||||
last_line_inst_.reset();
|
||||
dbg_line_info_.clear();
|
||||
} else {
|
||||
if (function_ == nullptr) { // Outside function definition
|
||||
SPIRV_ASSERT(consumer_, block_ == nullptr);
|
||||
|
||||
2
3rdparty/spirv-tools/source/opt/ir_loader.h
vendored
2
3rdparty/spirv-tools/source/opt/ir_loader.h
vendored
@@ -78,6 +78,8 @@ class IrLoader {
|
||||
std::unique_ptr<BasicBlock> block_;
|
||||
// Line related debug instructions accumulated thus far.
|
||||
std::vector<Instruction> dbg_line_info_;
|
||||
// Line instruction that should be applied to the next instruction.
|
||||
std::unique_ptr<Instruction> last_line_inst_;
|
||||
|
||||
// The last DebugScope information that IrLoader::AddInstruction() handled.
|
||||
DebugScope last_dbg_scope_;
|
||||
|
||||
@@ -149,8 +149,8 @@ bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
|
||||
const analysis::Type* store_type = var_type->AsPointer()->pointee_type();
|
||||
if (!(store_type->AsStruct() || store_type->AsArray())) {
|
||||
context()->get_debug_info_mgr()->AddDebugValueIfVarDeclIsVisible(
|
||||
store_inst, var_id, store_inst->GetSingleWordInOperand(1),
|
||||
store_inst);
|
||||
nullptr, var_id, store_inst->GetSingleWordInOperand(1), store_inst,
|
||||
nullptr);
|
||||
context()->get_debug_info_mgr()->KillDebugDeclares(var_id);
|
||||
}
|
||||
}
|
||||
|
||||
43
3rdparty/spirv-tools/source/opt/module.cpp
vendored
43
3rdparty/spirv-tools/source/opt/module.cpp
vendored
@@ -143,8 +143,38 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
|
||||
|
||||
size_t bound_idx = binary->size() - 2;
|
||||
DebugScope last_scope(kNoDebugScope, kNoInlinedAt);
|
||||
auto write_inst = [binary, skip_nop, &last_scope,
|
||||
this](const Instruction* i) {
|
||||
const Instruction* last_line_inst = nullptr;
|
||||
bool between_merge_and_branch = false;
|
||||
auto write_inst = [binary, skip_nop, &last_scope, &last_line_inst,
|
||||
&between_merge_and_branch, this](const Instruction* i) {
|
||||
// Skip emitting line instructions between merge and branch instructions.
|
||||
auto opcode = i->opcode();
|
||||
if (between_merge_and_branch &&
|
||||
(opcode == SpvOpLine || opcode == SpvOpNoLine)) {
|
||||
return;
|
||||
}
|
||||
between_merge_and_branch = false;
|
||||
if (last_line_inst != nullptr) {
|
||||
// If the current instruction is OpLine and it is the same with
|
||||
// the last line instruction that is still effective (can be applied
|
||||
// to the next instruction), we skip writing the current instruction.
|
||||
if (opcode == SpvOpLine) {
|
||||
uint32_t operand_index = 0;
|
||||
if (last_line_inst->WhileEachInOperand(
|
||||
[&operand_index, i](const uint32_t* word) {
|
||||
assert(i->NumInOperandWords() > operand_index);
|
||||
return *word == i->GetSingleWordInOperand(operand_index++);
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
} else if (opcode != SpvOpNoLine && i->dbg_line_insts().empty()) {
|
||||
// If the current instruction does not have the line information,
|
||||
// the last line information is not effective any more. Emit OpNoLine
|
||||
// to specify it.
|
||||
binary->push_back((1 << 16) | static_cast<uint16_t>(SpvOpNoLine));
|
||||
last_line_inst = nullptr;
|
||||
}
|
||||
}
|
||||
if (!(skip_nop && i->IsNop())) {
|
||||
const auto& scope = i->GetDebugScope();
|
||||
if (scope != last_scope) {
|
||||
@@ -157,6 +187,15 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
|
||||
|
||||
i->ToBinaryWithoutAttachedDebugInsts(binary);
|
||||
}
|
||||
// Update the last line instruction.
|
||||
if (IsTerminatorInst(opcode) || opcode == SpvOpNoLine) {
|
||||
last_line_inst = nullptr;
|
||||
} else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
|
||||
between_merge_and_branch = true;
|
||||
last_line_inst = nullptr;
|
||||
} else if (opcode == SpvOpLine) {
|
||||
last_line_inst = i;
|
||||
}
|
||||
};
|
||||
ForEachInst(write_inst, true);
|
||||
|
||||
|
||||
6
3rdparty/spirv-tools/source/opt/module.h
vendored
6
3rdparty/spirv-tools/source/opt/module.h
vendored
@@ -246,6 +246,12 @@ class Module {
|
||||
// If |skip_nop| is true and this is a OpNop, do nothing.
|
||||
void ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const;
|
||||
|
||||
// Pushes the binary segments for this instruction into the back of *|binary|
|
||||
// including all OpLine and OpNoLine even if we can skip emitting some line
|
||||
// instructions. If |skip_nop| is true and this is a OpNop, do nothing.
|
||||
void ToBinaryWithAllOpLines(std::vector<uint32_t>* binary,
|
||||
bool skip_nop) const;
|
||||
|
||||
// Returns 1 more than the maximum Id value mentioned in the module.
|
||||
uint32_t ComputeIdBound() const;
|
||||
|
||||
|
||||
10
3rdparty/spirv-tools/source/opt/optimizer.cpp
vendored
10
3rdparty/spirv-tools/source/opt/optimizer.cpp
vendored
@@ -339,10 +339,6 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
|
||||
RegisterPass(CreateDescriptorScalarReplacementPass());
|
||||
} else if (pass_name == "eliminate-dead-code-aggressive") {
|
||||
RegisterPass(CreateAggressiveDCEPass());
|
||||
} else if (pass_name == "propagate-line-info") {
|
||||
RegisterPass(CreatePropagateLineInfoPass());
|
||||
} else if (pass_name == "eliminate-redundant-line-info") {
|
||||
RegisterPass(CreateRedundantLineInfoElimPass());
|
||||
} else if (pass_name == "eliminate-insert-extract") {
|
||||
RegisterPass(CreateInsertExtractElimPass());
|
||||
} else if (pass_name == "eliminate-local-single-block") {
|
||||
@@ -758,13 +754,11 @@ Optimizer::PassToken CreateAggressiveDCEPass() {
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreatePropagateLineInfoPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::ProcessLinesPass>(opt::kLinesPropagateLines));
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(MakeUnique<opt::EmptyPass>());
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateRedundantLineInfoElimPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::ProcessLinesPass>(opt::kLinesEliminateDeadLines));
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(MakeUnique<opt::EmptyPass>());
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateCompactIdsPass() {
|
||||
|
||||
2
3rdparty/spirv-tools/source/opt/passes.h
vendored
2
3rdparty/spirv-tools/source/opt/passes.h
vendored
@@ -35,6 +35,7 @@
|
||||
#include "source/opt/eliminate_dead_constant_pass.h"
|
||||
#include "source/opt/eliminate_dead_functions_pass.h"
|
||||
#include "source/opt/eliminate_dead_members_pass.h"
|
||||
#include "source/opt/empty_pass.h"
|
||||
#include "source/opt/fix_storage_class.h"
|
||||
#include "source/opt/flatten_decoration_pass.h"
|
||||
#include "source/opt/fold_spec_constant_op_and_composite_pass.h"
|
||||
@@ -61,7 +62,6 @@
|
||||
#include "source/opt/merge_return_pass.h"
|
||||
#include "source/opt/null_pass.h"
|
||||
#include "source/opt/private_to_local_pass.h"
|
||||
#include "source/opt/process_lines_pass.h"
|
||||
#include "source/opt/reduce_load_size.h"
|
||||
#include "source/opt/redundancy_elimination.h"
|
||||
#include "source/opt/relax_float_ops_pass.h"
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
// Copyright (c) 2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2018 Valve Corporation
|
||||
// Copyright (c) 2018 LunarG 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 "source/opt/process_lines_pass.h"
|
||||
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// Input Operand Indices
|
||||
static const int kSpvLineFileInIdx = 0;
|
||||
static const int kSpvLineLineInIdx = 1;
|
||||
static const int kSpvLineColInIdx = 2;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
Pass::Status ProcessLinesPass::Process() {
|
||||
bool modified = ProcessLines();
|
||||
return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::ProcessLines() {
|
||||
bool modified = false;
|
||||
uint32_t file_id = 0;
|
||||
uint32_t line = 0;
|
||||
uint32_t col = 0;
|
||||
// Process types, globals, constants
|
||||
for (Instruction& inst : get_module()->types_values())
|
||||
modified |= line_process_func_(&inst, &file_id, &line, &col);
|
||||
// Process functions
|
||||
for (Function& function : *get_module()) {
|
||||
modified |= line_process_func_(&function.DefInst(), &file_id, &line, &col);
|
||||
function.ForEachParam(
|
||||
[this, &modified, &file_id, &line, &col](Instruction* param) {
|
||||
modified |= line_process_func_(param, &file_id, &line, &col);
|
||||
});
|
||||
for (BasicBlock& block : function) {
|
||||
modified |=
|
||||
line_process_func_(block.GetLabelInst(), &file_id, &line, &col);
|
||||
for (Instruction& inst : block) {
|
||||
modified |= line_process_func_(&inst, &file_id, &line, &col);
|
||||
// Don't process terminal instruction if preceeded by merge
|
||||
if (inst.opcode() == SpvOpSelectionMerge ||
|
||||
inst.opcode() == SpvOpLoopMerge)
|
||||
break;
|
||||
}
|
||||
// Nullify line info after each block.
|
||||
file_id = 0;
|
||||
}
|
||||
modified |= line_process_func_(function.EndInst(), &file_id, &line, &col);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::PropagateLine(Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
bool modified = false;
|
||||
// only the last debug instruction needs to be considered
|
||||
auto line_itr = inst->dbg_line_insts().rbegin();
|
||||
// if no line instructions, propagate previous info
|
||||
if (line_itr == inst->dbg_line_insts().rend()) {
|
||||
// if no current line info, add OpNoLine, else OpLine
|
||||
if (*file_id == 0)
|
||||
inst->dbg_line_insts().push_back(Instruction(context(), SpvOpNoLine));
|
||||
else
|
||||
inst->dbg_line_insts().push_back(Instruction(
|
||||
context(), SpvOpLine, 0, 0,
|
||||
{{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*file_id}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {*line}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {*col}}}));
|
||||
modified = true;
|
||||
} else {
|
||||
// else pre-existing line instruction, so update source line info
|
||||
if (line_itr->opcode() == SpvOpNoLine) {
|
||||
*file_id = 0;
|
||||
} else {
|
||||
assert(line_itr->opcode() == SpvOpLine && "unexpected debug inst");
|
||||
*file_id = line_itr->GetSingleWordInOperand(kSpvLineFileInIdx);
|
||||
*line = line_itr->GetSingleWordInOperand(kSpvLineLineInIdx);
|
||||
*col = line_itr->GetSingleWordInOperand(kSpvLineColInIdx);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::EliminateDeadLines(Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
// If no debug line instructions, return without modifying lines
|
||||
if (inst->dbg_line_insts().empty()) return false;
|
||||
// Only the last debug instruction needs to be considered; delete all others
|
||||
bool modified = inst->dbg_line_insts().size() > 1;
|
||||
Instruction last_inst = inst->dbg_line_insts().back();
|
||||
inst->dbg_line_insts().clear();
|
||||
// If last line is OpNoLine
|
||||
if (last_inst.opcode() == SpvOpNoLine) {
|
||||
// If no propagated line info, throw away redundant OpNoLine
|
||||
if (*file_id == 0) {
|
||||
modified = true;
|
||||
// Else replace OpNoLine and propagate no line info
|
||||
} else {
|
||||
inst->dbg_line_insts().push_back(last_inst);
|
||||
*file_id = 0;
|
||||
}
|
||||
} else {
|
||||
// Else last line is OpLine
|
||||
assert(last_inst.opcode() == SpvOpLine && "unexpected debug inst");
|
||||
// If propagated info matches last line, throw away last line
|
||||
if (*file_id == last_inst.GetSingleWordInOperand(kSpvLineFileInIdx) &&
|
||||
*line == last_inst.GetSingleWordInOperand(kSpvLineLineInIdx) &&
|
||||
*col == last_inst.GetSingleWordInOperand(kSpvLineColInIdx)) {
|
||||
modified = true;
|
||||
} else {
|
||||
// Else replace last line and propagate line info
|
||||
*file_id = last_inst.GetSingleWordInOperand(kSpvLineFileInIdx);
|
||||
*line = last_inst.GetSingleWordInOperand(kSpvLineLineInIdx);
|
||||
*col = last_inst.GetSingleWordInOperand(kSpvLineColInIdx);
|
||||
inst->dbg_line_insts().push_back(last_inst);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
ProcessLinesPass::ProcessLinesPass(uint32_t func_id) {
|
||||
if (func_id == kLinesPropagateLines) {
|
||||
line_process_func_ = [this](Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
return PropagateLine(inst, file_id, line, col);
|
||||
};
|
||||
} else {
|
||||
assert(func_id == kLinesEliminateDeadLines && "unknown Lines param");
|
||||
line_process_func_ = [this](Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
return EliminateDeadLines(inst, file_id, line, col);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright (c) 2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2018 Valve Corporation
|
||||
// Copyright (c) 2018 LunarG Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
||||
#define SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
||||
|
||||
#include "source/opt/function.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "source/opt/pass.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
namespace {
|
||||
|
||||
// Constructor Parameters
|
||||
static const int kLinesPropagateLines = 0;
|
||||
static const int kLinesEliminateDeadLines = 1;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// See optimizer.hpp for documentation.
|
||||
class ProcessLinesPass : public Pass {
|
||||
using LineProcessFunction =
|
||||
std::function<bool(Instruction*, uint32_t*, uint32_t*, uint32_t*)>;
|
||||
|
||||
public:
|
||||
ProcessLinesPass(uint32_t func_id);
|
||||
~ProcessLinesPass() override = default;
|
||||
|
||||
const char* name() const override { return "propagate-lines"; }
|
||||
|
||||
// See optimizer.hpp for this pass' user documentation.
|
||||
Status Process() override;
|
||||
|
||||
IRContext::Analysis GetPreservedAnalyses() override {
|
||||
return IRContext::kAnalysisDefUse |
|
||||
IRContext::kAnalysisInstrToBlockMapping |
|
||||
IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators |
|
||||
IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis |
|
||||
IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants |
|
||||
IRContext::kAnalysisTypes;
|
||||
}
|
||||
|
||||
private:
|
||||
// If |inst| has no debug line instruction, create one with
|
||||
// |file_id, line, col|. If |inst| has debug line instructions, set
|
||||
// |file_id, line, col| from the last. |file_id| equals 0 indicates no line
|
||||
// info is available. Return true if |inst| modified.
|
||||
bool PropagateLine(Instruction* inst, uint32_t* file_id, uint32_t* line,
|
||||
uint32_t* col);
|
||||
|
||||
// If last debug line instruction of |inst| matches |file_id, line, col|,
|
||||
// delete all debug line instructions of |inst|. If they do not match,
|
||||
// replace all debug line instructions of |inst| with new line instruction
|
||||
// set from |file_id, line, col|. If |inst| has no debug line instructions,
|
||||
// do not modify |inst|. |file_id| equals 0 indicates no line info is
|
||||
// available. Return true if |inst| modified.
|
||||
bool EliminateDeadLines(Instruction* inst, uint32_t* file_id, uint32_t* line,
|
||||
uint32_t* col);
|
||||
|
||||
// Apply lpfn() to all type, constant, global variable and function
|
||||
// instructions in their physical order.
|
||||
bool ProcessLines();
|
||||
|
||||
// A function that calls either PropagateLine or EliminateDeadLines.
|
||||
// Initialized by the class constructor.
|
||||
LineProcessFunction line_process_func_;
|
||||
};
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
||||
@@ -66,6 +66,7 @@ namespace opt {
|
||||
namespace {
|
||||
const uint32_t kStoreValIdInIdx = 1;
|
||||
const uint32_t kVariableInitIdInIdx = 1;
|
||||
const uint32_t kDebugDeclareOperandVariableIdx = 5;
|
||||
} // namespace
|
||||
|
||||
std::string SSARewriter::PhiCandidate::PrettyPrint(const CFG* cfg) const {
|
||||
@@ -241,8 +242,8 @@ uint32_t SSARewriter::AddPhiOperands(PhiCandidate* phi_candidate) {
|
||||
return repl_id;
|
||||
}
|
||||
|
||||
uint32_t SSARewriter::GetReachingDef(uint32_t var_id, BasicBlock* bb) {
|
||||
// If |var_id| has a definition in |bb|, return it.
|
||||
uint32_t SSARewriter::GetValueAtBlock(uint32_t var_id, BasicBlock* bb) {
|
||||
assert(bb != nullptr);
|
||||
const auto& bb_it = defs_at_block_.find(bb);
|
||||
if (bb_it != defs_at_block_.end()) {
|
||||
const auto& current_defs = bb_it->second;
|
||||
@@ -251,9 +252,15 @@ uint32_t SSARewriter::GetReachingDef(uint32_t var_id, BasicBlock* bb) {
|
||||
return var_it->second;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t SSARewriter::GetReachingDef(uint32_t var_id, BasicBlock* bb) {
|
||||
// If |var_id| has a definition in |bb|, return it.
|
||||
uint32_t val_id = GetValueAtBlock(var_id, bb);
|
||||
if (val_id != 0) return val_id;
|
||||
|
||||
// Otherwise, look up the value for |var_id| in |bb|'s predecessors.
|
||||
uint32_t val_id = 0;
|
||||
auto& predecessors = pass_->cfg()->preds(bb->id());
|
||||
if (predecessors.size() == 1) {
|
||||
// If |bb| has exactly one predecessor, we look for |var_id|'s definition
|
||||
@@ -308,7 +315,7 @@ void SSARewriter::ProcessStore(Instruction* inst, BasicBlock* bb) {
|
||||
if (pass_->IsTargetVar(var_id)) {
|
||||
WriteVariable(var_id, bb, val_id);
|
||||
pass_->context()->get_debug_info_mgr()->AddDebugValueIfVarDeclIsVisible(
|
||||
inst, var_id, val_id, inst);
|
||||
inst, var_id, val_id, inst, &decls_invisible_to_value_assignment_);
|
||||
|
||||
#if SSA_REWRITE_DEBUGGING_LEVEL > 1
|
||||
std::cerr << "\tFound store '%" << var_id << " = %" << val_id << "': "
|
||||
@@ -439,8 +446,6 @@ bool SSARewriter::ApplyReplacements() {
|
||||
|
||||
// Add Phi instructions from completed Phi candidates.
|
||||
std::vector<Instruction*> generated_phis;
|
||||
// Add DebugValue instructions for Phi instructions.
|
||||
std::vector<Instruction*> dbg_values_for_phis;
|
||||
for (const PhiCandidate* phi_candidate : phis_to_generate_) {
|
||||
#if SSA_REWRITE_DEBUGGING_LEVEL > 2
|
||||
std::cerr << "Phi candidate: " << phi_candidate->PrettyPrint(pass_->cfg())
|
||||
@@ -493,7 +498,7 @@ bool SSARewriter::ApplyReplacements() {
|
||||
insert_it->SetDebugScope(local_var->GetDebugScope());
|
||||
pass_->context()->get_debug_info_mgr()->AddDebugValueIfVarDeclIsVisible(
|
||||
&*insert_it, phi_candidate->var_id(), phi_candidate->result_id(),
|
||||
&*insert_it);
|
||||
&*insert_it, &decls_invisible_to_value_assignment_);
|
||||
|
||||
modified = true;
|
||||
}
|
||||
@@ -581,6 +586,61 @@ void SSARewriter::FinalizePhiCandidates() {
|
||||
}
|
||||
}
|
||||
|
||||
Pass::Status SSARewriter::AddDebugValuesForInvisibleDebugDecls(Function* fp) {
|
||||
// For the cases the value assignment is invisible to DebugDeclare e.g.,
|
||||
// the argument passing for an inlined function.
|
||||
//
|
||||
// Before inlining foo(int x):
|
||||
// a = 3;
|
||||
// foo(3);
|
||||
// After inlining:
|
||||
// a = 3; // we want to specify "DebugValue: %x = %int_3"
|
||||
// foo and x disappeared!
|
||||
//
|
||||
// We want to specify the value for the variable using |defs_at_block_[bb]|,
|
||||
// where |bb| is the basic block contains the decl.
|
||||
DominatorAnalysis* dom_tree = pass_->context()->GetDominatorAnalysis(fp);
|
||||
Pass::Status status = Pass::Status::SuccessWithoutChange;
|
||||
for (auto* decl : decls_invisible_to_value_assignment_) {
|
||||
uint32_t var_id =
|
||||
decl->GetSingleWordOperand(kDebugDeclareOperandVariableIdx);
|
||||
auto* var = pass_->get_def_use_mgr()->GetDef(var_id);
|
||||
if (var->opcode() == SpvOpFunctionParameter) continue;
|
||||
|
||||
auto* bb = pass_->context()->get_instr_block(decl);
|
||||
uint32_t value_id = GetValueAtBlock(var_id, bb);
|
||||
Instruction* value = nullptr;
|
||||
if (value_id) value = pass_->get_def_use_mgr()->GetDef(value_id);
|
||||
|
||||
// If |value| is defined before the function body, it dominates |decl|.
|
||||
// If |value| dominates |decl|, we can set it as DebugValue.
|
||||
if (value && (pass_->context()->get_instr_block(value) == nullptr ||
|
||||
dom_tree->Dominates(value, decl))) {
|
||||
if (!pass_->context()->get_debug_info_mgr()->AddDebugValueForDecl(
|
||||
decl, value->result_id())) {
|
||||
return Pass::Status::Failure;
|
||||
}
|
||||
} else {
|
||||
// If |value| in the same basic block does not dominate |decl|, we can
|
||||
// assign the value in the immediate dominator.
|
||||
value_id = GetValueAtBlock(var_id, dom_tree->ImmediateDominator(bb));
|
||||
if (value_id &&
|
||||
!pass_->context()->get_debug_info_mgr()->AddDebugValueForDecl(
|
||||
decl, value_id)) {
|
||||
return Pass::Status::Failure;
|
||||
}
|
||||
}
|
||||
|
||||
// DebugDeclares of target variables will be removed by
|
||||
// SSARewritePass::Process().
|
||||
if (!pass_->IsTargetVar(var_id)) {
|
||||
pass_->context()->get_debug_info_mgr()->KillDebugDeclares(var_id);
|
||||
}
|
||||
status = Pass::Status::SuccessWithChange;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
Pass::Status SSARewriter::RewriteFunctionIntoSSA(Function* fp) {
|
||||
#if SSA_REWRITE_DEBUGGING_LEVEL > 0
|
||||
std::cerr << "Function before SSA rewrite:\n"
|
||||
@@ -610,6 +670,12 @@ Pass::Status SSARewriter::RewriteFunctionIntoSSA(Function* fp) {
|
||||
// Finally, apply all the replacements in the IR.
|
||||
bool modified = ApplyReplacements();
|
||||
|
||||
auto status = AddDebugValuesForInvisibleDebugDecls(fp);
|
||||
if (status == Pass::Status::SuccessWithChange ||
|
||||
status == Pass::Status::Failure) {
|
||||
return status;
|
||||
}
|
||||
|
||||
#if SSA_REWRITE_DEBUGGING_LEVEL > 0
|
||||
std::cerr << "\n\n\nFunction after SSA rewrite:\n"
|
||||
<< fp->PrettyPrint(0) << "\n";
|
||||
|
||||
@@ -192,6 +192,10 @@ class SSARewriter {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the value of |var_id| at |bb| if |defs_at_block_| contains it.
|
||||
// Otherwise, returns 0.
|
||||
uint32_t GetValueAtBlock(uint32_t var_id, BasicBlock* bb);
|
||||
|
||||
// Processes the store operation |inst| in basic block |bb|. This extracts
|
||||
// the variable ID being stored into, determines whether the variable is an
|
||||
// SSA-target variable, and, if it is, it stores its value in the
|
||||
@@ -249,6 +253,11 @@ class SSARewriter {
|
||||
// candidates.
|
||||
void FinalizePhiCandidates();
|
||||
|
||||
// Adds DebugValues for DebugDeclares in
|
||||
// |decls_invisible_to_value_assignment_|. Returns whether the function was
|
||||
// modified or not, and whether or not the conversion was successful.
|
||||
Pass::Status AddDebugValuesForInvisibleDebugDecls(Function* fp);
|
||||
|
||||
// Prints the table of Phi candidates to std::cerr.
|
||||
void PrintPhiCandidates() const;
|
||||
|
||||
@@ -286,6 +295,10 @@ class SSARewriter {
|
||||
|
||||
// Memory pass requesting the SSA rewriter.
|
||||
MemPass* pass_;
|
||||
|
||||
// Set of DebugDeclare instructions that are not added as DebugValue because
|
||||
// they are invisible to the store or phi instructions.
|
||||
std::unordered_set<Instruction*> decls_invisible_to_value_assignment_;
|
||||
};
|
||||
|
||||
class SSARewritePass : public MemPass {
|
||||
|
||||
@@ -78,7 +78,7 @@ endif()
|
||||
|
||||
spvtools_pch(SPIRV_TOOLS_REDUCE_SOURCES pch_source_reduce)
|
||||
|
||||
add_library(SPIRV-Tools-reduce STATIC ${SPIRV_TOOLS_REDUCE_SOURCES})
|
||||
add_library(SPIRV-Tools-reduce ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_REDUCE_SOURCES})
|
||||
|
||||
spvtools_default_compile_options(SPIRV-Tools-reduce)
|
||||
target_include_directories(SPIRV-Tools-reduce
|
||||
@@ -90,7 +90,7 @@ target_include_directories(SPIRV-Tools-reduce
|
||||
)
|
||||
# The reducer reuses a lot of functionality from the SPIRV-Tools library.
|
||||
target_link_libraries(SPIRV-Tools-reduce
|
||||
PUBLIC ${SPIRV_TOOLS}-static
|
||||
PUBLIC ${SPIRV_TOOLS_FULL_VISIBILITY}
|
||||
PUBLIC SPIRV-Tools-opt)
|
||||
|
||||
set_property(TARGET SPIRV-Tools-reduce PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright (c) 2017 Google Inc.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
|
||||
// reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -151,7 +153,9 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
|
||||
}
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env) &&
|
||||
_.GetBitWidth(result_type) != 32) {
|
||||
(_.GetBitWidth(result_type) != 32 &&
|
||||
(_.GetBitWidth(result_type) != 64 ||
|
||||
!_.HasCapability(SpvCapabilityInt64ImageEXT)))) {
|
||||
switch (opcode) {
|
||||
case SpvOpAtomicSMin:
|
||||
case SpvOpAtomicUMin:
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright (c) 2018 Google LLC.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
|
||||
// reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -14,8 +16,6 @@
|
||||
|
||||
// Validates correctness of built-in variables.
|
||||
|
||||
#include "source/val/validate.h"
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "source/spirv_target_env.h"
|
||||
#include "source/util/bitutils.h"
|
||||
#include "source/val/instruction.h"
|
||||
#include "source/val/validate.h"
|
||||
#include "source/val/validation_state.h"
|
||||
|
||||
namespace spvtools {
|
||||
@@ -230,6 +231,12 @@ class BuiltInsValidator {
|
||||
spv_result_t ValidateComputeI32InputAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
|
||||
spv_result_t ValidatePrimitiveShadingRateAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst);
|
||||
|
||||
spv_result_t ValidateShadingRateAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
|
||||
// The following section contains functions which are called when id defined
|
||||
// by |referenced_inst| is
|
||||
// 1. referenced by |referenced_from_inst|
|
||||
@@ -383,6 +390,16 @@ class BuiltInsValidator {
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidatePrimitiveShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidateShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
// Validates that |built_in_inst| is not (even indirectly) referenced from
|
||||
// within a function which can be called with |execution_model|.
|
||||
//
|
||||
@@ -2623,12 +2640,26 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
|
||||
case SpvExecutionModelVertex:
|
||||
case SpvExecutionModelTessellationEvaluation: {
|
||||
if (!_.HasCapability(SpvCapabilityShaderViewportIndexLayerEXT)) {
|
||||
if (operand == SpvBuiltInViewportIndex &&
|
||||
_.HasCapability(SpvCapabilityShaderViewportIndex))
|
||||
break; // Ok
|
||||
if (operand == SpvBuiltInLayer &&
|
||||
_.HasCapability(SpvCapabilityShaderLayer))
|
||||
break; // Ok
|
||||
|
||||
const char* capability = "ShaderViewportIndexLayerEXT";
|
||||
|
||||
if (operand == SpvBuiltInViewportIndex)
|
||||
capability = "ShaderViewportIndexLayerEXT or ShaderViewportIndex";
|
||||
if (operand == SpvBuiltInLayer)
|
||||
capability = "ShaderViewportIndexLayerEXT or ShaderLayer";
|
||||
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< "Using BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
operand)
|
||||
<< " in Vertex or Tessellation execution model requires "
|
||||
"the ShaderViewportIndexLayerEXT capability.";
|
||||
<< " in Vertex or Tessellation execution model requires the "
|
||||
<< capability << " capability.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3314,6 +3345,142 @@ spv_result_t BuiltInsValidator::ValidateSMBuiltinsAtReference(
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &inst,
|
||||
&decoration](const std::string& message) -> spv_result_t {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4486)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Seed at reference checks with this built-in.
|
||||
return ValidatePrimitiveShadingRateAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != SpvStorageClassMax &&
|
||||
storage_class != SpvStorageClassOutput) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4485) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be only used for variables with Output storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
<< " " << GetStorageClassDesc(referenced_from_inst);
|
||||
}
|
||||
|
||||
for (const SpvExecutionModel execution_model : execution_models_) {
|
||||
switch (execution_model) {
|
||||
case SpvExecutionModelVertex:
|
||||
case SpvExecutionModelGeometry:
|
||||
case SpvExecutionModelMeshNV:
|
||||
break;
|
||||
default: {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4484) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be used only with Vertex, Geometry, or MeshNV "
|
||||
"execution models. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_id_ == 0) {
|
||||
// Propagate this rule to all dependant ids in the global scope.
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(
|
||||
std::bind(&BuiltInsValidator::ValidatePrimitiveShadingRateAtReference,
|
||||
this, decoration, built_in_inst, referenced_from_inst,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateShadingRateAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &inst,
|
||||
&decoration](const std::string& message) -> spv_result_t {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4492)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Seed at reference checks with this built-in.
|
||||
return ValidateShadingRateAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != SpvStorageClassMax &&
|
||||
storage_class != SpvStorageClassInput) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4491) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be only used for variables with Input storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
<< " " << GetStorageClassDesc(referenced_from_inst);
|
||||
}
|
||||
|
||||
for (const SpvExecutionModel execution_model : execution_models_) {
|
||||
if (execution_model != SpvExecutionModelFragment) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4490) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be used only with the Fragment execution model. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_id_ == 0) {
|
||||
// Propagate this rule to all dependant ids in the global scope.
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateShadingRateAtReference, this, decoration,
|
||||
built_in_inst, referenced_from_inst, std::placeholders::_1));
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]);
|
||||
@@ -3514,6 +3681,11 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
case SpvBuiltInRayGeometryIndexKHR: {
|
||||
// No validation rules (for the moment).
|
||||
break;
|
||||
|
||||
case SpvBuiltInPrimitiveShadingRateKHR:
|
||||
return ValidatePrimitiveShadingRateAtDefinition(decoration, inst);
|
||||
case SpvBuiltInShadingRateKHR:
|
||||
return ValidateShadingRateAtDefinition(decoration, inst);
|
||||
}
|
||||
}
|
||||
return SPV_SUCCESS;
|
||||
|
||||
13
3rdparty/spirv-tools/source/val/validate_cfg.cpp
vendored
13
3rdparty/spirv-tools/source/val/validate_cfg.cpp
vendored
@@ -89,6 +89,8 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) {
|
||||
<< block->predecessors()->size() << ").";
|
||||
}
|
||||
|
||||
std::unordered_set<uint32_t> observed_predecessors;
|
||||
|
||||
for (size_t i = 3; i < inst->words().size(); ++i) {
|
||||
auto inc_id = inst->word(i);
|
||||
if (i % 2 == 1) {
|
||||
@@ -115,6 +117,17 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) {
|
||||
<< " is not a predecessor of <id> " << _.getIdName(block->id())
|
||||
<< ".";
|
||||
}
|
||||
|
||||
// We must not have already seen this predecessor as one of the phi's
|
||||
// operands.
|
||||
if (observed_predecessors.count(inc_id) != 0) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "OpPhi references incoming basic block <id> "
|
||||
<< _.getIdName(inc_id) << " multiple times.";
|
||||
}
|
||||
|
||||
// Note the fact that we have now observed this predecessor.
|
||||
observed_predecessors.insert(inc_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright (c) 2017 Google Inc.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
|
||||
// reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -737,7 +739,9 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if ((!_.IsFloatScalarType(info.sampled_type) &&
|
||||
!_.IsIntScalarType(info.sampled_type)) ||
|
||||
32 != _.GetBitWidth(info.sampled_type)) {
|
||||
(32 != _.GetBitWidth(info.sampled_type) &&
|
||||
(64 != _.GetBitWidth(info.sampled_type) ||
|
||||
!_.HasCapability(SpvCapabilityInt64ImageEXT)))) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Expected Sampled Type to be a 32-bit int or float "
|
||||
"scalar type for Vulkan environment";
|
||||
|
||||
Reference in New Issue
Block a user