Updated spirv-tools.

This commit is contained in:
Бранимир Караџић 2023-05-04 22:23:36 -07:00
parent 90e6e6f7a0
commit 1097abfc57
24 changed files with 827 additions and 136 deletions

View File

@ -1 +1 @@
"v2023.2", "SPIRV-Tools v2023.2 v2022.4-165-g574d9da4"
"v2023.2", "SPIRV-Tools v2023.2 v2022.4-192-ge472626b"

View File

@ -50,6 +50,7 @@ static const spv::Capability pygen_variable_caps_NamedBarrier[] = {spv::Capabili
static const spv::Capability pygen_variable_caps_PipeStorage[] = {spv::Capability::PipeStorage};
static const spv::Capability pygen_variable_caps_Pipes[] = {spv::Capability::Pipes};
static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR};
static const spv::Capability pygen_variable_caps_RayQueryPositionFetchKHR[] = {spv::Capability::RayQueryPositionFetchKHR};
static const spv::Capability pygen_variable_caps_RayTracingKHR[] = {spv::Capability::RayTracingKHR};
static const spv::Capability pygen_variable_caps_RayTracingKHRRayQueryKHR[] = {spv::Capability::RayTracingKHR, spv::Capability::RayQueryKHR};
static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv::Capability::RayTracingMotionBlurNV};
@ -76,6 +77,9 @@ static const spv::Capability pygen_variable_caps_SubgroupVoteKHR[] = {spv::Capab
static const spv::Capability pygen_variable_caps_TextureBlockMatchQCOM[] = {spv::Capability::TextureBlockMatchQCOM};
static const spv::Capability pygen_variable_caps_TextureBoxFilterQCOM[] = {spv::Capability::TextureBoxFilterQCOM};
static const spv::Capability pygen_variable_caps_TextureSampleWeightedQCOM[] = {spv::Capability::TextureSampleWeightedQCOM};
static const spv::Capability pygen_variable_caps_TileImageColorReadAccessEXT[] = {spv::Capability::TileImageColorReadAccessEXT};
static const spv::Capability pygen_variable_caps_TileImageDepthReadAccessEXT[] = {spv::Capability::TileImageDepthReadAccessEXT};
static const spv::Capability pygen_variable_caps_TileImageStencilReadAccessEXT[] = {spv::Capability::TileImageStencilReadAccessEXT};
static const spv::Capability pygen_variable_caps_USMStorageClassesINTEL[] = {spv::Capability::USMStorageClassesINTEL};
static const spv::Capability pygen_variable_caps_UnstructuredLoopControlsINTEL[] = {spv::Capability::UnstructuredLoopControlsINTEL};
static const spv::Capability pygen_variable_caps_VariableLengthArrayINTEL[] = {spv::Capability::VariableLengthArrayINTEL};
@ -455,6 +459,9 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"PtrEqual", spv::Op::OpPtrEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"PtrNotEqual", spv::Op::OpPtrNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"PtrDiff", spv::Op::OpPtrDiff, 3, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"ColorAttachmentReadEXT", spv::Op::OpColorAttachmentReadEXT, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"DepthAttachmentReadEXT", spv::Op::OpDepthAttachmentReadEXT, 1, pygen_variable_caps_TileImageDepthReadAccessEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"StencilAttachmentReadEXT", spv::Op::OpStencilAttachmentReadEXT, 1, pygen_variable_caps_TileImageStencilReadAccessEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TerminateInvocation", spv::Op::OpTerminateInvocation, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_terminate_invocation, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu},
{"SubgroupBallotKHR", spv::Op::OpSubgroupBallotKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu},
{"SubgroupFirstInvocationKHR", spv::Op::OpSubgroupFirstInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu},
@ -547,6 +554,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"TraceNV", spv::Op::OpTraceNV, 1, pygen_variable_caps_RayTracingNV, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TraceMotionNV", spv::Op::OpTraceMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu},
{"TraceRayMotionNV", spv::Op::OpTraceRayMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu},
{"RayQueryGetIntersectionTriangleVertexPositionsKHR", spv::Op::OpRayQueryGetIntersectionTriangleVertexPositionsKHR, 1, pygen_variable_caps_RayQueryPositionFetchKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"TypeAccelerationStructureKHR", spv::Op::OpTypeAccelerationStructureKHR, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"TypeAccelerationStructureNV", spv::Op::OpTypeAccelerationStructureNV, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"ExecuteCallableNV", spv::Op::OpExecuteCallableNV, 1, pygen_variable_caps_RayTracingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},

View File

@ -50,6 +50,8 @@ const char* ExtensionToString(Extension extension) {
return "SPV_EXT_shader_image_int64";
case Extension::kSPV_EXT_shader_stencil_export:
return "SPV_EXT_shader_stencil_export";
case Extension::kSPV_EXT_shader_tile_image:
return "SPV_EXT_shader_tile_image";
case Extension::kSPV_EXT_shader_viewport_index_layer:
return "SPV_EXT_shader_viewport_index_layer";
case Extension::kSPV_GOOGLE_decorate_string:
@ -166,6 +168,8 @@ const char* ExtensionToString(Extension extension) {
return "SPV_KHR_ray_query";
case Extension::kSPV_KHR_ray_tracing:
return "SPV_KHR_ray_tracing";
case Extension::kSPV_KHR_ray_tracing_position_fetch:
return "SPV_KHR_ray_tracing_position_fetch";
case Extension::kSPV_KHR_shader_atomic_counter_ops:
return "SPV_KHR_shader_atomic_counter_ops";
case Extension::kSPV_KHR_shader_ballot:
@ -237,8 +241,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_early_and_late_fragment_tests", "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_ARM_core_builtins", "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_mesh_shader", "SPV_EXT_opacity_micromap", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_bfloat16_conversion", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_argument_interfaces", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_dsp_control", "SPV_INTEL_fpga_invocation_pipelining_attributes", "SPV_INTEL_fpga_latency_control", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_runtime_aligned", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_cull_mask", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_invocation_reorder", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_QCOM_image_processing", "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_early_and_late_fragment_tests, 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_ARM_core_builtins, 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_mesh_shader, Extension::kSPV_EXT_opacity_micromap, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_bfloat16_conversion, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_argument_interfaces, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_dsp_control, Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes, Extension::kSPV_INTEL_fpga_latency_control, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_runtime_aligned, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_cull_mask, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_invocation_reorder, 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_QCOM_image_processing, 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_early_and_late_fragment_tests", "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_ARM_core_builtins", "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_mesh_shader", "SPV_EXT_opacity_micromap", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_tile_image", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_bfloat16_conversion", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_argument_interfaces", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_dsp_control", "SPV_INTEL_fpga_invocation_pipelining_attributes", "SPV_INTEL_fpga_latency_control", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_runtime_aligned", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_cull_mask", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_ray_tracing_position_fetch", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_invocation_reorder", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_QCOM_image_processing", "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_early_and_late_fragment_tests, 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_ARM_core_builtins, 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_mesh_shader, Extension::kSPV_EXT_opacity_micromap, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_tile_image, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_bfloat16_conversion, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_argument_interfaces, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_dsp_control, Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes, Extension::kSPV_INTEL_fpga_latency_control, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_runtime_aligned, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_cull_mask, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_ray_tracing_position_fetch, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_invocation_reorder, 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_QCOM_image_processing, 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(
@ -396,6 +400,12 @@ const char* CapabilityToString(spv::Capability capability) {
return "UniformDecoration";
case spv::Capability::CoreBuiltinsARM:
return "CoreBuiltinsARM";
case spv::Capability::TileImageColorReadAccessEXT:
return "TileImageColorReadAccessEXT";
case spv::Capability::TileImageDepthReadAccessEXT:
return "TileImageDepthReadAccessEXT";
case spv::Capability::TileImageStencilReadAccessEXT:
return "TileImageStencilReadAccessEXT";
case spv::Capability::FragmentShadingRateKHR:
return "FragmentShadingRateKHR";
case spv::Capability::SubgroupBallotKHR:
@ -526,6 +536,8 @@ const char* CapabilityToString(spv::Capability capability) {
return "UniformTexelBufferArrayNonUniformIndexing";
case spv::Capability::StorageTexelBufferArrayNonUniformIndexing:
return "StorageTexelBufferArrayNonUniformIndexing";
case spv::Capability::RayTracingPositionFetchKHR:
return "RayTracingPositionFetchKHR";
case spv::Capability::RayTracingNV:
return "RayTracingNV";
case spv::Capability::RayTracingMotionBlurNV:
@ -558,6 +570,8 @@ const char* CapabilityToString(spv::Capability capability) {
return "ShaderInvocationReorderNV";
case spv::Capability::BindlessTextureNV:
return "BindlessTextureNV";
case spv::Capability::RayQueryPositionFetchKHR:
return "RayQueryPositionFetchKHR";
case spv::Capability::SubgroupShuffleINTEL:
return "SubgroupShuffleINTEL";
case spv::Capability::SubgroupBufferBlockIOINTEL:

View File

@ -23,6 +23,7 @@ kSPV_EXT_shader_atomic_float_add,
kSPV_EXT_shader_atomic_float_min_max,
kSPV_EXT_shader_image_int64,
kSPV_EXT_shader_stencil_export,
kSPV_EXT_shader_tile_image,
kSPV_EXT_shader_viewport_index_layer,
kSPV_GOOGLE_decorate_string,
kSPV_GOOGLE_hlsl_functionality1,
@ -81,6 +82,7 @@ kSPV_KHR_post_depth_coverage,
kSPV_KHR_ray_cull_mask,
kSPV_KHR_ray_query,
kSPV_KHR_ray_tracing,
kSPV_KHR_ray_tracing_position_fetch,
kSPV_KHR_shader_atomic_counter_ops,
kSPV_KHR_shader_ballot,
kSPV_KHR_shader_clock,

View File

@ -86,6 +86,7 @@ static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv
static const spv::Capability pygen_variable_caps_RayTracingNV[] = {spv::Capability::RayTracingNV};
static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR};
static const spv::Capability pygen_variable_caps_RayTracingOpacityMicromapEXT[] = {spv::Capability::RayTracingOpacityMicromapEXT};
static const spv::Capability pygen_variable_caps_RayTracingPositionFetchKHR[] = {spv::Capability::RayTracingPositionFetchKHR};
static const spv::Capability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {spv::Capability::RayTraversalPrimitiveCullingKHR};
static const spv::Capability pygen_variable_caps_RoundToInfinityINTEL[] = {spv::Capability::RoundToInfinityINTEL};
static const spv::Capability pygen_variable_caps_RoundingModeRTE[] = {spv::Capability::RoundingModeRTE};
@ -119,6 +120,9 @@ static const spv::Capability pygen_variable_caps_StorageImageExtendedFormats[] =
static const spv::Capability pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot[] = {spv::Capability::SubgroupBallotKHR, spv::Capability::GroupNonUniformBallot};
static const spv::Capability pygen_variable_caps_SubgroupDispatch[] = {spv::Capability::SubgroupDispatch};
static const spv::Capability pygen_variable_caps_Tessellation[] = {spv::Capability::Tessellation};
static const spv::Capability pygen_variable_caps_TileImageColorReadAccessEXT[] = {spv::Capability::TileImageColorReadAccessEXT};
static const spv::Capability pygen_variable_caps_TileImageDepthReadAccessEXT[] = {spv::Capability::TileImageDepthReadAccessEXT};
static const spv::Capability pygen_variable_caps_TileImageStencilReadAccessEXT[] = {spv::Capability::TileImageStencilReadAccessEXT};
static const spv::Capability pygen_variable_caps_TransformFeedback[] = {spv::Capability::TransformFeedback};
static const spv::Capability pygen_variable_caps_USMStorageClassesINTEL[] = {spv::Capability::USMStorageClassesINTEL};
static const spv::Capability pygen_variable_caps_VariablePointersStorageBuffer[] = {spv::Capability::VariablePointersStorageBuffer};
@ -151,6 +155,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_min_max[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_min_max};
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_tile_image[] = {spvtools::Extension::kSPV_EXT_shader_tile_image};
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};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_user_type[] = {spvtools::Extension::kSPV_GOOGLE_user_type};
@ -208,6 +213,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvt
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_querySPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_query, spvtools::Extension::kSPV_KHR_ray_tracing};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_NV_ray_tracing};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch[] = {spvtools::Extension::kSPV_KHR_ray_tracing_position_fetch};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops[] = {spvtools::Extension::kSPV_KHR_shader_atomic_counter_ops};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot};
static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock};
@ -468,6 +474,9 @@ static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = {
{"SubgroupsPerWorkgroupId", 37, 1, pygen_variable_caps_SubgroupDispatch, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu},
{"LocalSizeId", 38, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu},
{"LocalSizeHintId", 39, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu},
{"NonCoherentColorAttachmentReadEXT", 4169, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"NonCoherentDepthAttachmentReadEXT", 4170, 1, pygen_variable_caps_TileImageDepthReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"NonCoherentStencilAttachmentReadEXT", 4171, 1, pygen_variable_caps_TileImageStencilReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupUniformControlFlowKHR", 4421, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_subgroup_uniform_control_flow, {}, 0xffffffffu, 0xffffffffu},
{"PostDepthCoverage", 4446, 1, pygen_variable_caps_SampleMaskPostDepthCoverage, 1, pygen_variable_exts_SPV_KHR_post_depth_coverage, {}, 0xffffffffu, 0xffffffffu},
{"DenormPreserve", 4459, 1, pygen_variable_caps_DenormPreserve, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
@ -526,6 +535,7 @@ static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = {
{"AtomicCounter", 10, 1, pygen_variable_caps_AtomicStorage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Image", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"StorageBuffer", 12, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"TileImageEXT", 4172, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"CallableDataNV", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"CallableDataKHR", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"IncomingCallableDataNV", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
@ -554,7 +564,8 @@ static const spv_operand_desc_t pygen_variable_DimEntries[] = {
{"Cube", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Rect", 4, 1, pygen_variable_caps_SampledRect, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Buffer", 5, 1, pygen_variable_caps_SampledBuffer, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SubpassData", 6, 1, pygen_variable_caps_InputAttachment, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
{"SubpassData", 6, 1, pygen_variable_caps_InputAttachment, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TileImageDataEXT", 4173, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_SamplerAddressingModeEntries[] = {
@ -974,6 +985,7 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
{"HitKindNV", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"HitKindKHR", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"CurrentRayTimeNV", 5334, 1, pygen_variable_caps_RayTracingMotionBlurNV, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, {}, 0xffffffffu, 0xffffffffu},
{"HitTriangleVertexPositionsKHR", 5335, 1, pygen_variable_caps_RayTracingPositionFetchKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"IncomingRayFlagsNV", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"IncomingRayFlagsKHR", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"RayGeometryIndexKHR", 5352, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
@ -1083,6 +1095,9 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"ShaderViewportIndex", 70, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformDecoration", 71, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu},
{"CoreBuiltinsARM", 4165, 0, nullptr, 1, pygen_variable_exts_SPV_ARM_core_builtins, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TileImageColorReadAccessEXT", 4166, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu},
{"TileImageDepthReadAccessEXT", 4167, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu},
{"TileImageStencilReadAccessEXT", 4168, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 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},
@ -1165,6 +1180,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"UniformTexelBufferArrayNonUniformIndexingEXT", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageTexelBufferArrayNonUniformIndexing", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageTexelBufferArrayNonUniformIndexingEXT", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"RayTracingPositionFetchKHR", 5336, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch, {}, 0xffffffffu, 0xffffffffu},
{"RayTracingNV", 5340, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"RayTracingMotionBlurNV", 5341, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, {}, 0xffffffffu, 0xffffffffu},
{"VulkanMemoryModel", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
@ -1185,6 +1201,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"RayTracingOpacityMicromapEXT", 5381, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 1, pygen_variable_exts_SPV_EXT_opacity_micromap, {}, 0xffffffffu, 0xffffffffu},
{"ShaderInvocationReorderNV", 5383, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_shader_invocation_reorder, {}, 0xffffffffu, 0xffffffffu},
{"BindlessTextureNV", 5390, 0, nullptr, 1, pygen_variable_exts_SPV_NV_bindless_texture, {}, 0xffffffffu, 0xffffffffu},
{"RayQueryPositionFetchKHR", 5391, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupShuffleINTEL", 5568, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupBufferBlockIOINTEL", 5569, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu},
{"SubgroupImageBlockIOINTEL", 5570, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu},

View File

@ -146,23 +146,29 @@ static const int kInstValidationOutError = kInstStageOutCnt;
// about the validation error.
//
// A bindless bounds error will output the index and the bound.
static const int kInstBindlessBoundsOutDescIndex = kInstStageOutCnt + 1;
static const int kInstBindlessBoundsOutDescBound = kInstStageOutCnt + 2;
static const int kInstBindlessBoundsOutUnused = kInstStageOutCnt + 3;
static const int kInstBindlessBoundsOutCnt = kInstStageOutCnt + 4;
static const int kInstBindlessBoundsOutDescSet = kInstStageOutCnt + 1;
static const int kInstBindlessBoundsOutDescBinding = kInstStageOutCnt + 2;
static const int kInstBindlessBoundsOutDescIndex = kInstStageOutCnt + 3;
static const int kInstBindlessBoundsOutDescBound = kInstStageOutCnt + 4;
static const int kInstBindlessBoundsOutUnused = kInstStageOutCnt + 5;
static const int kInstBindlessBoundsOutCnt = kInstStageOutCnt + 6;
// A descriptor uninitialized error will output the index.
static const int kInstBindlessUninitOutDescIndex = kInstStageOutCnt + 1;
static const int kInstBindlessUninitOutUnused = kInstStageOutCnt + 2;
static const int kInstBindlessUninitOutUnused2 = kInstStageOutCnt + 3;
static const int kInstBindlessUninitOutCnt = kInstStageOutCnt + 4;
static const int kInstBindlessUninitOutDescSet = kInstStageOutCnt + 1;
static const int kInstBindlessUninitOutBinding = kInstStageOutCnt + 2;
static const int kInstBindlessUninitOutDescIndex = kInstStageOutCnt + 3;
static const int kInstBindlessUninitOutUnused = kInstStageOutCnt + 4;
static const int kInstBindlessUninitOutUnused2 = kInstStageOutCnt + 5;
static const int kInstBindlessUninitOutCnt = kInstStageOutCnt + 6;
// A buffer out-of-bounds error will output the descriptor
// index, the buffer offset and the buffer size
static const int kInstBindlessBuffOOBOutDescIndex = kInstStageOutCnt + 1;
static const int kInstBindlessBuffOOBOutBuffOff = kInstStageOutCnt + 2;
static const int kInstBindlessBuffOOBOutBuffSize = kInstStageOutCnt + 3;
static const int kInstBindlessBuffOOBOutCnt = kInstStageOutCnt + 4;
static const int kInstBindlessBuffOOBOutDescSet = kInstStageOutCnt + 1;
static const int kInstBindlessBuffOOBOutDescBinding = kInstStageOutCnt + 2;
static const int kInstBindlessBuffOOBOutDescIndex = kInstStageOutCnt + 3;
static const int kInstBindlessBuffOOBOutBuffOff = kInstStageOutCnt + 4;
static const int kInstBindlessBuffOOBOutBuffSize = kInstStageOutCnt + 5;
static const int kInstBindlessBuffOOBOutCnt = kInstStageOutCnt + 6;
// A buffer address unalloc error will output the 64-bit pointer in
// two 32-bit pieces, lower bits first.
@ -171,7 +177,7 @@ static const int kInstBuffAddrUnallocOutDescPtrHi = kInstStageOutCnt + 2;
static const int kInstBuffAddrUnallocOutCnt = kInstStageOutCnt + 3;
// Maximum Output Record Member Count
static const int kInstMaxOutCnt = kInstStageOutCnt + 4;
static const int kInstMaxOutCnt = kInstStageOutCnt + 6;
// Validation Error Codes
//
@ -217,26 +223,37 @@ static const int kDebugInputBindingBuffAddr = 2;
// This is the output buffer written by InstDebugPrintfPass.
static const int kDebugOutputPrintfStream = 3;
// clang-format off
// Bindless Validation Input Buffer Format
//
// An input buffer for bindless validation consists of a single array of
// unsigned integers we will call Data[]. This array is formatted as follows.
// An input buffer for bindless validation has this structure:
// GLSL:
// layout(buffer_reference, std430, buffer_reference_align = 8) buffer DescriptorSetData {
// uint num_bindings;
// uint data[];
// };
//
// At offset kDebugInputBindlessInitOffset in Data[] is a single uint which
// gives an offset to the start of the bindless initialization data. More
// specifically, if the following value is zero, we know that the descriptor at
// (set = s, binding = b, index = i) is not initialized; if the value is
// non-zero, and the descriptor points to a buffer, the value is the length of
// the buffer in bytes and can be used to check for out-of-bounds buffer
// references:
// Data[ i + Data[ b + Data[ s + Data[ kDebugInputBindlessInitOffset ] ] ] ]
static const int kDebugInputBindlessInitOffset = 0;
// At offset kDebugInputBindlessOffsetLengths is some number of uints which
// provide the bindless length data. More specifically, the number of
// descriptors at (set=s, binding=b) is:
// Data[ Data[ s + kDebugInputBindlessOffsetLengths ] + b ]
static const int kDebugInputBindlessOffsetLengths = 1;
// layout(set = 7, binding = 1, std430) buffer inst_bindless_InputBuffer
// {
// DescriptorSetData desc_sets[32];
// } inst_bindless_input_buffer;
//
//
// To look up the length of a binding:
// uint length = inst_bindless_input_buffer[set].data[binding];
// Scalar bindings have a length of 1.
//
// To look up the initialization state of a descriptor in a binding:
// uint num_bindings = inst_bindless_input_buffer[set].num_bindings;
// uint binding_state_start = inst_bindless_input_buffer[set].data[num_bindings + binding];
// uint init_state = inst_bindless_input_buffer[set].data[binding_state_start + index];
//
// For scalar bindings, use 0 for the index.
// clang-format on
//
// The size of the inst_bindless_input_buffer array, regardless of how many
// descriptor sets the device supports.
static const int kDebugInputBindlessMaxDescSets = 32;
// Buffer Device Address Input Buffer Format
//

View File

@ -398,6 +398,7 @@ ConstantFoldingRule FoldVectorTimesMatrix() {
if (float_type->width() == 32) {
for (uint32_t i = 0; i < resultVectorSize; ++i) {
float result_scalar = 0.0f;
if (!c2_components[i]->AsNullConstant()) {
const analysis::VectorConstant* c2_vec =
c2_components[i]->AsVectorConstant();
for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) {
@ -405,6 +406,7 @@ ConstantFoldingRule FoldVectorTimesMatrix() {
float c2_scalar = c2_vec->GetComponents()[j]->GetFloat();
result_scalar += c1_scalar * c2_scalar;
}
}
utils::FloatProxy<float> result(result_scalar);
std::vector<uint32_t> words = result.GetWords();
const analysis::Constant* new_elem =
@ -415,6 +417,7 @@ ConstantFoldingRule FoldVectorTimesMatrix() {
} else if (float_type->width() == 64) {
for (uint32_t i = 0; i < c2_components.size(); ++i) {
double result_scalar = 0.0;
if (!c2_components[i]->AsNullConstant()) {
const analysis::VectorConstant* c2_vec =
c2_components[i]->AsVectorConstant();
for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) {
@ -422,6 +425,7 @@ ConstantFoldingRule FoldVectorTimesMatrix() {
double c2_scalar = c2_vec->GetComponents()[j]->GetDouble();
result_scalar += c1_scalar * c2_scalar;
}
}
utils::FloatProxy<double> result(result_scalar);
std::vector<uint32_t> words = result.GetWords();
const analysis::Constant* new_elem =
@ -491,6 +495,7 @@ ConstantFoldingRule FoldMatrixTimesVector() {
for (uint32_t i = 0; i < resultVectorSize; ++i) {
float result_scalar = 0.0f;
for (uint32_t j = 0; j < c1_components.size(); ++j) {
if (!c1_components[j]->AsNullConstant()) {
float c1_scalar = c1_components[j]
->AsVectorConstant()
->GetComponents()[i]
@ -498,6 +503,7 @@ ConstantFoldingRule FoldMatrixTimesVector() {
float c2_scalar = c2_components[j]->GetFloat();
result_scalar += c1_scalar * c2_scalar;
}
}
utils::FloatProxy<float> result(result_scalar);
std::vector<uint32_t> words = result.GetWords();
const analysis::Constant* new_elem =
@ -509,6 +515,7 @@ ConstantFoldingRule FoldMatrixTimesVector() {
for (uint32_t i = 0; i < resultVectorSize; ++i) {
double result_scalar = 0.0;
for (uint32_t j = 0; j < c1_components.size(); ++j) {
if (!c1_components[j]->AsNullConstant()) {
double c1_scalar = c1_components[j]
->AsVectorConstant()
->GetComponents()[i]
@ -516,6 +523,7 @@ ConstantFoldingRule FoldMatrixTimesVector() {
double c2_scalar = c2_components[j]->GetDouble();
result_scalar += c1_scalar * c2_scalar;
}
}
utils::FloatProxy<double> result(result_scalar);
std::vector<uint32_t> words = result.GetWords();
const analysis::Constant* new_elem =

View File

@ -16,6 +16,8 @@
#include "inst_bindless_check_pass.h"
#include "source/spirv_constant.h"
namespace spvtools {
namespace opt {
namespace {
@ -40,37 +42,521 @@ constexpr int kSpvTypeImageMS = 4;
constexpr int kSpvTypeImageSampled = 5;
} // namespace
uint32_t InstBindlessCheckPass::GenDebugReadLength(
uint32_t var_id, InstructionBuilder* builder) {
uint32_t desc_set_idx =
var2desc_set_[var_id] + kDebugInputBindlessOffsetLengths;
uint32_t desc_set_idx_id = builder->GetUintConstantId(desc_set_idx);
uint32_t binding_idx_id = builder->GetUintConstantId(var2binding_[var_id]);
return GenDebugDirectRead({desc_set_idx_id, binding_idx_id}, builder);
void InstBindlessCheckPass::SetupInputBufferIds() {
if (input_buffer_id_ != 0) {
return;
}
AddStorageBufferExt();
if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) {
context()->AddExtension("SPV_KHR_physical_storage_buffer");
}
context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses);
Instruction* memory_model = get_module()->GetMemoryModel();
// TODO should this be just Physical64?
memory_model->SetInOperand(
0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)});
analysis::DecorationManager* deco_mgr = get_decoration_mgr();
analysis::TypeManager* type_mgr = context()->get_type_mgr();
constexpr uint32_t width = 32u;
// declare the DescriptorSetData struct
analysis::Struct* desc_set_struct =
GetStruct({type_mgr->GetUIntType(), GetUintRuntimeArrayType(width)});
desc_set_type_id_ = type_mgr->GetTypeInstruction(desc_set_struct);
// By the Vulkan spec, a pre-existing struct containing a RuntimeArray
// must be a block, and will therefore be decorated with Block. Therefore
// the undecorated type returned here will not be pre-existing and can
// safely be decorated. Since this type is now decorated, it is out of
// sync with the TypeManager and therefore the TypeManager must be
// invalidated after this pass.
assert(context()->get_def_use_mgr()->NumUses(desc_set_type_id_) == 0 &&
"used struct type returned");
deco_mgr->AddDecoration(desc_set_type_id_, uint32_t(spv::Decoration::Block));
deco_mgr->AddMemberDecoration(desc_set_type_id_, 0,
uint32_t(spv::Decoration::Offset), 0);
deco_mgr->AddMemberDecoration(desc_set_type_id_, 1,
uint32_t(spv::Decoration::Offset), 4);
context()->AddDebug2Inst(
NewGlobalName(desc_set_type_id_, "DescriptorSetData"));
context()->AddDebug2Inst(NewMemberName(desc_set_type_id_, 0, "num_bindings"));
context()->AddDebug2Inst(NewMemberName(desc_set_type_id_, 1, "data"));
// declare buffer address reference to DescriptorSetData
desc_set_ptr_id_ = type_mgr->FindPointerToType(
desc_set_type_id_, spv::StorageClass::PhysicalStorageBuffer);
// runtime array of buffer addresses
analysis::Type* rarr_ty = GetArray(type_mgr->GetType(desc_set_ptr_id_),
kDebugInputBindlessMaxDescSets);
deco_mgr->AddDecorationVal(type_mgr->GetId(rarr_ty),
uint32_t(spv::Decoration::ArrayStride), 8u);
// declare the InputBuffer type, a struct wrapper around the runtime array
analysis::Struct* input_buffer_struct = GetStruct({rarr_ty});
input_buffer_struct_id_ = type_mgr->GetTypeInstruction(input_buffer_struct);
deco_mgr->AddDecoration(input_buffer_struct_id_,
uint32_t(spv::Decoration::Block));
deco_mgr->AddMemberDecoration(input_buffer_struct_id_, 0,
uint32_t(spv::Decoration::Offset), 0);
context()->AddDebug2Inst(
NewGlobalName(input_buffer_struct_id_, "InputBuffer"));
context()->AddDebug2Inst(
NewMemberName(input_buffer_struct_id_, 0, "desc_sets"));
input_buffer_ptr_id_ = type_mgr->FindPointerToType(
input_buffer_struct_id_, spv::StorageClass::StorageBuffer);
// declare the input_buffer global variable
input_buffer_id_ = TakeNextId();
const std::vector<Operand> var_operands = {
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
{uint32_t(spv::StorageClass::StorageBuffer)}},
};
auto new_var_op = spvtools::MakeUnique<Instruction>(
context(), spv::Op::OpVariable, input_buffer_ptr_id_, input_buffer_id_,
var_operands);
context()->AddGlobalValue(std::move(new_var_op));
context()->AddDebug2Inst(NewGlobalName(input_buffer_id_, "input_buffer"));
deco_mgr->AddDecorationVal(
input_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_);
deco_mgr->AddDecorationVal(input_buffer_id_,
uint32_t(spv::Decoration::Binding),
GetInputBufferBinding());
if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
// Add the new buffer to all entry points.
for (auto& entry : get_module()->entry_points()) {
entry.AddOperand({SPV_OPERAND_TYPE_ID, {input_buffer_id_}});
context()->AnalyzeUses(&entry);
}
}
}
// clang-format off
// GLSL:
// uint inst_bindless_read_binding_length(uint desc_set_idx, uint binding_idx)
// {
// if (desc_set_idx >= inst_bindless_input_buffer.desc_sets.length()) {
// return 0;
// }
//
// DescriptorSetData set_data = inst_bindless_input_buffer.desc_sets[desc_set_idx];
// uvec2 ptr_as_vec = uvec2(set_data);
// if ((ptr_as_vec.x == 0u) && (_ptr_as_vec.y == 0u))
// {
// return 0u;
// }
// uint num_bindings = set_data.num_bindings;
// if (binding_idx >= num_bindings) {
// return 0;
// }
// return set_data.data[binding_idx];
// }
// clang-format on
uint32_t InstBindlessCheckPass::GenDebugReadLengthFunctionId() {
if (read_length_func_id_ != 0) {
return read_length_func_id_;
}
SetupInputBufferIds();
const analysis::Integer* uint_type = GetInteger(32, false);
const std::vector<const analysis::Type*> param_types(2, uint_type);
const uint32_t func_id = TakeNextId();
std::unique_ptr<Function> func =
StartFunction(func_id, uint_type, param_types);
const std::vector<uint32_t> param_ids = AddParameters(*func, param_types);
// Create block
auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
InstructionBuilder builder(
context(), new_blk_ptr.get(),
IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
Instruction* inst;
inst = builder.AddBinaryOp(
GetBoolId(), spv::Op::OpUGreaterThanEqual, param_ids[0],
builder.GetUintConstantId(kDebugInputBindlessMaxDescSets));
const uint32_t desc_cmp_id = inst->result_id();
uint32_t error_blk_id = TakeNextId();
uint32_t merge_blk_id = TakeNextId();
std::unique_ptr<Instruction> merge_label(NewLabel(merge_blk_id));
std::unique_ptr<Instruction> error_label(NewLabel(error_blk_id));
(void)builder.AddConditionalBranch(desc_cmp_id, error_blk_id, merge_blk_id,
merge_blk_id);
func->AddBasicBlock(std::move(new_blk_ptr));
// error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
builder.SetInsertPoint(&*new_blk_ptr);
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
builder.GetUintConstantId(0));
func->AddBasicBlock(std::move(new_blk_ptr));
// check descriptor set table entry is non-null
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
builder.SetInsertPoint(&*new_blk_ptr);
analysis::TypeManager* type_mgr = context()->get_type_mgr();
const uint32_t desc_set_ptr_ptr = type_mgr->FindPointerToType(
desc_set_ptr_id_, spv::StorageClass::StorageBuffer);
inst = builder.AddAccessChain(desc_set_ptr_ptr, input_buffer_id_,
{builder.GetUintConstantId(0), param_ids[0]});
const uint32_t set_access_chain_id = inst->result_id();
inst = builder.AddLoad(desc_set_ptr_id_, set_access_chain_id);
const uint32_t desc_set_ptr_id = inst->result_id();
inst =
builder.AddUnaryOp(GetVecUintId(2), spv::Op::OpBitcast, desc_set_ptr_id);
const uint32_t ptr_as_uvec_id = inst->result_id();
inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {0});
const uint32_t uvec_x = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_x,
builder.GetUintConstantId(0));
const uint32_t x_is_zero_id = inst->result_id();
inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {1});
const uint32_t uvec_y = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_y,
builder.GetUintConstantId(0));
const uint32_t y_is_zero_id = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpLogicalAnd, x_is_zero_id,
y_is_zero_id);
const uint32_t is_null_id = inst->result_id();
error_blk_id = TakeNextId();
merge_blk_id = TakeNextId();
merge_label = NewLabel(merge_blk_id);
error_label = NewLabel(error_blk_id);
(void)builder.AddConditionalBranch(is_null_id, error_blk_id, merge_blk_id,
merge_blk_id);
func->AddBasicBlock(std::move(new_blk_ptr));
// error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
builder.SetInsertPoint(&*new_blk_ptr);
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
builder.GetUintConstantId(0));
func->AddBasicBlock(std::move(new_blk_ptr));
// check binding is in range
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
builder.SetInsertPoint(&*new_blk_ptr);
const uint32_t uint_ptr = type_mgr->FindPointerToType(
GetUintId(), spv::StorageClass::PhysicalStorageBuffer);
inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
{builder.GetUintConstantId(0)});
const uint32_t binding_access_chain_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), binding_access_chain_id, 8);
const uint32_t num_bindings_id = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
param_ids[1], num_bindings_id);
const uint32_t bindings_cmp_id = inst->result_id();
error_blk_id = TakeNextId();
merge_blk_id = TakeNextId();
merge_label = NewLabel(merge_blk_id);
error_label = NewLabel(error_blk_id);
(void)builder.AddConditionalBranch(bindings_cmp_id, error_blk_id,
merge_blk_id, merge_blk_id);
func->AddBasicBlock(std::move(new_blk_ptr));
// error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
builder.SetInsertPoint(&*new_blk_ptr);
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
builder.GetUintConstantId(0));
func->AddBasicBlock(std::move(new_blk_ptr));
// read binding length
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
builder.SetInsertPoint(&*new_blk_ptr);
inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
{{builder.GetUintConstantId(1), param_ids[1]}});
const uint32_t length_ac_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), length_ac_id, sizeof(uint32_t));
const uint32_t length_id = inst->result_id();
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, length_id);
func->AddBasicBlock(std::move(new_blk_ptr));
func->SetFunctionEnd(EndFunction());
context()->AddFunction(std::move(func));
context()->AddDebug2Inst(NewGlobalName(func_id, "read_binding_length"));
read_length_func_id_ = func_id;
// Make sure this function doesn't get processed by
// InstrumentPass::InstProcessCallTreeFromRoots()
param2output_func_id_[2] = func_id;
return read_length_func_id_;
}
// clang-format off
// GLSL:
// result = inst_bindless_read_binding_length(desc_set_id, binding_id);
// clang-format on
uint32_t InstBindlessCheckPass::GenDebugReadLength(
uint32_t var_id, InstructionBuilder* builder) {
const uint32_t func_id = GenDebugReadLengthFunctionId();
const std::vector<uint32_t> args = {
builder->GetUintConstantId(var2desc_set_[var_id]),
builder->GetUintConstantId(var2binding_[var_id]),
};
return GenReadFunctionCall(func_id, args, builder);
}
// clang-format off
// GLSL:
// uint inst_bindless_read_desc_init(uint desc_set_idx, uint binding_idx, uint desc_idx)
// {
// if (desc_set_idx >= uint(inst_bindless_input_buffer.desc_sets.length()))
// {
// return 0u;
// }
// DescriptorSetData set_data = inst_bindless_input_buffer.desc_sets[desc_set_idx];
// uvec2 ptr_as_vec = uvec2(set_data)
// if ((ptr_as_vec .x == 0u) && (ptr_as_vec.y == 0u))
// {
// return 0u;
// }
// if (binding_idx >= set_data.num_bindings)
// {
// return 0u;
// }
// if (desc_idx >= set_data.data[binding_idx])
// {
// return 0u;
// }
// uint desc_records_start = set_data.data[set_data.num_bindings + binding_idx];
// return set_data.data[desc_records_start + desc_idx];
// }
// clang-format on
uint32_t InstBindlessCheckPass::GenDebugReadInitFunctionId() {
if (read_init_func_id_ != 0) {
return read_init_func_id_;
}
SetupInputBufferIds();
const analysis::Integer* uint_type = GetInteger(32, false);
const std::vector<const analysis::Type*> param_types(3, uint_type);
const uint32_t func_id = TakeNextId();
std::unique_ptr<Function> func =
StartFunction(func_id, uint_type, param_types);
const std::vector<uint32_t> param_ids = AddParameters(*func, param_types);
// Create block
auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
InstructionBuilder builder(
context(), new_blk_ptr.get(),
IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
Instruction* inst;
inst = builder.AddBinaryOp(
GetBoolId(), spv::Op::OpUGreaterThanEqual, param_ids[0],
builder.GetUintConstantId(kDebugInputBindlessMaxDescSets));
const uint32_t desc_cmp_id = inst->result_id();
uint32_t error_blk_id = TakeNextId();
uint32_t merge_blk_id = TakeNextId();
std::unique_ptr<Instruction> merge_label(NewLabel(merge_blk_id));
std::unique_ptr<Instruction> error_label(NewLabel(error_blk_id));
(void)builder.AddConditionalBranch(desc_cmp_id, error_blk_id, merge_blk_id,
merge_blk_id);
func->AddBasicBlock(std::move(new_blk_ptr));
// error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
builder.SetInsertPoint(&*new_blk_ptr);
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
builder.GetUintConstantId(0));
func->AddBasicBlock(std::move(new_blk_ptr));
// check descriptor set table entry is non-null
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
builder.SetInsertPoint(&*new_blk_ptr);
analysis::TypeManager* type_mgr = context()->get_type_mgr();
const uint32_t desc_set_ptr_ptr = type_mgr->FindPointerToType(
desc_set_ptr_id_, spv::StorageClass::StorageBuffer);
inst = builder.AddAccessChain(desc_set_ptr_ptr, input_buffer_id_,
{builder.GetUintConstantId(0), param_ids[0]});
const uint32_t set_access_chain_id = inst->result_id();
inst = builder.AddLoad(desc_set_ptr_id_, set_access_chain_id);
const uint32_t desc_set_ptr_id = inst->result_id();
inst =
builder.AddUnaryOp(GetVecUintId(2), spv::Op::OpBitcast, desc_set_ptr_id);
const uint32_t ptr_as_uvec_id = inst->result_id();
inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {0});
const uint32_t uvec_x = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_x,
builder.GetUintConstantId(0));
const uint32_t x_is_zero_id = inst->result_id();
inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {1});
const uint32_t uvec_y = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_y,
builder.GetUintConstantId(0));
const uint32_t y_is_zero_id = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpLogicalAnd, x_is_zero_id,
y_is_zero_id);
const uint32_t is_null_id = inst->result_id();
error_blk_id = TakeNextId();
merge_blk_id = TakeNextId();
merge_label = NewLabel(merge_blk_id);
error_label = NewLabel(error_blk_id);
(void)builder.AddConditionalBranch(is_null_id, error_blk_id, merge_blk_id,
merge_blk_id);
func->AddBasicBlock(std::move(new_blk_ptr));
// error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
builder.SetInsertPoint(&*new_blk_ptr);
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
builder.GetUintConstantId(0));
func->AddBasicBlock(std::move(new_blk_ptr));
// check binding is in range
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
builder.SetInsertPoint(&*new_blk_ptr);
const uint32_t uint_ptr = type_mgr->FindPointerToType(
GetUintId(), spv::StorageClass::PhysicalStorageBuffer);
inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
{builder.GetUintConstantId(0)});
const uint32_t binding_access_chain_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), binding_access_chain_id, 8);
const uint32_t num_bindings_id = inst->result_id();
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
param_ids[1], num_bindings_id);
const uint32_t bindings_cmp_id = inst->result_id();
error_blk_id = TakeNextId();
merge_blk_id = TakeNextId();
merge_label = NewLabel(merge_blk_id);
error_label = NewLabel(error_blk_id);
(void)builder.AddConditionalBranch(bindings_cmp_id, error_blk_id,
merge_blk_id, merge_blk_id);
func->AddBasicBlock(std::move(new_blk_ptr));
// error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
builder.SetInsertPoint(&*new_blk_ptr);
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
builder.GetUintConstantId(0));
func->AddBasicBlock(std::move(new_blk_ptr));
// read binding length
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
builder.SetInsertPoint(&*new_blk_ptr);
inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
{{builder.GetUintConstantId(1), param_ids[1]}});
const uint32_t length_ac_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), length_ac_id, sizeof(uint32_t));
const uint32_t length_id = inst->result_id();
// Check descriptor index in bounds
inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
param_ids[2], length_id);
const uint32_t desc_idx_range_id = inst->result_id();
error_blk_id = TakeNextId();
merge_blk_id = TakeNextId();
merge_label = NewLabel(merge_blk_id);
error_label = NewLabel(error_blk_id);
(void)builder.AddConditionalBranch(desc_idx_range_id, error_blk_id,
merge_blk_id, merge_blk_id);
func->AddBasicBlock(std::move(new_blk_ptr));
// Error return
new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
builder.SetInsertPoint(&*new_blk_ptr);
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
builder.GetUintConstantId(0));
func->AddBasicBlock(std::move(new_blk_ptr));
// Read descriptor init status
new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
builder.SetInsertPoint(&*new_blk_ptr);
inst = builder.AddIAdd(GetUintId(), num_bindings_id, param_ids[1]);
const uint32_t state_offset_id = inst->result_id();
inst =
builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
{{builder.GetUintConstantId(1), state_offset_id}});
const uint32_t state_start_ac_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), state_start_ac_id, sizeof(uint32_t));
const uint32_t state_start_id = inst->result_id();
inst = builder.AddIAdd(GetUintId(), state_start_id, param_ids[2]);
const uint32_t state_entry_id = inst->result_id();
// Note: length starts from the beginning of the buffer, not the beginning of
// the data array
inst =
builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
{{builder.GetUintConstantId(1), state_entry_id}});
const uint32_t init_ac_id = inst->result_id();
inst = builder.AddLoad(GetUintId(), init_ac_id, sizeof(uint32_t));
const uint32_t init_status_id = inst->result_id();
(void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, init_status_id);
func->AddBasicBlock(std::move(new_blk_ptr));
func->SetFunctionEnd(EndFunction());
context()->AddFunction(std::move(func));
context()->AddDebug2Inst(NewGlobalName(func_id, "read_desc_init"));
read_init_func_id_ = func_id;
// Make sure function doesn't get processed by
// InstrumentPass::InstProcessCallTreeFromRoots()
param2output_func_id_[3] = func_id;
return read_init_func_id_;
}
// clang-format off
// GLSL:
// result = inst_bindless_read_desc_init(desc_set_id, binding_id, desc_idx_id);
//
// clang-format on
uint32_t InstBindlessCheckPass::GenDebugReadInit(uint32_t var_id,
uint32_t desc_idx_id,
InstructionBuilder* builder) {
uint32_t binding_idx_id = builder->GetUintConstantId(var2binding_[var_id]);
uint32_t u_desc_idx_id = GenUintCastCode(desc_idx_id, builder);
// If desc index checking is not enabled, we know the offset of initialization
// entries is 1, so we can avoid loading this value and just add 1 to the
// descriptor set.
if (!desc_idx_enabled_) {
uint32_t desc_set_idx_id =
builder->GetUintConstantId(var2desc_set_[var_id] + 1);
return GenDebugDirectRead({desc_set_idx_id, binding_idx_id, u_desc_idx_id},
builder);
} else {
uint32_t desc_set_base_id =
builder->GetUintConstantId(kDebugInputBindlessInitOffset);
uint32_t desc_set_idx_id =
builder->GetUintConstantId(var2desc_set_[var_id]);
return GenDebugDirectRead(
{desc_set_base_id, desc_set_idx_id, binding_idx_id, u_desc_idx_id},
builder);
}
const uint32_t func_id = GenDebugReadInitFunctionId();
const std::vector<uint32_t> args = {
builder->GetUintConstantId(var2desc_set_[var_id]),
builder->GetUintConstantId(var2binding_[var_id]),
GenUintCastCode(desc_idx_id, builder)};
return GenReadFunctionCall(func_id, args, builder);
}
uint32_t InstBindlessCheckPass::CloneOriginalImage(
@ -248,9 +734,18 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst,
ptr_inst->GetSingleWordInOperand(kSpvAccessChainIndex0IdInIdx);
break;
default:
ref->desc_idx_id = 0;
break;
}
auto decos =
context()->get_decoration_mgr()->GetDecorationsFor(ref->var_id, false);
for (const auto& deco : decos) {
spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u));
if (d == spv::Decoration::DescriptorSet) {
ref->set = deco->GetSingleWordInOperand(2u);
} else if (d == spv::Decoration::Binding) {
ref->binding = deco->GetSingleWordInOperand(2u);
}
}
return true;
}
// Reference is not load or store. If not an image-based reference, return.
@ -300,6 +795,16 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst,
// TODO(greg-lunarg): Handle additional possibilities?
return false;
}
auto decos =
context()->get_decoration_mgr()->GetDecorationsFor(ref->var_id, false);
for (const auto& deco : decos) {
spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u));
if (d == spv::Decoration::DescriptorSet) {
ref->set = deco->GetSingleWordInOperand(2u);
} else if (d == spv::Decoration::Binding) {
ref->binding = deco->GetSingleWordInOperand(2u);
}
}
return true;
}
@ -542,27 +1047,29 @@ void InstBindlessCheckPass::GenCheckCode(
// Gen invalid block
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);
const uint32_t u_set_id = builder.GetUintConstantId(ref->set);
const uint32_t u_binding_id = builder.GetUintConstantId(ref->binding);
const uint32_t u_index_id = GenUintCastCode(ref->desc_idx_id, &builder);
const uint32_t u_length_id = GenUintCastCode(length_id, &builder);
if (offset_id != 0) {
const uint32_t u_offset_id = GenUintCastCode(offset_id, &builder);
// 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, u_offset_id, u_length_id},
{error_id, u_set_id, u_binding_id, u_index_id,
u_offset_id, u_length_id},
&builder);
} else if (buffer_bounds_enabled_ || texel_buffer_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, u_length_id, builder.GetUintConstantId(0)},
GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx,
{error_id, u_set_id, u_binding_id, u_index_id,
u_length_id, builder.GetUintConstantId(0)},
&builder);
} 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, u_length_id}, &builder);
GenDebugStreamWrite(
uid2offset_[ref->ref_inst->unique_id()], stage_idx,
{error_id, u_set_id, u_binding_id, u_index_id, u_length_id}, &builder);
}
// Generate a ConstantNull, converting to uint64 if the type cannot be a null.
if (new_ref_id != 0) {

View File

@ -110,10 +110,14 @@ class InstBindlessCheckPass : public InstrumentPass {
UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
void SetupInputBufferIds();
uint32_t GenDebugReadLengthFunctionId();
// Generate instructions into |builder| to read length of runtime descriptor
// array |var_id| from debug input buffer and return id of value.
uint32_t GenDebugReadLength(uint32_t var_id, InstructionBuilder* builder);
uint32_t GenDebugReadInitFunctionId();
// Generate instructions into |builder| to read initialization status of
// descriptor array |image_id| at |index_id| from debug input buffer and
// return id of value.
@ -124,14 +128,16 @@ class InstBindlessCheckPass : public InstrumentPass {
// AnalyzeDescriptorReference. It is necessary and sufficient for further
// analysis and regeneration of the reference.
typedef struct RefAnalysis {
uint32_t desc_load_id;
uint32_t image_id;
uint32_t load_id;
uint32_t ptr_id;
uint32_t var_id;
uint32_t desc_idx_id;
uint32_t strg_class;
Instruction* ref_inst;
uint32_t desc_load_id{0};
uint32_t image_id{0};
uint32_t load_id{0};
uint32_t ptr_id{0};
uint32_t var_id{0};
uint32_t set{0};
uint32_t binding{0};
uint32_t desc_idx_id{0};
uint32_t strg_class{0};
Instruction* ref_inst{nullptr};
} RefAnalysis;
// Return size of type |ty_id| in bytes. Use |matrix_stride| and |col_major|
@ -201,6 +207,13 @@ class InstBindlessCheckPass : public InstrumentPass {
// Mapping from variable to binding
std::unordered_map<uint32_t, uint32_t> var2binding_;
uint32_t read_length_func_id_{0};
uint32_t read_init_func_id_{0};
uint32_t desc_set_type_id_{0};
uint32_t desc_set_ptr_id_{0};
uint32_t input_buffer_struct_id_{0};
uint32_t input_buffer_ptr_id_{0};
};
} // namespace opt

View File

@ -19,6 +19,24 @@
namespace spvtools {
namespace opt {
bool InstBuffAddrCheckPass::InstrumentFunction(Function* func,
uint32_t stage_idx,
InstProcessFunction& pfn) {
// The bindless instrumentation pass adds functions that use
// BufferDeviceAddress They should not be instrumented by this pass.
Instruction* func_name_inst =
context()->GetNames(func->DefInst().result_id()).begin()->second;
if (func_name_inst) {
static const std::string kPrefix{"inst_bindless_"};
std::string func_name = func_name_inst->GetOperand(1).AsString();
if (func_name.size() >= kPrefix.size() &&
func_name.compare(0, kPrefix.size(), kPrefix) == 0) {
return false;
}
}
return InstrumentPass::InstrumentFunction(func, stage_idx, pfn);
}
uint32_t InstBuffAddrCheckPass::CloneOriginalReference(
Instruction* ref_inst, InstructionBuilder* builder) {
// Clone original ref with new result id (if load)

View File

@ -41,6 +41,9 @@ class InstBuffAddrCheckPass : public InstrumentPass {
const char* name() const override { return "inst-buff-addr-check-pass"; }
bool InstrumentFunction(Function* func, uint32_t stage_idx,
InstProcessFunction& pfn) override;
private:
// Return byte alignment of type |type_id|. Must be int, float, vector,
// matrix, struct, array or physical pointer. Uses std430 alignment.

View File

@ -564,6 +564,19 @@ analysis::RuntimeArray* InstrumentPass::GetRuntimeArray(
return type->AsRuntimeArray();
}
analysis::Array* InstrumentPass::GetArray(const analysis::Type* element,
uint32_t length) {
uint32_t length_id = context()->get_constant_mgr()->GetUIntConstId(length);
analysis::Array::LengthInfo length_info{
length_id, {analysis::Array::LengthInfo::Case::kConstant, length}};
analysis::Array r(element, length_info);
analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&r);
assert(type && type->AsArray());
return type->AsArray();
}
analysis::Function* InstrumentPass::GetFunction(
const analysis::Type* return_val,
const std::vector<const analysis::Type*>& args) {

View File

@ -270,6 +270,7 @@ class InstrumentPass : public Pass {
analysis::Integer* GetInteger(uint32_t width, bool is_signed);
analysis::Struct* GetStruct(const std::vector<const analysis::Type*>& fields);
analysis::RuntimeArray* GetRuntimeArray(const analysis::Type* element);
analysis::Array* GetArray(const analysis::Type* element, uint32_t size);
analysis::Function* GetFunction(
const analysis::Type* return_val,
const std::vector<const analysis::Type*>& args);
@ -339,7 +340,7 @@ class InstrumentPass : public Pass {
// If code is generated for an instruction, replace the instruction's
// block with the new blocks that are generated. Continue processing at the
// top of the last new block.
bool InstrumentFunction(Function* func, uint32_t stage_idx,
virtual bool InstrumentFunction(Function* func, uint32_t stage_idx,
InstProcessFunction& pfn);
// Call |pfn| on all functions in the call tree of the function

View File

@ -480,9 +480,16 @@ class InstructionBuilder {
return AddInstruction(std::move(new_inst));
}
Instruction* AddLoad(uint32_t type_id, uint32_t base_ptr_id) {
Instruction* AddLoad(uint32_t type_id, uint32_t base_ptr_id,
uint32_t alignment = 0) {
std::vector<Operand> operands;
operands.push_back({SPV_OPERAND_TYPE_ID, {base_ptr_id}});
if (alignment != 0) {
operands.push_back(
{SPV_OPERAND_TYPE_MEMORY_ACCESS,
{static_cast<uint32_t>(spv::MemoryAccessMask::Aligned)}});
operands.push_back({SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, {alignment}});
}
// TODO(1841): Handle id overflow.
std::unique_ptr<Instruction> new_inst(

View File

@ -84,7 +84,7 @@ Pass::Status LICMPass::AnalyseAndHoistFromBB(
bool modified = false;
std::function<bool(Instruction*)> hoist_inst =
[this, &loop, &modified](Instruction* inst) {
if (loop->ShouldHoistInstruction(this->context(), inst)) {
if (loop->ShouldHoistInstruction(*inst)) {
if (!HoistInstruction(loop, inst)) {
return false;
}

View File

@ -450,25 +450,20 @@ bool Loop::IsLCSSA() const {
return true;
}
bool Loop::ShouldHoistInstruction(IRContext* context, Instruction* inst) {
return AreAllOperandsOutsideLoop(context, inst) &&
inst->IsOpcodeCodeMotionSafe();
bool Loop::ShouldHoistInstruction(const Instruction& inst) const {
return inst.IsOpcodeCodeMotionSafe() && AreAllOperandsOutsideLoop(inst) &&
(!inst.IsLoad() || inst.IsReadOnlyLoad());
}
bool Loop::AreAllOperandsOutsideLoop(IRContext* context, Instruction* inst) {
analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
bool all_outside_loop = true;
bool Loop::AreAllOperandsOutsideLoop(const Instruction& inst) const {
analysis::DefUseManager* def_use_mgr = GetContext()->get_def_use_mgr();
const std::function<void(uint32_t*)> operand_outside_loop =
[this, &def_use_mgr, &all_outside_loop](uint32_t* id) {
if (this->IsInsideLoop(def_use_mgr->GetDef(*id))) {
all_outside_loop = false;
return;
}
const std::function<bool(const uint32_t*)> operand_outside_loop =
[this, &def_use_mgr](const uint32_t* id) {
return !this->IsInsideLoop(def_use_mgr->GetDef(*id));
};
inst->ForEachInId(operand_outside_loop);
return all_outside_loop;
return inst.WhileEachInId(operand_outside_loop);
}
void Loop::ComputeLoopStructuredOrder(

View File

@ -296,12 +296,12 @@ class Loop {
// as a nested child loop.
inline void SetParent(Loop* parent) { parent_ = parent; }
// Returns true is the instruction is invariant and safe to move wrt loop
bool ShouldHoistInstruction(IRContext* context, Instruction* inst);
// Returns true is the instruction is invariant and safe to move wrt loop.
bool ShouldHoistInstruction(const Instruction& inst) const;
// Returns true if all operands of inst are in basic blocks not contained in
// loop
bool AreAllOperandsOutsideLoop(IRContext* context, Instruction* inst);
// loop.
bool AreAllOperandsOutsideLoop(const Instruction& inst) const;
// Extract the initial value from the |induction| variable and store it in
// |value|. If the function couldn't find the initial value of |induction|

View File

@ -15,7 +15,9 @@
#ifndef SOURCE_UTIL_SMALL_VECTOR_H_
#define SOURCE_UTIL_SMALL_VECTOR_H_
#include <array>
#include <cassert>
#include <cstddef>
#include <iostream>
#include <memory>
#include <utility>
@ -461,14 +463,18 @@ class SmallVector {
// The number of elements in |small_data_| that have been constructed.
size_t size_;
// The pointed used to access the array of elements when the number of
// elements is small.
T* small_data_;
// A type with the same alignment and size as T, but will is POD.
struct alignas(T) PodType {
std::array<int8_t, sizeof(T)> data;
};
// The actual data used to store the array elements. It must never be used
// directly, but must only be accessed through |small_data_|.
typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type
buffer[small_size];
PodType buffer[small_size];
// The pointed used to access the array of elements when the number of
// elements is small.
T* small_data_;
// A pointer to a vector that is used to store the elements of the vector when
// this size exceeds |small_size|. If |large_data_| is nullptr, then the data

View File

@ -193,7 +193,8 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec,
switch (dec) {
case spv::Decoration::Location:
case spv::Decoration::Component:
// Location is used for input, output and ray tracing stages.
// Location is used for input, output, tile image, and ray tracing
// stages.
if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output &&
sc != spv::StorageClass::RayPayloadKHR &&
sc != spv::StorageClass::IncomingRayPayloadKHR &&
@ -201,7 +202,8 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec,
sc != spv::StorageClass::CallableDataKHR &&
sc != spv::StorageClass::IncomingCallableDataKHR &&
sc != spv::StorageClass::ShaderRecordBufferKHR &&
sc != spv::StorageClass::HitObjectAttributeNV) {
sc != spv::StorageClass::HitObjectAttributeNV &&
sc != spv::StorageClass::TileImageEXT) {
return _.diag(SPV_ERROR_INVALID_ID, target)
<< _.VkErrorID(6672) << _.SpvDecorationString(dec)
<< " decoration must not be applied to this storage class";

View File

@ -76,7 +76,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _,
}
const auto constituent_result_type = _.FindDef(constituent->type_id());
if (!constituent_result_type ||
component_type->opcode() != constituent_result_type->opcode()) {
component_type->id() != constituent_result_type->id()) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< opcode_name << " Constituent <id> "
<< _.getIdName(constituent_id)

View File

@ -14,6 +14,7 @@
#include <algorithm>
#include "source/enum_string_mapping.h"
#include "source/opcode.h"
#include "source/val/instruction.h"
#include "source/val/validate.h"

View File

@ -210,6 +210,7 @@ uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) {
case spv::Dim::Dim2D:
case spv::Dim::Rect:
case spv::Dim::SubpassData:
case spv::Dim::TileImageDataEXT:
plane_size = 2;
break;
case spv::Dim::Dim3D:
@ -218,6 +219,7 @@ uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) {
plane_size = 3;
break;
case spv::Dim::Max:
default:
assert(0);
break;
}
@ -853,6 +855,28 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Dim SubpassData requires format Unknown";
}
} else if (info.dim == spv::Dim::TileImageDataEXT) {
if (_.IsVoidType(info.sampled_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Dim TileImageDataEXT requires Sampled Type to be not "
"OpTypeVoid";
}
if (info.sampled != 2) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Dim TileImageDataEXT requires Sampled to be 2";
}
if (info.format != spv::ImageFormat::Unknown) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Dim TileImageDataEXT requires format Unknown";
}
if (info.depth != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Dim TileImageDataEXT requires Depth to be 0";
}
if (info.arrayed != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Dim TileImageDataEXT requires Arrayed to be 0";
}
} else {
if (info.multisampled && (info.sampled == 2) &&
!_.HasCapability(spv::Capability::StorageImageMultisample)) {
@ -918,6 +942,8 @@ spv_result_t ValidateTypeSampledImage(ValidationState_t& _,
}
// OpenCL requires Sampled=0, checked elsewhere.
// Vulkan uses the Sampled=1 case.
// If Dim is TileImageDataEXT, Sampled must be 2 and this is validated
// elsewhere.
if ((info.sampled != 0) && (info.sampled != 1)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4657)
@ -1117,6 +1143,12 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _,
<< "Image Dim SubpassData cannot be used with OpImageTexelPointer";
}
if (info.dim == spv::Dim::TileImageDataEXT) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Image Dim TileImageDataEXT cannot be used with "
"OpImageTexelPointer";
}
const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
if (!coord_type || !_.IsIntScalarOrVectorType(coord_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@ -1623,6 +1655,12 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
spvOpcodeString(opcode));
}
if (info.dim == spv::Dim::TileImageDataEXT) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Image Dim TileImageDataEXT cannot be used with "
<< spvOpcodeString(opcode);
}
if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
const uint32_t result_component_type =
_.GetComponentType(actual_result_type);
@ -1685,6 +1723,11 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) {
<< "Image 'Dim' cannot be SubpassData";
}
if (info.dim == spv::Dim::TileImageDataEXT) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Image 'Dim' cannot be TileImageDataEXT";
}
if (spv_result_t result = ValidateImageReadWrite(_, inst, info))
return result;
@ -1899,10 +1942,22 @@ spv_result_t ValidateImageQueryFormatOrOrder(ValidationState_t& _,
<< "Expected Result Type to be int scalar type";
}
if (_.GetIdOpcode(_.GetOperandTypeId(inst, 2)) != spv::Op::OpTypeImage) {
const uint32_t image_type = _.GetOperandTypeId(inst, 2);
if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected operand to be of type OpTypeImage";
}
ImageTypeInfo info;
if (!GetImageTypeInfo(_, image_type, &info)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Corrupt image type definition";
}
if (info.dim == spv::Dim::TileImageDataEXT) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Image 'Dim' cannot be TileImageDataEXT";
}
return SPV_SUCCESS;
}

View File

@ -502,6 +502,9 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
case spv::ExecutionMode::DepthGreater:
case spv::ExecutionMode::DepthLess:
case spv::ExecutionMode::DepthUnchanged:
case spv::ExecutionMode::NonCoherentColorAttachmentReadEXT:
case spv::ExecutionMode::NonCoherentDepthAttachmentReadEXT:
case spv::ExecutionMode::NonCoherentStencilAttachmentReadEXT:
case spv::ExecutionMode::PixelInterlockOrderedEXT:
case spv::ExecutionMode::PixelInterlockUnorderedEXT:
case spv::ExecutionMode::SampleInterlockOrderedEXT:

View File

@ -1572,6 +1572,7 @@ bool ValidationState_t::IsValidStorageClass(
case spv::StorageClass::ShaderRecordBufferKHR:
case spv::StorageClass::TaskPayloadWorkgroupEXT:
case spv::StorageClass::HitObjectAttributeNV:
case spv::StorageClass::TileImageEXT:
return true;
default:
return false;