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 @@
|
||||
"v2019.4-dev", "SPIRV-Tools v2019.4-dev v2019.3-41-ga8ae579f"
|
||||
"v2019.4-dev", "SPIRV-Tools v2019.4-dev v2019.3-47-g59983a60"
|
||||
|
||||
@@ -38,6 +38,8 @@ const char* ExtensionToString(Extension extension) {
|
||||
return "SPV_GOOGLE_decorate_string";
|
||||
case Extension::kSPV_GOOGLE_hlsl_functionality1:
|
||||
return "SPV_GOOGLE_hlsl_functionality1";
|
||||
case Extension::kSPV_GOOGLE_user_type:
|
||||
return "SPV_GOOGLE_user_type";
|
||||
case Extension::kSPV_INTEL_device_side_avc_motion_estimation:
|
||||
return "SPV_INTEL_device_side_avc_motion_estimation";
|
||||
case Extension::kSPV_INTEL_media_block_io:
|
||||
@@ -111,8 +113,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_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_post_depth_coverage", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
|
||||
static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
|
||||
static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_media_block_io", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_device_group", "SPV_KHR_float_controls", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_post_depth_coverage", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_vote", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
|
||||
static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
|
||||
const auto b = std::begin(known_ext_strs);
|
||||
const auto e = std::end(known_ext_strs);
|
||||
const auto found = std::equal_range(
|
||||
@@ -330,6 +332,16 @@ const char* CapabilityToString(SpvCapability capability) {
|
||||
return "FragmentFullyCoveredEXT";
|
||||
case SpvCapabilityMeshShadingNV:
|
||||
return "MeshShadingNV";
|
||||
case SpvCapabilityImageFootprintNV:
|
||||
return "ImageFootprintNV";
|
||||
case SpvCapabilityFragmentBarycentricNV:
|
||||
return "FragmentBarycentricNV";
|
||||
case SpvCapabilityComputeDerivativeGroupQuadsNV:
|
||||
return "ComputeDerivativeGroupQuadsNV";
|
||||
case SpvCapabilityFragmentDensityEXT:
|
||||
return "FragmentDensityEXT";
|
||||
case SpvCapabilityGroupNonUniformPartitionedNV:
|
||||
return "GroupNonUniformPartitionedNV";
|
||||
case SpvCapabilityShaderNonUniformEXT:
|
||||
return "ShaderNonUniformEXT";
|
||||
case SpvCapabilityRuntimeDescriptorArrayEXT:
|
||||
@@ -356,6 +368,24 @@ const char* CapabilityToString(SpvCapability capability) {
|
||||
return "StorageTexelBufferArrayNonUniformIndexingEXT";
|
||||
case SpvCapabilityRayTracingNV:
|
||||
return "RayTracingNV";
|
||||
case SpvCapabilityVulkanMemoryModelKHR:
|
||||
return "VulkanMemoryModelKHR";
|
||||
case SpvCapabilityVulkanMemoryModelDeviceScopeKHR:
|
||||
return "VulkanMemoryModelDeviceScopeKHR";
|
||||
case SpvCapabilityPhysicalStorageBufferAddressesEXT:
|
||||
return "PhysicalStorageBufferAddressesEXT";
|
||||
case SpvCapabilityComputeDerivativeGroupLinearNV:
|
||||
return "ComputeDerivativeGroupLinearNV";
|
||||
case SpvCapabilityCooperativeMatrixNV:
|
||||
return "CooperativeMatrixNV";
|
||||
case SpvCapabilityFragmentShaderSampleInterlockEXT:
|
||||
return "FragmentShaderSampleInterlockEXT";
|
||||
case SpvCapabilityFragmentShaderShadingRateInterlockEXT:
|
||||
return "FragmentShaderShadingRateInterlockEXT";
|
||||
case SpvCapabilityShaderSMBuiltinsNV:
|
||||
return "ShaderSMBuiltinsNV";
|
||||
case SpvCapabilityFragmentShaderPixelInterlockEXT:
|
||||
return "FragmentShaderPixelInterlockEXT";
|
||||
case SpvCapabilitySubgroupShuffleINTEL:
|
||||
return "SubgroupShuffleINTEL";
|
||||
case SpvCapabilitySubgroupBufferBlockIOINTEL:
|
||||
@@ -372,34 +402,6 @@ const char* CapabilityToString(SpvCapability capability) {
|
||||
return "SubgroupAvcMotionEstimationIntraINTEL";
|
||||
case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL:
|
||||
return "SubgroupAvcMotionEstimationChromaINTEL";
|
||||
case SpvCapabilityGroupNonUniformPartitionedNV:
|
||||
return "GroupNonUniformPartitionedNV";
|
||||
case SpvCapabilityVulkanMemoryModelKHR:
|
||||
return "VulkanMemoryModelKHR";
|
||||
case SpvCapabilityVulkanMemoryModelDeviceScopeKHR:
|
||||
return "VulkanMemoryModelDeviceScopeKHR";
|
||||
case SpvCapabilityImageFootprintNV:
|
||||
return "ImageFootprintNV";
|
||||
case SpvCapabilityFragmentBarycentricNV:
|
||||
return "FragmentBarycentricNV";
|
||||
case SpvCapabilityComputeDerivativeGroupQuadsNV:
|
||||
return "ComputeDerivativeGroupQuadsNV";
|
||||
case SpvCapabilityComputeDerivativeGroupLinearNV:
|
||||
return "ComputeDerivativeGroupLinearNV";
|
||||
case SpvCapabilityFragmentDensityEXT:
|
||||
return "FragmentDensityEXT";
|
||||
case SpvCapabilityPhysicalStorageBufferAddressesEXT:
|
||||
return "PhysicalStorageBufferAddressesEXT";
|
||||
case SpvCapabilityCooperativeMatrixNV:
|
||||
return "CooperativeMatrixNV";
|
||||
case SpvCapabilityFragmentShaderSampleInterlockEXT:
|
||||
return "FragmentShaderSampleInterlockEXT";
|
||||
case SpvCapabilityFragmentShaderShadingRateInterlockEXT:
|
||||
return "FragmentShaderShadingRateInterlockEXT";
|
||||
case SpvCapabilityFragmentShaderPixelInterlockEXT:
|
||||
return "FragmentShaderPixelInterlockEXT";
|
||||
case SpvCapabilityShaderSMBuiltinsNV:
|
||||
return "ShaderSMBuiltinsNV";
|
||||
case SpvCapabilityMax:
|
||||
assert(0 && "Attempting to convert SpvCapabilityMax to string");
|
||||
return "";
|
||||
|
||||
@@ -17,6 +17,7 @@ kSPV_EXT_shader_stencil_export,
|
||||
kSPV_EXT_shader_viewport_index_layer,
|
||||
kSPV_GOOGLE_decorate_string,
|
||||
kSPV_GOOGLE_hlsl_functionality1,
|
||||
kSPV_GOOGLE_user_type,
|
||||
kSPV_INTEL_device_side_avc_motion_estimation,
|
||||
kSPV_INTEL_media_block_io,
|
||||
kSPV_INTEL_shader_integer_functions2,
|
||||
|
||||
@@ -99,6 +99,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_stencil_expo
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layer[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer};
|
||||
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};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation[] = {spvtools::Extension::kSPV_INTEL_device_side_avc_motion_estimation};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_media_block_io[] = {spvtools::Extension::kSPV_INTEL_media_block_io};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_INTEL_shader_integer_functions2[] = {spvtools::Extension::kSPV_INTEL_shader_integer_functions2};
|
||||
@@ -145,10 +146,10 @@ static const spv_operand_desc_t pygen_variable_ImageOperandsEntries[] = {
|
||||
{"ConstOffsets", 0x0020, 1, pygen_variable_caps_ImageGatherExtended, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Sample", 0x0040, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MinLod", 0x0080, 1, pygen_variable_caps_MinLod, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MakeTexelAvailableKHR", 0x0100, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MakeTexelVisibleKHR", 0x0200, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"NonPrivateTexelKHR", 0x0400, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"VolatileTexelKHR", 0x0800, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MakeTexelAvailableKHR", 0x0100, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
|
||||
{"MakeTexelVisibleKHR", 0x0200, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
|
||||
{"NonPrivateTexelKHR", 0x0400, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"VolatileTexelKHR", 0x0800, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SignExtend", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
|
||||
{"ZeroExtend", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}
|
||||
};
|
||||
@@ -202,9 +203,10 @@ static const spv_operand_desc_t pygen_variable_MemorySemanticsEntries[] = {
|
||||
{"CrossWorkgroupMemory", 0x0200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"AtomicCounterMemory", 0x0400, 1, pygen_variable_caps_AtomicStorage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"ImageMemory", 0x0800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"OutputMemoryKHR", 0x1000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MakeAvailableKHR", 0x2000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MakeVisibleKHR", 0x4000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"OutputMemoryKHR", 0x1000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MakeAvailableKHR", 0x2000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MakeVisibleKHR", 0x4000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"Volatile", 0x8000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_MemoryAccessEntries[] = {
|
||||
@@ -212,9 +214,9 @@ static const spv_operand_desc_t pygen_variable_MemoryAccessEntries[] = {
|
||||
{"Volatile", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Aligned", 0x0002, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Nontemporal", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MakePointerAvailableKHR", 0x0008, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MakePointerVisibleKHR", 0x0010, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"NonPrivatePointerKHR", 0x0020, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"MakePointerAvailableKHR", 0x0008, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
|
||||
{"MakePointerVisibleKHR", 0x0010, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
|
||||
{"NonPrivatePointerKHR", 0x0020, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_KernelProfilingInfoEntries[] = {
|
||||
@@ -239,28 +241,28 @@ static const spv_operand_desc_t pygen_variable_ExecutionModelEntries[] = {
|
||||
{"Fragment", 4, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"GLCompute", 5, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Kernel", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"TaskNV", 5267, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MeshNV", 5268, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"RayGenerationNV", 5313, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"IntersectionNV", 5314, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"AnyHitNV", 5315, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"ClosestHitNV", 5316, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"MissNV", 5317, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"CallableNV", 5318, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"TaskNV", 5267, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MeshNV", 5268, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayGenerationNV", 5313, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IntersectionNV", 5314, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"AnyHitNV", 5315, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ClosestHitNV", 5316, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MissNV", 5317, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CallableNV", 5318, 1, pygen_variable_caps_RayTracingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_AddressingModelEntries[] = {
|
||||
{"Logical", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Physical32", 1, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Physical64", 2, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_MemoryModelEntries[] = {
|
||||
{"Simple", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"GLSL450", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"OpenCL", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"VulkanKHR", 3, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"VulkanKHR", 3, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = {
|
||||
@@ -336,13 +338,13 @@ 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},
|
||||
{"CallableDataNV", 5328, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"IncomingCallableDataNV", 5329, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"RayPayloadNV", 5338, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"HitAttributeNV", 5339, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"IncomingRayPayloadNV", 5342, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"ShaderRecordBufferNV", 5343, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"CallableDataNV", 5328, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingCallableDataNV", 5329, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayPayloadNV", 5338, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitAttributeNV", 5339, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayPayloadNV", 5342, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ShaderRecordBufferNV", 5343, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_DimEntries[] = {
|
||||
@@ -548,7 +550,8 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = {
|
||||
{"CounterBuffer", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
|
||||
{"HlslCounterBufferGOOGLE", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu},
|
||||
{"UserSemantic", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
|
||||
{"HlslSemanticGOOGLE", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}
|
||||
{"HlslSemanticGOOGLE", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu},
|
||||
{"UserTypeGOOGLE", 5636, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_user_type, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
|
||||
@@ -636,24 +639,24 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
|
||||
{"FragmentSizeNV", 5292, 2, pygen_variable_caps_ShadingRateNVFragmentDensityEXT, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"FragInvocationCountEXT", 5293, 2, pygen_variable_caps_FragmentDensityEXTShadingRateNV, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"InvocationsPerPixelNV", 5293, 2, pygen_variable_caps_ShadingRateNVFragmentDensityEXT, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchIdNV", 5319, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"LaunchSizeNV", 5320, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"WorldRayOriginNV", 5321, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"WorldRayDirectionNV", 5322, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"ObjectRayOriginNV", 5323, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"ObjectRayDirectionNV", 5324, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"RayTminNV", 5325, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"RayTmaxNV", 5326, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"InstanceCustomIndexNV", 5327, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"ObjectToWorldNV", 5330, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"WorldToObjectNV", 5331, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"HitTNV", 5332, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"HitKindNV", 5333, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"IncomingRayFlagsNV", 5351, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"WarpsPerSMNV", 5374, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"SMCountNV", 5375, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"WarpIDNV", 5376, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"SMIDNV", 5377, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"LaunchIdNV", 5319, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchSizeNV", 5320, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayOriginNV", 5321, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayDirectionNV", 5322, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayOriginNV", 5323, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayDirectionNV", 5324, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTminNV", 5325, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTmaxNV", 5326, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"InstanceCustomIndexNV", 5327, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectToWorldNV", 5330, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldToObjectNV", 5331, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitTNV", 5332, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitKindNV", 5333, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayFlagsNV", 5351, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WarpsPerSMNV", 5374, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SMCountNV", 5375, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WarpIDNV", 5376, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SMIDNV", 5377, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_ScopeEntries[] = {
|
||||
@@ -662,7 +665,7 @@ static const spv_operand_desc_t pygen_variable_ScopeEntries[] = {
|
||||
{"Workgroup", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Subgroup", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"Invocation", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
|
||||
{"QueueFamilyKHR", 5, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
|
||||
{"QueueFamilyKHR", 5, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_GroupOperationEntries[] = {
|
||||
|
||||
@@ -30,8 +30,8 @@ if(SPIRV_BUILD_FUZZER)
|
||||
fuzzer.h
|
||||
fuzzer_context.h
|
||||
fuzzer_pass.h
|
||||
fuzzer_pass_add_useful_constructs.h
|
||||
fuzzer_pass_add_dead_breaks.h
|
||||
fuzzer_pass_add_useful_constructs.h
|
||||
fuzzer_pass_permute_blocks.h
|
||||
fuzzer_pass_split_blocks.h
|
||||
fuzzer_util.h
|
||||
@@ -39,6 +39,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
protobufs/spirvfuzz_protobufs.h
|
||||
pseudo_random_generator.h
|
||||
random_generator.h
|
||||
replayer.h
|
||||
transformation_add_constant_boolean.h
|
||||
transformation_add_constant_scalar.h
|
||||
transformation_add_dead_break.h
|
||||
@@ -48,6 +49,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
transformation_move_block_down.h
|
||||
transformation_replace_boolean_constant_with_constant_binary.h
|
||||
transformation_split_block.h
|
||||
uniform_buffer_element_descriptor.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.h
|
||||
|
||||
fact_manager.cpp
|
||||
@@ -62,6 +64,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
id_use_descriptor.cpp
|
||||
pseudo_random_generator.cpp
|
||||
random_generator.cpp
|
||||
replayer.cpp
|
||||
transformation_add_constant_boolean.cpp
|
||||
transformation_add_constant_scalar.cpp
|
||||
transformation_add_dead_break.cpp
|
||||
@@ -71,6 +74,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
transformation_move_block_down.cpp
|
||||
transformation_replace_boolean_constant_with_constant_binary.cpp
|
||||
transformation_split_block.cpp
|
||||
uniform_buffer_element_descriptor.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.cc
|
||||
)
|
||||
|
||||
|
||||
274
3rdparty/spirv-tools/source/fuzz/fact_manager.cpp
vendored
274
3rdparty/spirv-tools/source/fuzz/fact_manager.cpp
vendored
@@ -12,15 +12,242 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "source/fuzz/fact_manager.h"
|
||||
|
||||
#include "source/fuzz/uniform_buffer_element_descriptor.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
FactManager::FactManager() = default;
|
||||
// The purpose of this struct is to group the fields and data used to represent
|
||||
// facts about uniform constants.
|
||||
struct FactManager::ConstantUniformFacts {
|
||||
// See method in FactManager which delegates to this method.
|
||||
bool AddFact(const protobufs::FactConstantUniform& fact,
|
||||
opt::IRContext* context);
|
||||
|
||||
// See method in FactManager which delegates to this method.
|
||||
std::vector<uint32_t> GetConstantsAvailableFromUniformsForType(
|
||||
opt::IRContext* ir_context, uint32_t type_id) const;
|
||||
|
||||
// See method in FactManager which delegates to this method.
|
||||
const std::vector<protobufs::UniformBufferElementDescriptor>
|
||||
GetUniformDescriptorsForConstant(opt::IRContext* ir_context,
|
||||
uint32_t constant_id) const;
|
||||
|
||||
// See method in FactManager which delegates to this method.
|
||||
uint32_t GetConstantFromUniformDescriptor(
|
||||
opt::IRContext* context,
|
||||
const protobufs::UniformBufferElementDescriptor& uniform_descriptor)
|
||||
const;
|
||||
|
||||
// See method in FactManager which delegates to this method.
|
||||
std::vector<uint32_t> GetTypesForWhichUniformValuesAreKnown() const;
|
||||
|
||||
// Returns true if and only if the words associated with
|
||||
// |constant_instruction| exactly match the words for the constant associated
|
||||
// with |constant_uniform_fact|.
|
||||
bool DataMatches(
|
||||
const opt::Instruction& constant_instruction,
|
||||
const protobufs::FactConstantUniform& constant_uniform_fact) const;
|
||||
|
||||
// Yields the constant words associated with |constant_uniform_fact|.
|
||||
std::vector<uint32_t> GetConstantWords(
|
||||
const protobufs::FactConstantUniform& constant_uniform_fact) const;
|
||||
|
||||
// Yields the id of a constant of type |type_id| whose data matches the
|
||||
// constant data in |constant_uniform_fact|, or 0 if no such constant is
|
||||
// declared.
|
||||
uint32_t GetConstantId(
|
||||
opt::IRContext* context,
|
||||
const protobufs::FactConstantUniform& constant_uniform_fact,
|
||||
uint32_t type_id) const;
|
||||
|
||||
std::vector<std::pair<protobufs::FactConstantUniform, uint32_t>>
|
||||
facts_and_type_ids;
|
||||
};
|
||||
|
||||
uint32_t FactManager::ConstantUniformFacts::GetConstantId(
|
||||
opt::IRContext* context,
|
||||
const protobufs::FactConstantUniform& constant_uniform_fact,
|
||||
uint32_t type_id) const {
|
||||
auto type = context->get_type_mgr()->GetType(type_id);
|
||||
assert(type != nullptr && "Unknown type id.");
|
||||
auto constant = context->get_constant_mgr()->GetConstant(
|
||||
type, GetConstantWords(constant_uniform_fact));
|
||||
return context->get_constant_mgr()->FindDeclaredConstant(constant, type_id);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> FactManager::ConstantUniformFacts::GetConstantWords(
|
||||
const protobufs::FactConstantUniform& constant_uniform_fact) const {
|
||||
std::vector<uint32_t> result;
|
||||
for (auto constant_word : constant_uniform_fact.constant_word()) {
|
||||
result.push_back(constant_word);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FactManager::ConstantUniformFacts::DataMatches(
|
||||
const opt::Instruction& constant_instruction,
|
||||
const protobufs::FactConstantUniform& constant_uniform_fact) const {
|
||||
assert(constant_instruction.opcode() == SpvOpConstant);
|
||||
std::vector<uint32_t> data_in_constant;
|
||||
for (uint32_t i = 0; i < constant_instruction.NumInOperands(); i++) {
|
||||
data_in_constant.push_back(constant_instruction.GetSingleWordInOperand(i));
|
||||
}
|
||||
return data_in_constant == GetConstantWords(constant_uniform_fact);
|
||||
}
|
||||
|
||||
std::vector<uint32_t>
|
||||
FactManager::ConstantUniformFacts::GetConstantsAvailableFromUniformsForType(
|
||||
opt::IRContext* ir_context, uint32_t type_id) const {
|
||||
std::vector<uint32_t> result;
|
||||
std::set<uint32_t> already_seen;
|
||||
for (auto& fact_and_type_id : facts_and_type_ids) {
|
||||
if (fact_and_type_id.second != type_id) {
|
||||
continue;
|
||||
}
|
||||
if (auto constant_id =
|
||||
GetConstantId(ir_context, fact_and_type_id.first, type_id)) {
|
||||
if (already_seen.find(constant_id) == already_seen.end()) {
|
||||
result.push_back(constant_id);
|
||||
already_seen.insert(constant_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::vector<protobufs::UniformBufferElementDescriptor>
|
||||
FactManager::ConstantUniformFacts::GetUniformDescriptorsForConstant(
|
||||
opt::IRContext* ir_context, uint32_t constant_id) const {
|
||||
std::vector<protobufs::UniformBufferElementDescriptor> result;
|
||||
auto constant_inst = ir_context->get_def_use_mgr()->GetDef(constant_id);
|
||||
assert(constant_inst->opcode() == SpvOpConstant &&
|
||||
"The given id must be that of a constant");
|
||||
auto type_id = constant_inst->type_id();
|
||||
for (auto& fact_and_type_id : facts_and_type_ids) {
|
||||
if (fact_and_type_id.second != type_id) {
|
||||
continue;
|
||||
}
|
||||
if (DataMatches(*constant_inst, fact_and_type_id.first)) {
|
||||
result.emplace_back(
|
||||
fact_and_type_id.first.uniform_buffer_element_descriptor());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t FactManager::ConstantUniformFacts::GetConstantFromUniformDescriptor(
|
||||
opt::IRContext* context,
|
||||
const protobufs::UniformBufferElementDescriptor& uniform_descriptor) const {
|
||||
// Consider each fact.
|
||||
for (auto& fact_and_type : facts_and_type_ids) {
|
||||
// Check whether the uniform descriptor associated with the fact matches
|
||||
// |uniform_descriptor|.
|
||||
if (UniformBufferElementDescriptorEquals()(
|
||||
&uniform_descriptor,
|
||||
&fact_and_type.first.uniform_buffer_element_descriptor())) {
|
||||
return GetConstantId(context, fact_and_type.first, fact_and_type.second);
|
||||
}
|
||||
}
|
||||
// No fact associated with the given uniform descriptor was found.
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<uint32_t>
|
||||
FactManager::ConstantUniformFacts::GetTypesForWhichUniformValuesAreKnown()
|
||||
const {
|
||||
std::vector<uint32_t> result;
|
||||
for (auto& fact_and_type : facts_and_type_ids) {
|
||||
if (std::find(result.begin(), result.end(), fact_and_type.second) ==
|
||||
result.end()) {
|
||||
result.push_back(fact_and_type.second);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FactManager::ConstantUniformFacts::AddFact(
|
||||
const protobufs::FactConstantUniform& fact, opt::IRContext* context) {
|
||||
auto should_be_uniform_variable = context->get_def_use_mgr()->GetDef(
|
||||
fact.uniform_buffer_element_descriptor().uniform_variable_id());
|
||||
if (!should_be_uniform_variable) {
|
||||
return false;
|
||||
}
|
||||
if (SpvOpVariable != should_be_uniform_variable->opcode()) {
|
||||
return false;
|
||||
}
|
||||
if (SpvStorageClassUniform !=
|
||||
should_be_uniform_variable->GetSingleWordInOperand(0)) {
|
||||
return false;
|
||||
}
|
||||
auto should_be_uniform_pointer_type =
|
||||
context->get_type_mgr()->GetType(should_be_uniform_variable->type_id());
|
||||
if (!should_be_uniform_pointer_type->AsPointer()) {
|
||||
return false;
|
||||
}
|
||||
if (should_be_uniform_pointer_type->AsPointer()->storage_class() !=
|
||||
SpvStorageClassUniform) {
|
||||
return false;
|
||||
}
|
||||
auto should_be_uniform_pointer_instruction =
|
||||
context->get_def_use_mgr()->GetDef(should_be_uniform_variable->type_id());
|
||||
auto element_type =
|
||||
should_be_uniform_pointer_instruction->GetSingleWordInOperand(1);
|
||||
|
||||
for (auto index : fact.uniform_buffer_element_descriptor().index()) {
|
||||
auto should_be_composite_type =
|
||||
context->get_def_use_mgr()->GetDef(element_type);
|
||||
if (SpvOpTypeStruct == should_be_composite_type->opcode()) {
|
||||
if (index >= should_be_composite_type->NumInOperands()) {
|
||||
return false;
|
||||
}
|
||||
element_type = should_be_composite_type->GetSingleWordInOperand(index);
|
||||
} else if (SpvOpTypeArray == should_be_composite_type->opcode()) {
|
||||
auto array_length_constant =
|
||||
context->get_constant_mgr()
|
||||
->GetConstantFromInst(context->get_def_use_mgr()->GetDef(
|
||||
should_be_composite_type->GetSingleWordInOperand(1)))
|
||||
->AsIntConstant();
|
||||
if (array_length_constant->words().size() != 1) {
|
||||
return false;
|
||||
}
|
||||
auto array_length = array_length_constant->GetU32();
|
||||
if (index >= array_length) {
|
||||
return false;
|
||||
}
|
||||
element_type = should_be_composite_type->GetSingleWordInOperand(0);
|
||||
} else if (SpvOpTypeVector == should_be_composite_type->opcode()) {
|
||||
auto vector_length = should_be_composite_type->GetSingleWordInOperand(1);
|
||||
if (index >= vector_length) {
|
||||
return false;
|
||||
}
|
||||
element_type = should_be_composite_type->GetSingleWordInOperand(0);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto final_element_type = context->get_type_mgr()->GetType(element_type);
|
||||
if (!(final_element_type->AsFloat() || final_element_type->AsInteger())) {
|
||||
return false;
|
||||
}
|
||||
auto width = final_element_type->AsFloat()
|
||||
? final_element_type->AsFloat()->width()
|
||||
: final_element_type->AsInteger()->width();
|
||||
auto required_words = (width + 32 - 1) / 32;
|
||||
if (static_cast<uint32_t>(fact.constant_word().size()) != required_words) {
|
||||
return false;
|
||||
}
|
||||
facts_and_type_ids.emplace_back(
|
||||
std::pair<protobufs::FactConstantUniform, uint32_t>(fact, element_type));
|
||||
return true;
|
||||
}
|
||||
|
||||
FactManager::FactManager() {
|
||||
uniform_constant_facts_ = MakeUnique<ConstantUniformFacts>();
|
||||
}
|
||||
|
||||
FactManager::~FactManager() = default;
|
||||
|
||||
@@ -36,11 +263,46 @@ bool FactManager::AddFacts(const protobufs::FactSequence& initial_facts,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FactManager::AddFact(const spvtools::fuzz::protobufs::Fact&,
|
||||
spvtools::opt::IRContext*) {
|
||||
assert(0 && "No facts are yet supported.");
|
||||
bool FactManager::AddFact(const spvtools::fuzz::protobufs::Fact& fact,
|
||||
spvtools::opt::IRContext* context) {
|
||||
assert(fact.fact_case() == protobufs::Fact::kConstantUniformFact &&
|
||||
"Right now this is the only fact.");
|
||||
if (!uniform_constant_facts_->AddFact(fact.constant_uniform_fact(),
|
||||
context)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> FactManager::GetConstantsAvailableFromUniformsForType(
|
||||
opt::IRContext* ir_context, uint32_t type_id) const {
|
||||
return uniform_constant_facts_->GetConstantsAvailableFromUniformsForType(
|
||||
ir_context, type_id);
|
||||
}
|
||||
|
||||
const std::vector<protobufs::UniformBufferElementDescriptor>
|
||||
FactManager::GetUniformDescriptorsForConstant(opt::IRContext* ir_context,
|
||||
uint32_t constant_id) const {
|
||||
return uniform_constant_facts_->GetUniformDescriptorsForConstant(ir_context,
|
||||
constant_id);
|
||||
}
|
||||
|
||||
uint32_t FactManager::GetConstantFromUniformDescriptor(
|
||||
opt::IRContext* context,
|
||||
const protobufs::UniformBufferElementDescriptor& uniform_descriptor) const {
|
||||
return uniform_constant_facts_->GetConstantFromUniformDescriptor(
|
||||
context, uniform_descriptor);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> FactManager::GetTypesForWhichUniformValuesAreKnown()
|
||||
const {
|
||||
return uniform_constant_facts_->GetTypesForWhichUniformValuesAreKnown();
|
||||
}
|
||||
|
||||
const std::vector<std::pair<protobufs::FactConstantUniform, uint32_t>>&
|
||||
FactManager::GetConstantUniformFactsAndTypes() const {
|
||||
return uniform_constant_facts_->facts_and_type_ids;
|
||||
}
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
|
||||
56
3rdparty/spirv-tools/source/fuzz/fact_manager.h
vendored
56
3rdparty/spirv-tools/source/fuzz/fact_manager.h
vendored
@@ -15,7 +15,9 @@
|
||||
#ifndef SOURCE_FUZZ_FACT_MANAGER_H_
|
||||
#define SOURCE_FUZZ_FACT_MANAGER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||
#include "source/opt/constants.h"
|
||||
@@ -45,6 +47,60 @@ class FactManager {
|
||||
// Adds |fact| to the fact manager, checking it for validity with respect to
|
||||
// |context|. Returns true if and only if the fact is valid.
|
||||
bool AddFact(const protobufs::Fact& fact, opt::IRContext* context);
|
||||
|
||||
// The fact manager will ultimately be responsible for managing a few distinct
|
||||
// categories of facts. In principle there could be different fact managers
|
||||
// for each kind of fact, but in practice providing one 'go to' place for
|
||||
// facts will be convenient. To keep some separation, the public methods of
|
||||
// the fact manager should be grouped according to the kind of fact to which
|
||||
// they relate. At present we only have one kind of fact: facts about
|
||||
// uniform variables.
|
||||
|
||||
//==============================
|
||||
// Querying facts about uniform constants
|
||||
|
||||
// Provides the distinct type ids for which at least one "constant ==
|
||||
// uniform element" fact is known.
|
||||
std::vector<uint32_t> GetTypesForWhichUniformValuesAreKnown() const;
|
||||
|
||||
// Provides distinct constant ids with type |type_id| for which at least one
|
||||
// "constant == uniform element" fact is known. If multiple identically-
|
||||
// valued constants are relevant, only one will appear in the sequence.
|
||||
std::vector<uint32_t> GetConstantsAvailableFromUniformsForType(
|
||||
opt::IRContext* ir_context, uint32_t type_id) const;
|
||||
|
||||
// Provides details of all uniform elements that are known to be equal to the
|
||||
// constant associated with |constant_id| in |ir_context|.
|
||||
const std::vector<protobufs::UniformBufferElementDescriptor>
|
||||
GetUniformDescriptorsForConstant(opt::IRContext* ir_context,
|
||||
uint32_t constant_id) const;
|
||||
|
||||
// Returns the id of a constant whose value is known to match that of
|
||||
// |uniform_descriptor|, and whose type matches the type of the uniform
|
||||
// element. If multiple such constant is exist, the one that is returned
|
||||
// is arbitrary. Returns 0 if no such constant id exists.
|
||||
uint32_t GetConstantFromUniformDescriptor(
|
||||
opt::IRContext* context,
|
||||
const protobufs::UniformBufferElementDescriptor& uniform_descriptor)
|
||||
const;
|
||||
|
||||
// Returns all "constant == uniform element" facts known to the fact
|
||||
// manager, pairing each fact with id of the type that is associated with
|
||||
// both the constant and the uniform element.
|
||||
const std::vector<std::pair<protobufs::FactConstantUniform, uint32_t>>&
|
||||
GetConstantUniformFactsAndTypes() const;
|
||||
|
||||
// End of uniform constant facts
|
||||
//==============================
|
||||
|
||||
private:
|
||||
// For each distinct kind of fact to be managed, we use a separate opaque
|
||||
// struct type.
|
||||
|
||||
struct ConstantUniformFacts; // Opaque struct for holding data about uniform
|
||||
// buffer elements.
|
||||
std::unique_ptr<ConstantUniformFacts>
|
||||
uniform_constant_facts_; // Unique pointer to internal data.
|
||||
};
|
||||
|
||||
} // namespace fuzz
|
||||
|
||||
@@ -57,12 +57,63 @@ message IdUseDescriptor {
|
||||
|
||||
}
|
||||
|
||||
message UniformBufferElementDescriptor {
|
||||
|
||||
// Represents a data element inside a uniform buffer. The element is
|
||||
// specified via (a) the result id of a uniform variable in which the element
|
||||
// is contained, and (b) a series of indices that need to be followed to get
|
||||
// to the element (via fields and array/vector indices).
|
||||
//
|
||||
// Example: suppose %42 is the id of a uniform variable, and that the uniform
|
||||
// variable has the following type (using GLSL-like syntax):
|
||||
//
|
||||
// struct S {
|
||||
// float f;
|
||||
// vec3 g;
|
||||
// int4 h[10];
|
||||
// };
|
||||
//
|
||||
// Then:
|
||||
// - 42[0] describes the 'f' field.
|
||||
// - 42[1,1] describes the y component of the 'g' field.
|
||||
// - 42[2,7,3] describes the w component of element 7 of the 'h' field
|
||||
|
||||
// The result id of a uniform variable.
|
||||
uint32 uniform_variable_id = 1;
|
||||
|
||||
// An ordered sequence of indices through composite structures in the
|
||||
// uniform buffer.
|
||||
repeated uint32 index = 2;
|
||||
|
||||
}
|
||||
|
||||
message FactSequence {
|
||||
repeated Fact fact = 1;
|
||||
}
|
||||
|
||||
message Fact {
|
||||
// Currently there are no facts.
|
||||
oneof fact {
|
||||
// Order the fact options by numeric id (rather than alphabetically).
|
||||
FactConstantUniform constant_uniform_fact = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep fact message types in alphabetical order:
|
||||
|
||||
message FactConstantUniform {
|
||||
|
||||
// Records the fact that a uniform buffer element is guaranteed to be equal
|
||||
// to a particular constant value. spirv-fuzz can use such guarantees to
|
||||
// obfuscate code, e.g. to manufacture an expression that will (due to the
|
||||
// guarantee) evaluate to a particular value at runtime but in a manner that
|
||||
// cannot be predicted at compile-time.
|
||||
|
||||
// An element of a uniform buffer
|
||||
UniformBufferElementDescriptor uniform_buffer_element_descriptor = 1;
|
||||
|
||||
// The words of the associated constant
|
||||
repeated uint32 constant_word = 2;
|
||||
|
||||
}
|
||||
|
||||
message TransformationSequence {
|
||||
|
||||
200
3rdparty/spirv-tools/source/fuzz/replayer.cpp
vendored
Normal file
200
3rdparty/spirv-tools/source/fuzz/replayer.cpp
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
// Copyright (c) 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/fuzz/replayer.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "source/fuzz/fact_manager.h"
|
||||
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||
#include "source/fuzz/transformation_add_constant_boolean.h"
|
||||
#include "source/fuzz/transformation_add_constant_scalar.h"
|
||||
#include "source/fuzz/transformation_add_dead_break.h"
|
||||
#include "source/fuzz/transformation_add_type_boolean.h"
|
||||
#include "source/fuzz/transformation_add_type_float.h"
|
||||
#include "source/fuzz/transformation_add_type_int.h"
|
||||
#include "source/fuzz/transformation_move_block_down.h"
|
||||
#include "source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h"
|
||||
#include "source/fuzz/transformation_split_block.h"
|
||||
#include "source/opt/build_module.h"
|
||||
#include "source/util/make_unique.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
namespace {
|
||||
|
||||
// Returns true if and only if the precondition for |transformation| holds, with
|
||||
// respect to the given |context| and |fact_manager|.
|
||||
bool IsApplicable(const protobufs::Transformation& transformation,
|
||||
opt::IRContext* context, const FactManager& fact_manager) {
|
||||
switch (transformation.transformation_case()) {
|
||||
case protobufs::Transformation::TransformationCase::kAddConstantBoolean:
|
||||
return transformation::IsApplicable(transformation.add_constant_boolean(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::kAddConstantScalar:
|
||||
return transformation::IsApplicable(transformation.add_constant_scalar(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::kAddDeadBreak:
|
||||
return transformation::IsApplicable(transformation.add_dead_break(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::kAddTypeBoolean:
|
||||
return transformation::IsApplicable(transformation.add_type_boolean(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::kAddTypeFloat:
|
||||
return transformation::IsApplicable(transformation.add_type_float(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::kAddTypeInt:
|
||||
return transformation::IsApplicable(transformation.add_type_int(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::kMoveBlockDown:
|
||||
return transformation::IsApplicable(transformation.move_block_down(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::
|
||||
kReplaceBooleanConstantWithConstantBinary:
|
||||
return transformation::IsApplicable(
|
||||
transformation.replace_boolean_constant_with_constant_binary(),
|
||||
context, fact_manager);
|
||||
case protobufs::Transformation::TransformationCase::kSplitBlock:
|
||||
return transformation::IsApplicable(transformation.split_block(), context,
|
||||
fact_manager);
|
||||
default:
|
||||
assert(transformation.transformation_case() ==
|
||||
protobufs::Transformation::TRANSFORMATION_NOT_SET &&
|
||||
"Unhandled transformation type.");
|
||||
assert(false && "An unset transformation was encountered.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Requires that IsApplicable holds. Applies |transformation| to the given
|
||||
// |context| and |fact_manager|.
|
||||
void Apply(const protobufs::Transformation& transformation,
|
||||
opt::IRContext* context, FactManager* fact_manager) {
|
||||
switch (transformation.transformation_case()) {
|
||||
case protobufs::Transformation::TransformationCase::kAddConstantBoolean:
|
||||
transformation::Apply(transformation.add_constant_boolean(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::kAddConstantScalar:
|
||||
transformation::Apply(transformation.add_constant_scalar(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::kAddDeadBreak:
|
||||
transformation::Apply(transformation.add_dead_break(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::kAddTypeBoolean:
|
||||
transformation::Apply(transformation.add_type_boolean(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::kAddTypeFloat:
|
||||
transformation::Apply(transformation.add_type_float(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::kAddTypeInt:
|
||||
transformation::Apply(transformation.add_type_int(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::kMoveBlockDown:
|
||||
transformation::Apply(transformation.move_block_down(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::
|
||||
kReplaceBooleanConstantWithConstantBinary:
|
||||
transformation::Apply(
|
||||
transformation.replace_boolean_constant_with_constant_binary(),
|
||||
context, fact_manager);
|
||||
break;
|
||||
case protobufs::Transformation::TransformationCase::kSplitBlock:
|
||||
transformation::Apply(transformation.split_block(), context,
|
||||
fact_manager);
|
||||
break;
|
||||
default:
|
||||
assert(transformation.transformation_case() ==
|
||||
protobufs::Transformation::TRANSFORMATION_NOT_SET &&
|
||||
"Unhandled transformation type.");
|
||||
assert(false && "An unset transformation was encountered.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
struct Replayer::Impl {
|
||||
explicit Impl(spv_target_env env) : target_env(env) {}
|
||||
|
||||
const spv_target_env target_env; // Target environment.
|
||||
MessageConsumer consumer; // Message consumer.
|
||||
};
|
||||
|
||||
Replayer::Replayer(spv_target_env env) : impl_(MakeUnique<Impl>(env)) {}
|
||||
|
||||
Replayer::~Replayer() = default;
|
||||
|
||||
void Replayer::SetMessageConsumer(MessageConsumer c) {
|
||||
impl_->consumer = std::move(c);
|
||||
}
|
||||
|
||||
Replayer::ReplayerResultStatus Replayer::Run(
|
||||
const std::vector<uint32_t>& binary_in,
|
||||
const protobufs::FactSequence& initial_facts,
|
||||
const protobufs::TransformationSequence& transformation_sequence_in,
|
||||
std::vector<uint32_t>* binary_out,
|
||||
protobufs::TransformationSequence* transformation_sequence_out) const {
|
||||
// Check compatibility between the library version being linked with and the
|
||||
// header files being used.
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
spvtools::SpirvTools tools(impl_->target_env);
|
||||
if (!tools.IsValid()) {
|
||||
impl_->consumer(SPV_MSG_ERROR, nullptr, {},
|
||||
"Failed to create SPIRV-Tools interface; stopping.");
|
||||
return Replayer::ReplayerResultStatus::kFailedToCreateSpirvToolsInterface;
|
||||
}
|
||||
|
||||
// Initial binary should be valid.
|
||||
if (!tools.Validate(&binary_in[0], binary_in.size())) {
|
||||
impl_->consumer(SPV_MSG_INFO, nullptr, {},
|
||||
"Initial binary is invalid; stopping.");
|
||||
return Replayer::ReplayerResultStatus::kInitialBinaryInvalid;
|
||||
}
|
||||
|
||||
// Build the module from the input binary.
|
||||
std::unique_ptr<opt::IRContext> ir_context = BuildModule(
|
||||
impl_->target_env, impl_->consumer, binary_in.data(), binary_in.size());
|
||||
assert(ir_context);
|
||||
|
||||
FactManager fact_manager;
|
||||
if (!fact_manager.AddFacts(initial_facts, ir_context.get())) {
|
||||
return Replayer::ReplayerResultStatus::kInitialFactsInvalid;
|
||||
}
|
||||
|
||||
// Consider the transformation proto messages in turn.
|
||||
for (auto& transformation : transformation_sequence_in.transformation()) {
|
||||
// Check whether the transformation can be applied.
|
||||
if (IsApplicable(transformation, ir_context.get(), fact_manager)) {
|
||||
// The transformation is applicable, so apply it, and copy it to the
|
||||
// sequence of transformations that were applied.
|
||||
Apply(transformation, ir_context.get(), &fact_manager);
|
||||
*transformation_sequence_out->add_transformation() = transformation;
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the module as a binary.
|
||||
ir_context->module()->ToBinary(binary_out, false);
|
||||
return Replayer::ReplayerResultStatus::kComplete;
|
||||
}
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
74
3rdparty/spirv-tools/source/fuzz/replayer.h
vendored
Normal file
74
3rdparty/spirv-tools/source/fuzz/replayer.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SOURCE_FUZZ_REPLAYER_H_
|
||||
#define SOURCE_FUZZ_REPLAYER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||
#include "spirv-tools/libspirv.hpp"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
// Transforms a SPIR-V module into a semantically equivalent SPIR-V module by
|
||||
// applying a series of pre-defined transformations.
|
||||
class Replayer {
|
||||
public:
|
||||
// Possible statuses that can result from running the replayer.
|
||||
enum ReplayerResultStatus {
|
||||
kComplete,
|
||||
kFailedToCreateSpirvToolsInterface,
|
||||
kInitialBinaryInvalid,
|
||||
kInitialFactsInvalid,
|
||||
};
|
||||
|
||||
// Constructs a replayer from the given target environment.
|
||||
explicit Replayer(spv_target_env env);
|
||||
|
||||
// Disables copy/move constructor/assignment operations.
|
||||
Replayer(const Replayer&) = delete;
|
||||
Replayer(Replayer&&) = delete;
|
||||
Replayer& operator=(const Replayer&) = delete;
|
||||
Replayer& operator=(Replayer&&) = delete;
|
||||
|
||||
~Replayer();
|
||||
|
||||
// Sets the message consumer to the given |consumer|. The |consumer| will be
|
||||
// invoked once for each message communicated from the library.
|
||||
void SetMessageConsumer(MessageConsumer consumer);
|
||||
|
||||
// Transforms |binary_in| to |binary_out| by attempting to apply the
|
||||
// transformations from |transformation_sequence_in|. Initial facts about the
|
||||
// input binary and the context in which it will execute are provided via
|
||||
// |initial_facts|. The transformations that were successfully applied are
|
||||
// returned via |transformation_sequence_out|.
|
||||
ReplayerResultStatus Run(
|
||||
const std::vector<uint32_t>& binary_in,
|
||||
const protobufs::FactSequence& initial_facts,
|
||||
const protobufs::TransformationSequence& transformation_sequence_in,
|
||||
std::vector<uint32_t>* binary_out,
|
||||
protobufs::TransformationSequence* transformation_sequence_out) const;
|
||||
|
||||
private:
|
||||
struct Impl; // Opaque struct for holding internal data.
|
||||
std::unique_ptr<Impl> impl_; // Unique pointer to internal data.
|
||||
};
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_FUZZ_REPLAYER_H_
|
||||
39
3rdparty/spirv-tools/source/fuzz/uniform_buffer_element_descriptor.cpp
vendored
Normal file
39
3rdparty/spirv-tools/source/fuzz/uniform_buffer_element_descriptor.cpp
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/fuzz/uniform_buffer_element_descriptor.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
protobufs::UniformBufferElementDescriptor MakeUniformBufferElementDescriptor(
|
||||
uint32_t uniform_variable_id, std::vector<uint32_t>&& indices) {
|
||||
protobufs::UniformBufferElementDescriptor result;
|
||||
result.set_uniform_variable_id(uniform_variable_id);
|
||||
for (auto index : indices) {
|
||||
result.add_index(index);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool UniformBufferElementDescriptorEquals::operator()(
|
||||
const protobufs::UniformBufferElementDescriptor* first,
|
||||
const protobufs::UniformBufferElementDescriptor* second) const {
|
||||
return first->uniform_variable_id() == second->uniform_variable_id() &&
|
||||
std::equal(first->index().begin(), first->index().end(),
|
||||
second->index().begin());
|
||||
}
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
41
3rdparty/spirv-tools/source/fuzz/uniform_buffer_element_descriptor.h
vendored
Normal file
41
3rdparty/spirv-tools/source/fuzz/uniform_buffer_element_descriptor.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SOURCE_FUZZ_UNIFORM_BUFFER_ELEMENT_DESCRIPTOR_H_
|
||||
#define SOURCE_FUZZ_UNIFORM_BUFFER_ELEMENT_DESCRIPTOR_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
// Factory method to create a uniform buffer element descriptor message from an
|
||||
// id and list of indices.
|
||||
protobufs::UniformBufferElementDescriptor MakeUniformBufferElementDescriptor(
|
||||
uint32_t uniform_variable_id, std::vector<uint32_t>&& indices);
|
||||
|
||||
// Equality function for uniform buffer element descriptors.
|
||||
struct UniformBufferElementDescriptorEquals {
|
||||
bool operator()(
|
||||
const protobufs::UniformBufferElementDescriptor* first,
|
||||
const protobufs::UniformBufferElementDescriptor* second) const;
|
||||
};
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // #define SOURCE_FUZZ_UNIFORM_BUFFER_ELEMENT_DESCRIPTOR_H_
|
||||
80
3rdparty/spirv-tools/source/opt/log.h
vendored
80
3rdparty/spirv-tools/source/opt/log.h
vendored
@@ -54,18 +54,19 @@
|
||||
|
||||
// Logs an error message to the consumer saying the given feature is
|
||||
// unimplemented.
|
||||
#define SPIRV_UNIMPLEMENTED(consumer, feature) \
|
||||
do { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{__LINE__, 0, 0}, "unimplemented: " feature); \
|
||||
#define SPIRV_UNIMPLEMENTED(consumer, feature) \
|
||||
do { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{static_cast<size_t>(__LINE__), 0, 0}, \
|
||||
"unimplemented: " feature); \
|
||||
} while (0)
|
||||
|
||||
// Logs an error message to the consumer saying the code location
|
||||
// should be unreachable.
|
||||
#define SPIRV_UNREACHABLE(consumer) \
|
||||
do { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{__LINE__, 0, 0}, "unreachable"); \
|
||||
#define SPIRV_UNREACHABLE(consumer) \
|
||||
do { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{static_cast<size_t>(__LINE__), 0, 0}, "unreachable"); \
|
||||
} while (0)
|
||||
|
||||
// Helper macros for concatenating arguments.
|
||||
@@ -154,32 +155,34 @@ inline void Errorf(const MessageConsumer& consumer, const char* source,
|
||||
PP_EXPAND(SPIRV_CONCATENATE(SPIRV_DEBUG_, PP_NARGS(__VA_ARGS__))( \
|
||||
consumer, __VA_ARGS__))
|
||||
|
||||
#define SPIRV_ASSERT_1(consumer, condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{__LINE__, 0, 0}, "assertion failed: " #condition); \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
} \
|
||||
#define SPIRV_ASSERT_1(consumer, condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{static_cast<size_t>(__LINE__), 0, 0}, \
|
||||
"assertion failed: " #condition); \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SPIRV_ASSERT_2(consumer, condition, message) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{__LINE__, 0, 0}, "assertion failed: " message); \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
} \
|
||||
#define SPIRV_ASSERT_2(consumer, condition, message) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{static_cast<size_t>(__LINE__), 0, 0}, \
|
||||
"assertion failed: " message); \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SPIRV_ASSERT_more(consumer, condition, format, ...) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
spvtools::Logf(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{__LINE__, 0, 0}, "assertion failed: " format, \
|
||||
__VA_ARGS__); \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
} \
|
||||
#define SPIRV_ASSERT_more(consumer, condition, format, ...) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
spvtools::Logf(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
|
||||
{static_cast<size_t>(__LINE__), 0, 0}, \
|
||||
"assertion failed: " format, __VA_ARGS__); \
|
||||
std::exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SPIRV_ASSERT_3(consumer, condition, format, ...) \
|
||||
@@ -191,16 +194,17 @@ inline void Errorf(const MessageConsumer& consumer, const char* source,
|
||||
#define SPIRV_ASSERT_5(consumer, condition, format, ...) \
|
||||
SPIRV_ASSERT_more(consumer, condition, format, __VA_ARGS__)
|
||||
|
||||
#define SPIRV_DEBUG_1(consumer, message) \
|
||||
do { \
|
||||
spvtools::Log(consumer, SPV_MSG_DEBUG, __FILE__, {__LINE__, 0, 0}, \
|
||||
message); \
|
||||
#define SPIRV_DEBUG_1(consumer, message) \
|
||||
do { \
|
||||
spvtools::Log(consumer, SPV_MSG_DEBUG, __FILE__, \
|
||||
{static_cast<size_t>(__LINE__), 0, 0}, message); \
|
||||
} while (0)
|
||||
|
||||
#define SPIRV_DEBUG_more(consumer, format, ...) \
|
||||
do { \
|
||||
spvtools::Logf(consumer, SPV_MSG_DEBUG, __FILE__, {__LINE__, 0, 0}, \
|
||||
format, __VA_ARGS__); \
|
||||
#define SPIRV_DEBUG_more(consumer, format, ...) \
|
||||
do { \
|
||||
spvtools::Logf(consumer, SPV_MSG_DEBUG, __FILE__, \
|
||||
{static_cast<size_t>(__LINE__), 0, 0}, format, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define SPIRV_DEBUG_2(consumer, format, ...) \
|
||||
|
||||
@@ -211,6 +211,17 @@ class BuiltInsValidator {
|
||||
spv_result_t ValidateSMBuiltinsAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
|
||||
// Used for SubgroupEqMask, SubgroupGeMask, SubgroupGtMask, SubgroupLtMask,
|
||||
// SubgroupLeMask.
|
||||
spv_result_t ValidateI32Vec4InputAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
// Used for SubgroupLocalInvocationId, SubgroupSize.
|
||||
spv_result_t ValidateI32InputAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
// Used for SubgroupId, NumSubgroups.
|
||||
spv_result_t ValidateComputeI32InputAtDefinition(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|
|
||||
@@ -333,6 +344,11 @@ class BuiltInsValidator {
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
// Used for SubgroupId and NumSubgroups.
|
||||
spv_result_t ValidateComputeI32InputAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidateSMBuiltinsAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
@@ -2603,6 +2619,171 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference(
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (decoration.struct_member_index() != Decoration::kInvalidMember) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " cannot be used as a member decoration ";
|
||||
}
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &decoration,
|
||||
&inst](const std::string& message) -> spv_result_t {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "According to the "
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " variable needs to be a 32-bit int "
|
||||
"vector. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Seed at reference checks with this built-in.
|
||||
return ValidateComputeI32InputAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference(
|
||||
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)
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " 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_) {
|
||||
bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute ||
|
||||
execution_model == SpvExecutionModelTaskNV ||
|
||||
execution_model == SpvExecutionModelMeshNV;
|
||||
if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be used only with GLCompute 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::ValidateComputeI32InputAtReference, this,
|
||||
decoration, built_in_inst, referenced_from_inst,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (decoration.struct_member_index() != Decoration::kInvalidMember) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " cannot be used as a member decoration ";
|
||||
}
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &decoration,
|
||||
&inst](const std::string& message) -> spv_result_t {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "According to the "
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " variable needs to be a 32-bit int. " << message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const SpvStorageClass storage_class = GetStorageClass(inst);
|
||||
if (storage_class != SpvStorageClassMax &&
|
||||
storage_class != SpvStorageClassInput) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " 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, inst, inst, inst) << " "
|
||||
<< GetStorageClassDesc(inst);
|
||||
}
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (decoration.struct_member_index() != Decoration::kInvalidMember) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " cannot be used as a member decoration ";
|
||||
}
|
||||
if (spv_result_t error = ValidateI32Vec(
|
||||
decoration, inst, 4,
|
||||
[this, &decoration,
|
||||
&inst](const std::string& message) -> spv_result_t {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "According to the "
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " variable needs to be a 4-component 32-bit int "
|
||||
"vector. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const SpvStorageClass storage_class = GetStorageClass(inst);
|
||||
if (storage_class != SpvStorageClassMax &&
|
||||
storage_class != SpvStorageClassInput) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " 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, inst, inst, inst) << " "
|
||||
<< GetStorageClassDesc(inst);
|
||||
}
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) {
|
||||
@@ -2788,6 +2969,21 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
case SpvBuiltInSamplePosition: {
|
||||
return ValidateSamplePositionAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInSubgroupId:
|
||||
case SpvBuiltInNumSubgroups: {
|
||||
return ValidateComputeI32InputAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInSubgroupLocalInvocationId:
|
||||
case SpvBuiltInSubgroupSize: {
|
||||
return ValidateI32InputAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInSubgroupEqMask:
|
||||
case SpvBuiltInSubgroupGeMask:
|
||||
case SpvBuiltInSubgroupGtMask:
|
||||
case SpvBuiltInSubgroupLeMask:
|
||||
case SpvBuiltInSubgroupLtMask: {
|
||||
return ValidateI32Vec4InputAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInTessCoord: {
|
||||
return ValidateTessCoordAtDefinition(decoration, inst);
|
||||
}
|
||||
@@ -2821,17 +3017,8 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
case SpvBuiltInEnqueuedWorkgroupSize:
|
||||
case SpvBuiltInGlobalOffset:
|
||||
case SpvBuiltInGlobalLinearId:
|
||||
case SpvBuiltInSubgroupSize:
|
||||
case SpvBuiltInSubgroupMaxSize:
|
||||
case SpvBuiltInNumSubgroups:
|
||||
case SpvBuiltInNumEnqueuedSubgroups:
|
||||
case SpvBuiltInSubgroupId:
|
||||
case SpvBuiltInSubgroupLocalInvocationId:
|
||||
case SpvBuiltInSubgroupEqMaskKHR:
|
||||
case SpvBuiltInSubgroupGeMaskKHR:
|
||||
case SpvBuiltInSubgroupGtMaskKHR:
|
||||
case SpvBuiltInSubgroupLeMaskKHR:
|
||||
case SpvBuiltInSubgroupLtMaskKHR:
|
||||
case SpvBuiltInBaseVertex:
|
||||
case SpvBuiltInBaseInstance:
|
||||
case SpvBuiltInDrawIndex:
|
||||
|
||||
@@ -422,6 +422,11 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
|
||||
<< "OpVariable Initializer <id> '" << _.getIdName(initializer_id)
|
||||
<< "' is not a constant or module-scope variable.";
|
||||
}
|
||||
if (initializer->type_id() != result_type->GetOperandAs<uint32_t>(2u)) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "Initializer type must match the type pointed to by the Result "
|
||||
"Type";
|
||||
}
|
||||
}
|
||||
|
||||
const auto storage_class =
|
||||
|
||||
@@ -17,7 +17,8 @@ if (${SPIRV_BUILD_FUZZER})
|
||||
set(SOURCES
|
||||
fuzz_test_util.h
|
||||
|
||||
fuzzer_test.cpp
|
||||
fuzzer_replayer_test.cpp
|
||||
fact_manager_test.cpp
|
||||
fuzz_test_util.cpp
|
||||
transformation_add_constant_boolean_test.cpp
|
||||
transformation_add_constant_scalar_test.cpp
|
||||
|
||||
534
3rdparty/spirv-tools/test/fuzz/fact_manager_test.cpp
vendored
Normal file
534
3rdparty/spirv-tools/test/fuzz/fact_manager_test.cpp
vendored
Normal file
@@ -0,0 +1,534 @@
|
||||
// Copyright (c) 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/fuzz/fact_manager.h"
|
||||
#include "source/fuzz/uniform_buffer_element_descriptor.h"
|
||||
#include "test/fuzz/fuzz_test_util.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
namespace {
|
||||
|
||||
using opt::analysis::BoolConstant;
|
||||
using opt::analysis::FloatConstant;
|
||||
using opt::analysis::IntConstant;
|
||||
using opt::analysis::ScalarConstant;
|
||||
|
||||
using opt::analysis::Bool;
|
||||
using opt::analysis::Float;
|
||||
using opt::analysis::Integer;
|
||||
using opt::analysis::Type;
|
||||
|
||||
bool AddFactHelper(
|
||||
FactManager* fact_manager, opt::IRContext* context,
|
||||
std::vector<uint32_t>&& words,
|
||||
const protobufs::UniformBufferElementDescriptor& descriptor) {
|
||||
protobufs::FactConstantUniform constant_uniform_fact;
|
||||
for (auto word : words) {
|
||||
constant_uniform_fact.add_constant_word(word);
|
||||
}
|
||||
*constant_uniform_fact.mutable_uniform_buffer_element_descriptor() =
|
||||
descriptor;
|
||||
protobufs::Fact fact;
|
||||
*fact.mutable_constant_uniform_fact() = constant_uniform_fact;
|
||||
return fact_manager->AddFact(fact, context);
|
||||
}
|
||||
|
||||
TEST(FactManagerTest, ConstantsAvailableViaUniforms) {
|
||||
std::string shader = R"(
|
||||
OpCapability Shader
|
||||
OpCapability Int64
|
||||
OpCapability Float64
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main"
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %4 "main"
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%10 = OpTypeInt 32 0
|
||||
%11 = OpTypeInt 32 1
|
||||
%12 = OpTypeInt 64 0
|
||||
%13 = OpTypeInt 64 1
|
||||
%15 = OpTypeFloat 32
|
||||
%16 = OpTypeFloat 64
|
||||
%17 = OpConstant %11 5
|
||||
%18 = OpConstant %11 20
|
||||
%19 = OpTypeVector %10 4
|
||||
%20 = OpConstant %11 6
|
||||
%21 = OpTypeVector %12 4
|
||||
%22 = OpConstant %11 10
|
||||
%23 = OpTypeVector %11 4
|
||||
|
||||
%102 = OpTypeStruct %10 %10 %23
|
||||
%101 = OpTypePointer Uniform %102
|
||||
%100 = OpVariable %101 Uniform
|
||||
|
||||
%203 = OpTypeArray %23 %17
|
||||
%202 = OpTypeArray %203 %18
|
||||
%201 = OpTypePointer Uniform %202
|
||||
%200 = OpVariable %201 Uniform
|
||||
|
||||
%305 = OpTypeStruct %16 %16 %16 %11 %16
|
||||
%304 = OpTypeStruct %16 %16 %305
|
||||
%303 = OpTypeStruct %304
|
||||
%302 = OpTypeStruct %10 %303
|
||||
%301 = OpTypePointer Uniform %302
|
||||
%300 = OpVariable %301 Uniform
|
||||
|
||||
%400 = OpVariable %101 Uniform
|
||||
|
||||
%500 = OpVariable %201 Uniform
|
||||
|
||||
%604 = OpTypeArray %13 %20
|
||||
%603 = OpTypeArray %604 %20
|
||||
%602 = OpTypeArray %603 %20
|
||||
%601 = OpTypePointer Uniform %602
|
||||
%600 = OpVariable %601 Uniform
|
||||
|
||||
%703 = OpTypeArray %13 %20
|
||||
%702 = OpTypeArray %703 %20
|
||||
%701 = OpTypePointer Uniform %702
|
||||
%700 = OpVariable %701 Uniform
|
||||
|
||||
%802 = OpTypeStruct %702 %602 %19 %202 %302
|
||||
%801 = OpTypePointer Uniform %802
|
||||
%800 = OpVariable %801 Uniform
|
||||
|
||||
%902 = OpTypeStruct %702 %802 %19 %202 %302
|
||||
%901 = OpTypePointer Uniform %902
|
||||
%900 = OpVariable %901 Uniform
|
||||
|
||||
%1003 = OpTypeStruct %802
|
||||
%1002 = OpTypeArray %1003 %20
|
||||
%1001 = OpTypePointer Uniform %1002
|
||||
%1000 = OpVariable %1001 Uniform
|
||||
|
||||
%1101 = OpTypePointer Uniform %21
|
||||
%1100 = OpVariable %1101 Uniform
|
||||
|
||||
%1202 = OpTypeArray %21 %20
|
||||
%1201 = OpTypePointer Uniform %1202
|
||||
%1200 = OpVariable %1201 Uniform
|
||||
|
||||
%1302 = OpTypeArray %21 %20
|
||||
%1301 = OpTypePointer Uniform %1302
|
||||
%1300 = OpVariable %1301 Uniform
|
||||
|
||||
%1402 = OpTypeArray %15 %22
|
||||
%1401 = OpTypePointer Uniform %1402
|
||||
%1400 = OpVariable %1401 Uniform
|
||||
|
||||
%1501 = OpTypePointer Uniform %1402
|
||||
%1500 = OpVariable %1501 Uniform
|
||||
|
||||
%1602 = OpTypeArray %1402 %22
|
||||
%1601 = OpTypePointer Uniform %1602
|
||||
%1600 = OpVariable %1601 Uniform
|
||||
|
||||
%1704 = OpTypeStruct %16 %16 %16
|
||||
%1703 = OpTypeArray %1704 %22
|
||||
%1702 = OpTypeArray %1703 %22
|
||||
%1701 = OpTypePointer Uniform %1702
|
||||
%1700 = OpVariable %1701 Uniform
|
||||
|
||||
%1800 = OpVariable %1701 Uniform
|
||||
|
||||
%1906 = OpTypeStruct %16
|
||||
%1905 = OpTypeStruct %1906
|
||||
%1904 = OpTypeStruct %1905
|
||||
%1903 = OpTypeStruct %1904
|
||||
%1902 = OpTypeStruct %1903
|
||||
%1901 = OpTypePointer Uniform %1902
|
||||
%1900 = OpVariable %1901 Uniform
|
||||
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_3;
|
||||
const auto consumer = nullptr;
|
||||
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
uint32_t buffer_int32_min[1];
|
||||
uint32_t buffer_int64_1[2];
|
||||
uint32_t buffer_int64_max[2];
|
||||
uint32_t buffer_uint64_1[2];
|
||||
uint32_t buffer_uint64_max[2];
|
||||
uint32_t buffer_float_10[1];
|
||||
uint32_t buffer_double_10[2];
|
||||
uint32_t buffer_double_20[2];
|
||||
|
||||
{
|
||||
int32_t temp = std::numeric_limits<int32_t>::min();
|
||||
std::memcpy(&buffer_int32_min, &temp, sizeof(temp));
|
||||
}
|
||||
|
||||
{
|
||||
int64_t temp = 1;
|
||||
std::memcpy(&buffer_int64_1, &temp, sizeof(temp));
|
||||
}
|
||||
|
||||
{
|
||||
int64_t temp = std::numeric_limits<int64_t>::max();
|
||||
std::memcpy(&buffer_int64_max, &temp, sizeof(temp));
|
||||
}
|
||||
|
||||
{
|
||||
uint64_t temp = 1;
|
||||
std::memcpy(&buffer_uint64_1, &temp, sizeof(temp));
|
||||
}
|
||||
|
||||
{
|
||||
uint64_t temp = std::numeric_limits<uint64_t>::max();
|
||||
std::memcpy(&buffer_uint64_max, &temp, sizeof(temp));
|
||||
}
|
||||
|
||||
{
|
||||
float temp = 10.0f;
|
||||
std::memcpy(&buffer_float_10, &temp, sizeof(float));
|
||||
}
|
||||
|
||||
{
|
||||
double temp = 10.0;
|
||||
std::memcpy(&buffer_double_10, &temp, sizeof(temp));
|
||||
}
|
||||
|
||||
{
|
||||
double temp = 20.0;
|
||||
std::memcpy(&buffer_double_20, &temp, sizeof(temp));
|
||||
}
|
||||
|
||||
FactManager fact_manager;
|
||||
|
||||
uint32_t type_int32_id = 11;
|
||||
uint32_t type_int64_id = 13;
|
||||
uint32_t type_uint32_id = 10;
|
||||
uint32_t type_uint64_id = 12;
|
||||
uint32_t type_float_id = 15;
|
||||
uint32_t type_double_id = 16;
|
||||
|
||||
// Initially there should be no facts about uniforms.
|
||||
ASSERT_TRUE(fact_manager
|
||||
.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_uint32_id)
|
||||
.empty());
|
||||
|
||||
// 100[2][3] == int(1)
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1},
|
||||
MakeUniformBufferElementDescriptor(100, {2, 3})));
|
||||
|
||||
// 200[1][2][3] == int(1)
|
||||
ASSERT_TRUE(
|
||||
AddFactHelper(&fact_manager, context.get(), {1},
|
||||
MakeUniformBufferElementDescriptor(200, {1, 2, 3})));
|
||||
|
||||
// 300[1][0][2][3] == int(1)
|
||||
ASSERT_TRUE(
|
||||
AddFactHelper(&fact_manager, context.get(), {1},
|
||||
MakeUniformBufferElementDescriptor(300, {1, 0, 2, 3})));
|
||||
|
||||
// 400[2][3] = int32_min
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_int32_min[0]},
|
||||
MakeUniformBufferElementDescriptor(400, {2, 3})));
|
||||
|
||||
// 500[1][2][3] = int32_min
|
||||
ASSERT_TRUE(
|
||||
AddFactHelper(&fact_manager, context.get(), {buffer_int32_min[0]},
|
||||
MakeUniformBufferElementDescriptor(500, {1, 2, 3})));
|
||||
|
||||
// 600[1][2][3] = int64_max
|
||||
ASSERT_TRUE(AddFactHelper(
|
||||
&fact_manager, context.get(), {buffer_int64_max[0], buffer_int64_max[1]},
|
||||
MakeUniformBufferElementDescriptor(600, {1, 2, 3})));
|
||||
|
||||
// 700[1][1] = int64_max
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
|
||||
{buffer_int64_max[0], buffer_int64_max[1]},
|
||||
MakeUniformBufferElementDescriptor(700, {1, 1})));
|
||||
|
||||
// 800[2][3] = uint(1)
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1},
|
||||
MakeUniformBufferElementDescriptor(800, {2, 3})));
|
||||
|
||||
// 900[1][2][3] = uint(1)
|
||||
ASSERT_TRUE(
|
||||
AddFactHelper(&fact_manager, context.get(), {1},
|
||||
MakeUniformBufferElementDescriptor(900, {1, 2, 3})));
|
||||
|
||||
// 1000[1][0][2][3] = uint(1)
|
||||
ASSERT_TRUE(
|
||||
AddFactHelper(&fact_manager, context.get(), {1},
|
||||
MakeUniformBufferElementDescriptor(1000, {1, 0, 2, 3})));
|
||||
|
||||
// 1100[0] = uint64(1)
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
|
||||
{buffer_uint64_1[0], buffer_uint64_1[1]},
|
||||
MakeUniformBufferElementDescriptor(1100, {0})));
|
||||
|
||||
// 1200[0][0] = uint64_max
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
|
||||
{buffer_uint64_max[0], buffer_uint64_max[1]},
|
||||
MakeUniformBufferElementDescriptor(1200, {0, 0})));
|
||||
|
||||
// 1300[1][0] = uint64_max
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
|
||||
{buffer_uint64_max[0], buffer_uint64_max[1]},
|
||||
MakeUniformBufferElementDescriptor(1300, {1, 0})));
|
||||
|
||||
// 1400[6] = float(10.0)
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]},
|
||||
MakeUniformBufferElementDescriptor(1400, {6})));
|
||||
|
||||
// 1500[7] = float(10.0)
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]},
|
||||
MakeUniformBufferElementDescriptor(1500, {7})));
|
||||
|
||||
// 1600[9][9] = float(10.0)
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]},
|
||||
MakeUniformBufferElementDescriptor(1600, {9, 9})));
|
||||
|
||||
// 1700[9][9][1] = double(10.0)
|
||||
ASSERT_TRUE(AddFactHelper(
|
||||
&fact_manager, context.get(), {buffer_double_10[0], buffer_double_10[1]},
|
||||
MakeUniformBufferElementDescriptor(1700, {9, 9, 1})));
|
||||
|
||||
// 1800[9][9][2] = double(10.0)
|
||||
ASSERT_TRUE(AddFactHelper(
|
||||
&fact_manager, context.get(), {buffer_double_10[0], buffer_double_10[1]},
|
||||
MakeUniformBufferElementDescriptor(1800, {9, 9, 2})));
|
||||
|
||||
// 1900[0][0][0][0][0] = double(20.0)
|
||||
ASSERT_TRUE(AddFactHelper(
|
||||
&fact_manager, context.get(), {buffer_double_20[0], buffer_double_20[1]},
|
||||
MakeUniformBufferElementDescriptor(1900, {0, 0, 0, 0, 0})));
|
||||
|
||||
opt::Instruction::OperandList operands = {
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_int32_id, 50, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int32_min[0]}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_int32_id, 51, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int64_max[0]}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int64_max[1]}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_int64_id, 52, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_uint32_id, 53, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_1[0]}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_1[1]}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_uint64_id, 54, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_max[0]}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_max[1]}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_uint64_id, 55, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_float_10[0]}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_float_id, 56, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_10[0]}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_10[1]}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_double_id, 57, operands));
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_20[0]}},
|
||||
{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_20[1]}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_double_id, 58, operands));
|
||||
|
||||
// A duplicate of the constant with id 59.
|
||||
operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}};
|
||||
context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||
context.get(), SpvOpConstant, type_int32_id, 59, operands));
|
||||
|
||||
context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone);
|
||||
|
||||
// Constants 1 and int32_min are available.
|
||||
ASSERT_EQ(2, fact_manager
|
||||
.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_int32_id)
|
||||
.size());
|
||||
// Constant int64_max is available.
|
||||
ASSERT_EQ(1, fact_manager
|
||||
.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_int64_id)
|
||||
.size());
|
||||
// Constant 1u is available.
|
||||
ASSERT_EQ(1, fact_manager
|
||||
.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_uint32_id)
|
||||
.size());
|
||||
// Constants 1u and uint64_max are available.
|
||||
ASSERT_EQ(2, fact_manager
|
||||
.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_uint64_id)
|
||||
.size());
|
||||
// Constant 10.0 is available.
|
||||
ASSERT_EQ(1, fact_manager
|
||||
.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_float_id)
|
||||
.size());
|
||||
// Constants 10.0 and 20.0 are available.
|
||||
ASSERT_EQ(2, fact_manager
|
||||
.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_double_id)
|
||||
.size());
|
||||
|
||||
ASSERT_EQ(std::numeric_limits<int64_t>::max(),
|
||||
context->get_constant_mgr()
|
||||
->FindDeclaredConstant(
|
||||
fact_manager.GetConstantsAvailableFromUniformsForType(
|
||||
context.get(), type_int64_id)[0])
|
||||
->AsIntConstant()
|
||||
->GetS64());
|
||||
ASSERT_EQ(1, context->get_constant_mgr()
|
||||
->FindDeclaredConstant(
|
||||
fact_manager.GetConstantsAvailableFromUniformsForType(
|
||||
context.get(), type_uint32_id)[0])
|
||||
->AsIntConstant()
|
||||
->GetU32());
|
||||
ASSERT_EQ(10.0f,
|
||||
context->get_constant_mgr()
|
||||
->FindDeclaredConstant(
|
||||
fact_manager.GetConstantsAvailableFromUniformsForType(
|
||||
context.get(), type_float_id)[0])
|
||||
->AsFloatConstant()
|
||||
->GetFloat());
|
||||
const std::vector<uint32_t>& double_constant_ids =
|
||||
fact_manager.GetConstantsAvailableFromUniformsForType(context.get(),
|
||||
type_double_id);
|
||||
ASSERT_EQ(10.0, context->get_constant_mgr()
|
||||
->FindDeclaredConstant(double_constant_ids[0])
|
||||
->AsFloatConstant()
|
||||
->GetDouble());
|
||||
ASSERT_EQ(20.0, context->get_constant_mgr()
|
||||
->FindDeclaredConstant(double_constant_ids[1])
|
||||
->AsFloatConstant()
|
||||
->GetDouble());
|
||||
|
||||
const std::vector<protobufs::UniformBufferElementDescriptor>
|
||||
descriptors_for_double_10 = fact_manager.GetUniformDescriptorsForConstant(
|
||||
context.get(), double_constant_ids[0]);
|
||||
ASSERT_EQ(2, descriptors_for_double_10.size());
|
||||
{
|
||||
auto temp = MakeUniformBufferElementDescriptor(1700, {9, 9, 1});
|
||||
ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
|
||||
&temp, &descriptors_for_double_10[0]));
|
||||
}
|
||||
{
|
||||
auto temp = MakeUniformBufferElementDescriptor(1800, {9, 9, 2});
|
||||
ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
|
||||
&temp, &descriptors_for_double_10[1]));
|
||||
}
|
||||
const std::vector<protobufs::UniformBufferElementDescriptor>
|
||||
descriptors_for_double_20 = fact_manager.GetUniformDescriptorsForConstant(
|
||||
context.get(), double_constant_ids[1]);
|
||||
ASSERT_EQ(1, descriptors_for_double_20.size());
|
||||
{
|
||||
auto temp = MakeUniformBufferElementDescriptor(1900, {0, 0, 0, 0, 0});
|
||||
ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
|
||||
&temp, &descriptors_for_double_20[0]));
|
||||
}
|
||||
|
||||
auto constant_1_id = fact_manager.GetConstantFromUniformDescriptor(
|
||||
context.get(), MakeUniformBufferElementDescriptor(1800, {9, 9, 2}));
|
||||
ASSERT_TRUE(constant_1_id);
|
||||
|
||||
auto constant_2_id = fact_manager.GetConstantFromUniformDescriptor(
|
||||
context.get(), MakeUniformBufferElementDescriptor(1900, {0, 0, 0, 0, 0}));
|
||||
ASSERT_TRUE(constant_2_id);
|
||||
|
||||
ASSERT_EQ(double_constant_ids[0], constant_1_id);
|
||||
|
||||
ASSERT_EQ(double_constant_ids[1], constant_2_id);
|
||||
}
|
||||
|
||||
TEST(FactManagerTest, TwoConstantsWithSameValue) {
|
||||
std::string shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main"
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 310
|
||||
OpName %4 "main"
|
||||
OpName %8 "x"
|
||||
OpName %10 "buf"
|
||||
OpMemberName %10 0 "a"
|
||||
OpName %12 ""
|
||||
OpDecorate %8 RelaxedPrecision
|
||||
OpMemberDecorate %10 0 RelaxedPrecision
|
||||
OpMemberDecorate %10 0 Offset 0
|
||||
OpDecorate %10 Block
|
||||
OpDecorate %12 DescriptorSet 0
|
||||
OpDecorate %12 Binding 0
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%6 = OpTypeInt 32 1
|
||||
%7 = OpTypePointer Function %6
|
||||
%9 = OpConstant %6 1
|
||||
%20 = OpConstant %6 1
|
||||
%10 = OpTypeStruct %6
|
||||
%11 = OpTypePointer Uniform %10
|
||||
%12 = OpVariable %11 Uniform
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
%8 = OpVariable %7 Function
|
||||
OpStore %8 %9
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_3;
|
||||
const auto consumer = nullptr;
|
||||
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
FactManager fact_manager;
|
||||
|
||||
auto uniform_buffer_element_descriptor =
|
||||
MakeUniformBufferElementDescriptor(12, {0});
|
||||
|
||||
// 12[0] = int(1)
|
||||
ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1},
|
||||
uniform_buffer_element_descriptor));
|
||||
auto constants =
|
||||
fact_manager.GetConstantsAvailableFromUniformsForType(context.get(), 6);
|
||||
ASSERT_EQ(1, constants.size());
|
||||
ASSERT_TRUE(constants[0] == 9 || constants[0] == 20);
|
||||
|
||||
auto constant = fact_manager.GetConstantFromUniformDescriptor(
|
||||
context.get(), uniform_buffer_element_descriptor);
|
||||
ASSERT_TRUE(constant == 9 || constant == 20);
|
||||
|
||||
// Because the constants with ids 9 and 20 are equal, we should get the same
|
||||
// single uniform buffer element descriptor when we look up the descriptors
|
||||
// for either one of them.
|
||||
for (auto constant_id : {9u, 20u}) {
|
||||
auto descriptors = fact_manager.GetUniformDescriptorsForConstant(
|
||||
context.get(), constant_id);
|
||||
ASSERT_EQ(1, descriptors.size());
|
||||
ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
|
||||
&uniform_buffer_element_descriptor, &descriptors[0]));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/fuzz/fuzzer.h"
|
||||
#include "source/fuzz/replayer.h"
|
||||
#include "test/fuzz/fuzz_test_util.h"
|
||||
|
||||
namespace spvtools {
|
||||
@@ -21,9 +22,11 @@ namespace {
|
||||
|
||||
// Assembles the given |shader| text, and then runs the fuzzer |num_runs|
|
||||
// times, using successive seeds starting from |initial_seed|. Checks that
|
||||
// the binary produced after each fuzzer run is valid.
|
||||
void RunFuzzer(const std::string& shader, uint32_t initial_seed,
|
||||
uint32_t num_runs) {
|
||||
// the binary produced after each fuzzer run is valid, and that replaying
|
||||
// the transformations that were applied during fuzzing leads to an
|
||||
// identical binary.
|
||||
void RunFuzzerAndReplayer(const std::string& shader, uint32_t initial_seed,
|
||||
uint32_t num_runs) {
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_3;
|
||||
|
||||
std::vector<uint32_t> binary_in;
|
||||
@@ -33,19 +36,38 @@ void RunFuzzer(const std::string& shader, uint32_t initial_seed,
|
||||
|
||||
for (uint32_t seed = initial_seed; seed < initial_seed + num_runs; seed++) {
|
||||
protobufs::FactSequence initial_facts;
|
||||
std::vector<uint32_t> binary_out;
|
||||
protobufs::TransformationSequence transformation_sequence_out;
|
||||
std::vector<uint32_t> fuzzer_binary_out;
|
||||
protobufs::TransformationSequence fuzzer_transformation_sequence_out;
|
||||
spvtools::FuzzerOptions fuzzer_options;
|
||||
spvFuzzerOptionsSetRandomSeed(fuzzer_options, seed);
|
||||
|
||||
Fuzzer fuzzer(env);
|
||||
fuzzer.Run(binary_in, initial_facts, &binary_out,
|
||||
&transformation_sequence_out, fuzzer_options);
|
||||
ASSERT_TRUE(t.Validate(binary_out));
|
||||
fuzzer.Run(binary_in, initial_facts, &fuzzer_binary_out,
|
||||
&fuzzer_transformation_sequence_out, fuzzer_options);
|
||||
ASSERT_TRUE(t.Validate(fuzzer_binary_out));
|
||||
|
||||
std::vector<uint32_t> replayer_binary_out;
|
||||
protobufs::TransformationSequence replayer_transformation_sequence_out;
|
||||
|
||||
Replayer replayer(env);
|
||||
replayer.Run(binary_in, initial_facts, fuzzer_transformation_sequence_out,
|
||||
&replayer_binary_out, &replayer_transformation_sequence_out);
|
||||
|
||||
// After replaying the transformations applied by the fuzzer, exactly those
|
||||
// transformations should have been applied, and the binary resulting from
|
||||
// replay should be identical to that which resulted from fuzzing.
|
||||
std::string fuzzer_transformations_string;
|
||||
std::string replayer_transformations_string;
|
||||
fuzzer_transformation_sequence_out.SerializeToString(
|
||||
&fuzzer_transformations_string);
|
||||
replayer_transformation_sequence_out.SerializeToString(
|
||||
&replayer_transformations_string);
|
||||
ASSERT_EQ(fuzzer_transformations_string, replayer_transformations_string);
|
||||
ASSERT_EQ(fuzzer_binary_out, replayer_binary_out);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FuzzerTest, Miscellaneous1) {
|
||||
TEST(FuzzerReplayerTest, Miscellaneous1) {
|
||||
// The SPIR-V came from this GLSL:
|
||||
//
|
||||
// #version 310 es
|
||||
@@ -211,10 +233,10 @@ TEST(FuzzerTest, Miscellaneous1) {
|
||||
|
||||
// Do 10 fuzzer runs, starting from an initial seed of 0 (seed value chosen
|
||||
// arbitrarily).
|
||||
RunFuzzer(shader, 0, 10);
|
||||
RunFuzzerAndReplayer(shader, 0, 10);
|
||||
}
|
||||
|
||||
TEST(FuzzerTest, Miscellaneous2) {
|
||||
TEST(FuzzerReplayerTest, Miscellaneous2) {
|
||||
// The SPIR-V came from this GLSL, which was then optimized using spirv-opt
|
||||
// with the -O argument:
|
||||
//
|
||||
@@ -456,7 +478,7 @@ TEST(FuzzerTest, Miscellaneous2) {
|
||||
|
||||
// Do 10 fuzzer runs, starting from an initial seed of 10 (seed value chosen
|
||||
// arbitrarily).
|
||||
RunFuzzer(shader, 10, 10);
|
||||
RunFuzzerAndReplayer(shader, 10, 10);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -3811,7 +3811,7 @@ OpName %output "output"
|
||||
%6 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%_ptr_Private_float = OpTypePointer Private %float
|
||||
%initializer = OpVariable %_ptr_Private_float Private
|
||||
%initializer = OpConstant %float 0
|
||||
%live = OpVariable %_ptr_Private_float Private %initializer
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%output = OpVariable %_ptr_Output_float Output
|
||||
|
||||
@@ -217,7 +217,7 @@ OpName %initializer "initializer"
|
||||
%6 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%_ptr_Private_float = OpTypePointer Private %float
|
||||
%initializer = OpVariable %_ptr_Private_float Private
|
||||
%initializer = OpConstant %float 0
|
||||
%live = OpVariable %_ptr_Private_float Private %initializer
|
||||
%main = OpFunction %void None %6
|
||||
%9 = OpLabel
|
||||
|
||||
222
3rdparty/spirv-tools/test/val/val_builtins_test.cpp
vendored
222
3rdparty/spirv-tools/test/val/val_builtins_test.cpp
vendored
@@ -52,6 +52,8 @@ using ::testing::Values;
|
||||
using ::testing::ValuesIn;
|
||||
|
||||
using ValidateBuiltIns = spvtest::ValidateBase<bool>;
|
||||
using ValidateVulkanSubgroupBuiltIns = spvtest::ValidateBase<
|
||||
std::tuple<const char*, const char*, const char*, const char*, TestResult>>;
|
||||
using ValidateVulkanCombineBuiltInExecutionModelDataTypeResult =
|
||||
spvtest::ValidateBase<std::tuple<const char*, const char*, const char*,
|
||||
const char*, TestResult>>;
|
||||
@@ -3080,6 +3082,226 @@ TEST_F(ValidateBuiltIns, GetUnderlyingTypeNoAssert) {
|
||||
"type"));
|
||||
}
|
||||
|
||||
TEST_P(ValidateVulkanSubgroupBuiltIns, InMain) {
|
||||
const char* const built_in = std::get<0>(GetParam());
|
||||
const char* const execution_model = std::get<1>(GetParam());
|
||||
const char* const storage_class = std::get<2>(GetParam());
|
||||
const char* const data_type = std::get<3>(GetParam());
|
||||
const TestResult& test_result = std::get<4>(GetParam());
|
||||
|
||||
CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
|
||||
generator.capabilities_ += R"(
|
||||
OpCapability GroupNonUniformBallot
|
||||
)";
|
||||
|
||||
generator.before_types_ = "OpDecorate %built_in_var BuiltIn ";
|
||||
generator.before_types_ += built_in;
|
||||
generator.before_types_ += "\n";
|
||||
|
||||
std::ostringstream after_types;
|
||||
after_types << "%built_in_ptr = OpTypePointer " << storage_class << " "
|
||||
<< data_type << "\n";
|
||||
after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class;
|
||||
after_types << "\n";
|
||||
generator.after_types_ = after_types.str();
|
||||
|
||||
EntryPoint entry_point;
|
||||
entry_point.name = "main";
|
||||
entry_point.execution_model = execution_model;
|
||||
if (strncmp(storage_class, "Input", 5) == 0 ||
|
||||
strncmp(storage_class, "Output", 6) == 0) {
|
||||
entry_point.interfaces = "%built_in_var";
|
||||
}
|
||||
entry_point.body =
|
||||
std::string("%ld = OpLoad ") + data_type + " %built_in_var\n";
|
||||
|
||||
std::ostringstream execution_modes;
|
||||
if (0 == std::strcmp(execution_model, "Fragment")) {
|
||||
execution_modes << "OpExecutionMode %" << entry_point.name
|
||||
<< " OriginUpperLeft\n";
|
||||
if (0 == std::strcmp(built_in, "FragDepth")) {
|
||||
execution_modes << "OpExecutionMode %" << entry_point.name
|
||||
<< " DepthReplacing\n";
|
||||
}
|
||||
}
|
||||
if (0 == std::strcmp(execution_model, "Geometry")) {
|
||||
execution_modes << "OpExecutionMode %" << entry_point.name
|
||||
<< " InputPoints\n";
|
||||
execution_modes << "OpExecutionMode %" << entry_point.name
|
||||
<< " OutputPoints\n";
|
||||
}
|
||||
if (0 == std::strcmp(execution_model, "GLCompute")) {
|
||||
execution_modes << "OpExecutionMode %" << entry_point.name
|
||||
<< " LocalSize 1 1 1\n";
|
||||
}
|
||||
entry_point.execution_modes = execution_modes.str();
|
||||
|
||||
generator.entry_points_.push_back(std::move(entry_point));
|
||||
|
||||
CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_1);
|
||||
ASSERT_EQ(test_result.validation_result,
|
||||
ValidateInstructions(SPV_ENV_VULKAN_1_1));
|
||||
if (test_result.error_str) {
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
|
||||
}
|
||||
if (test_result.error_str2) {
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupMaskNotVec4, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupEqMask", "SubgroupGeMask", "SubgroupGtMask",
|
||||
"SubgroupLeMask", "SubgroupLtMask"),
|
||||
Values("GLCompute"), Values("Input"), Values("%u32vec3"),
|
||||
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||
"needs to be a 4-component 32-bit int vector"))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupMaskNotU32, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupEqMask", "SubgroupGeMask", "SubgroupGtMask",
|
||||
"SubgroupLeMask", "SubgroupLtMask"),
|
||||
Values("GLCompute"), Values("Input"), Values("%f32vec4"),
|
||||
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||
"needs to be a 4-component 32-bit int vector"))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupMaskNotInput, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupEqMask", "SubgroupGeMask", "SubgroupGtMask",
|
||||
"SubgroupLeMask", "SubgroupLtMask"),
|
||||
Values("GLCompute"), Values("Output", "Workgroup", "Private"),
|
||||
Values("%u32vec4"),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"to be only used for variables with Input storage class"))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(SubgroupMaskOk, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupEqMask", "SubgroupGeMask",
|
||||
"SubgroupGtMask", "SubgroupLeMask",
|
||||
"SubgroupLtMask"),
|
||||
Values("GLCompute"), Values("Input"),
|
||||
Values("%u32vec4"),
|
||||
Values(TestResult(SPV_SUCCESS, ""))));
|
||||
|
||||
TEST_F(ValidateBuiltIns, SubgroupMaskMemberDecorate) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
OpCapability GroupNonUniformBallot
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %foo "foo"
|
||||
OpExecutionMode %foo LocalSize 1 1 1
|
||||
OpMemberDecorate %struct 0 BuiltIn SubgroupEqMask
|
||||
%void = OpTypeVoid
|
||||
%int = OpTypeInt 32 0
|
||||
%struct = OpTypeStruct %int
|
||||
%void_fn = OpTypeFunction %void
|
||||
%foo = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr(
|
||||
"BuiltIn SubgroupEqMask cannot be used as a member decoration"));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupInvocationIdAndSizeNotU32, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupLocalInvocationId", "SubgroupSize"),
|
||||
Values("GLCompute"), Values("Input"), Values("%f32"),
|
||||
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||
"needs to be a 32-bit int"))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupInvocationIdAndSizeNotInput, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupLocalInvocationId", "SubgroupSize"),
|
||||
Values("GLCompute"), Values("Output", "Workgroup", "Private"),
|
||||
Values("%u32"),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"to be only used for variables with Input storage class"))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupInvocationIdAndSizeOk, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupLocalInvocationId", "SubgroupSize"),
|
||||
Values("GLCompute"), Values("Input"), Values("%u32"),
|
||||
Values(TestResult(SPV_SUCCESS, ""))));
|
||||
|
||||
TEST_F(ValidateBuiltIns, SubgroupSizeMemberDecorate) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
OpCapability GroupNonUniform
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %foo "foo"
|
||||
OpExecutionMode %foo LocalSize 1 1 1
|
||||
OpMemberDecorate %struct 0 BuiltIn SubgroupSize
|
||||
%void = OpTypeVoid
|
||||
%int = OpTypeInt 32 0
|
||||
%struct = OpTypeStruct %int
|
||||
%void_fn = OpTypeFunction %void
|
||||
%foo = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("BuiltIn SubgroupSize cannot be used as a member decoration"));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupNumAndIdNotU32, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupId", "NumSubgroups"), Values("GLCompute"),
|
||||
Values("Input"), Values("%f32"),
|
||||
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||
"needs to be a 32-bit int"))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SubgroupNumAndIdNotInput, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupId", "NumSubgroups"), Values("GLCompute"),
|
||||
Values("Output", "Workgroup", "Private"), Values("%u32"),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"to be only used for variables with Input storage class"))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(SubgroupNumAndIdOk, ValidateVulkanSubgroupBuiltIns,
|
||||
Combine(Values("SubgroupId", "NumSubgroups"),
|
||||
Values("GLCompute"), Values("Input"),
|
||||
Values("%u32"),
|
||||
Values(TestResult(SPV_SUCCESS, ""))));
|
||||
|
||||
TEST_F(ValidateBuiltIns, SubgroupIdMemberDecorate) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
OpCapability GroupNonUniform
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %foo "foo"
|
||||
OpExecutionMode %foo LocalSize 1 1 1
|
||||
OpMemberDecorate %struct 0 BuiltIn SubgroupId
|
||||
%void = OpTypeVoid
|
||||
%int = OpTypeInt 32 0
|
||||
%struct = OpTypeStruct %int
|
||||
%void_fn = OpTypeFunction %void
|
||||
%foo = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("BuiltIn SubgroupId cannot be used as a member decoration"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
||||
@@ -3543,6 +3543,29 @@ OpFunctionEnd
|
||||
INSTANTIATE_TEST_SUITE_P(PointerComparisons, ValidatePointerComparisons,
|
||||
Values("OpPtrEqual", "OpPtrNotEqual", "OpPtrDiff"));
|
||||
|
||||
TEST_F(ValidateMemory, VariableInitializerWrongType) {
|
||||
const std::string spirv = R"(
|
||||
OpCapability Shader
|
||||
OpCapability Linkage
|
||||
OpCapability VariablePointersStorageBuffer
|
||||
OpMemoryModel Logical GLSL450
|
||||
%void = OpTypeVoid
|
||||
%int = OpTypeInt 32 0
|
||||
%float = OpTypeFloat 32
|
||||
%ptr_wg_int = OpTypePointer Workgroup %int
|
||||
%ptr_wg_float = OpTypePointer Workgroup %int
|
||||
%wg_var = OpVariable %ptr_wg_int Workgroup
|
||||
%ptr_private_wg_float = OpTypePointer Private %ptr_wg_float
|
||||
%priv_var = OpVariable %ptr_private_wg_float Private %wg_var
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Initializer type must match the type pointed to by "
|
||||
"the Result Type"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
||||
105
3rdparty/spirv-tools/tools/fuzz/fuzz.cpp
vendored
105
3rdparty/spirv-tools/tools/fuzz/fuzz.cpp
vendored
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "source/fuzz/fuzzer.h"
|
||||
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||
#include "source/fuzz/replayer.h"
|
||||
#include "source/opt/build_module.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "source/opt/log.h"
|
||||
@@ -32,7 +33,11 @@
|
||||
namespace {
|
||||
|
||||
// Status and actions to perform after parsing command-line arguments.
|
||||
enum class FuzzActions { CONTINUE, STOP };
|
||||
enum class FuzzActions {
|
||||
FUZZ, // Run the fuzzer to apply transformations in a randomized fashion.
|
||||
REPLAY, // Replay an existing sequence of transformations.
|
||||
STOP // Do nothing.
|
||||
};
|
||||
|
||||
struct FuzzStatus {
|
||||
FuzzActions action;
|
||||
@@ -60,6 +65,9 @@ Options (in lexicographical order):
|
||||
|
||||
-h, --help
|
||||
Print this help.
|
||||
--replay
|
||||
File from which to read a sequence of transformations to replay
|
||||
(instead of fuzzing)
|
||||
--seed
|
||||
Unsigned 32-bit integer seed to control random number
|
||||
generation.
|
||||
@@ -90,6 +98,7 @@ bool EndsWithSpv(const std::string& filename) {
|
||||
|
||||
FuzzStatus ParseFlags(int argc, const char** argv, std::string* in_binary_file,
|
||||
std::string* out_binary_file,
|
||||
std::string* replay_transformations_file,
|
||||
spvtools::FuzzerOptions* fuzzer_options) {
|
||||
uint32_t positional_arg_index = 0;
|
||||
|
||||
@@ -110,6 +119,9 @@ FuzzStatus ParseFlags(int argc, const char** argv, std::string* in_binary_file,
|
||||
PrintUsage(argv[0]);
|
||||
return {FuzzActions::STOP, 1};
|
||||
}
|
||||
} else if (0 == strncmp(cur_arg, "--replay=", sizeof("--replay=") - 1)) {
|
||||
const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg);
|
||||
*replay_transformations_file = std::string(split_flag.second);
|
||||
} else if (0 == strncmp(cur_arg, "--seed=", sizeof("--seed=") - 1)) {
|
||||
const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg);
|
||||
char* end = nullptr;
|
||||
@@ -158,7 +170,64 @@ FuzzStatus ParseFlags(int argc, const char** argv, std::string* in_binary_file,
|
||||
return {FuzzActions::STOP, 1};
|
||||
}
|
||||
|
||||
return {FuzzActions::CONTINUE, 0};
|
||||
if (!replay_transformations_file->empty()) {
|
||||
// A replay transformations file was given, thus the tool is being invoked
|
||||
// in replay mode.
|
||||
return {FuzzActions::REPLAY, 0};
|
||||
}
|
||||
|
||||
return {FuzzActions::FUZZ, 0};
|
||||
}
|
||||
|
||||
bool Replay(const spv_target_env& target_env,
|
||||
const std::vector<uint32_t>& binary_in,
|
||||
const spvtools::fuzz::protobufs::FactSequence& initial_facts,
|
||||
const std::string& replay_transformations_file,
|
||||
std::vector<uint32_t>* binary_out,
|
||||
spvtools::fuzz::protobufs::TransformationSequence*
|
||||
transformations_applied) {
|
||||
std::ifstream existing_transformations_file;
|
||||
existing_transformations_file.open(replay_transformations_file,
|
||||
std::ios::in | std::ios::binary);
|
||||
spvtools::fuzz::protobufs::TransformationSequence
|
||||
existing_transformation_sequence;
|
||||
auto parse_success = existing_transformation_sequence.ParseFromIstream(
|
||||
&existing_transformations_file);
|
||||
existing_transformations_file.close();
|
||||
if (!parse_success) {
|
||||
spvtools::Error(FuzzDiagnostic, nullptr, {},
|
||||
"Error reading transformations for replay");
|
||||
return false;
|
||||
}
|
||||
spvtools::fuzz::Replayer replayer(target_env);
|
||||
replayer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
|
||||
auto replay_result_status =
|
||||
replayer.Run(binary_in, initial_facts, existing_transformation_sequence,
|
||||
binary_out, transformations_applied);
|
||||
if (replay_result_status !=
|
||||
spvtools::fuzz::Replayer::ReplayerResultStatus::kComplete) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Fuzz(const spv_target_env& target_env,
|
||||
const spvtools::FuzzerOptions& fuzzer_options,
|
||||
const std::vector<uint>& binary_in,
|
||||
const spvtools::fuzz::protobufs::FactSequence& initial_facts,
|
||||
std::vector<uint32_t>* binary_out,
|
||||
spvtools::fuzz::protobufs::TransformationSequence*
|
||||
transformations_applied) {
|
||||
spvtools::fuzz::Fuzzer fuzzer(target_env);
|
||||
fuzzer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
|
||||
auto fuzz_result_status = fuzzer.Run(binary_in, initial_facts, binary_out,
|
||||
transformations_applied, fuzzer_options);
|
||||
if (fuzz_result_status !=
|
||||
spvtools::fuzz::Fuzzer::FuzzerResultStatus::kComplete) {
|
||||
spvtools::Error(FuzzDiagnostic, nullptr, {}, "Error running fuzzer");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -168,12 +237,12 @@ const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3;
|
||||
int main(int argc, const char** argv) {
|
||||
std::string in_binary_file;
|
||||
std::string out_binary_file;
|
||||
std::string replay_transformations_file;
|
||||
|
||||
spv_target_env target_env = kDefaultEnvironment;
|
||||
spvtools::FuzzerOptions fuzzer_options;
|
||||
|
||||
FuzzStatus status = ParseFlags(argc, argv, &in_binary_file, &out_binary_file,
|
||||
&fuzzer_options);
|
||||
&replay_transformations_file, &fuzzer_options);
|
||||
|
||||
if (status.action == FuzzActions::STOP) {
|
||||
return status.code;
|
||||
@@ -205,15 +274,25 @@ int main(int argc, const char** argv) {
|
||||
std::vector<uint32_t> binary_out;
|
||||
spvtools::fuzz::protobufs::TransformationSequence transformations_applied;
|
||||
|
||||
spvtools::fuzz::Fuzzer fuzzer(target_env);
|
||||
fuzzer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
|
||||
auto fuzz_result_status =
|
||||
fuzzer.Run(binary_in, initial_facts, &binary_out,
|
||||
&transformations_applied, fuzzer_options);
|
||||
if (fuzz_result_status !=
|
||||
spvtools::fuzz::Fuzzer::FuzzerResultStatus::kComplete) {
|
||||
spvtools::Error(FuzzDiagnostic, nullptr, {}, "Error running fuzzer");
|
||||
return 1;
|
||||
spv_target_env target_env = kDefaultEnvironment;
|
||||
|
||||
switch (status.action) {
|
||||
case FuzzActions::FUZZ:
|
||||
if (!Fuzz(target_env, fuzzer_options, binary_in, initial_facts,
|
||||
&binary_out, &transformations_applied)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case FuzzActions::REPLAY:
|
||||
if (!Replay(target_env, binary_in, initial_facts,
|
||||
replay_transformations_file, &binary_out,
|
||||
&transformations_applied)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unknown fuzzer action.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!WriteFile<uint32_t>(out_binary_file.c_str(), "wb", binary_out.data(),
|
||||
|
||||
Reference in New Issue
Block a user