Better SPIR-V Capability checks (#1664)

* Restructure DeviceRequirement in shaderc

* Add missing SPIR-V capabilities

* Avoid generating a check for every instruction in the file XD
This commit is contained in:
Rua 2021-08-16 20:12:43 +02:00 committed by GitHub
parent 148dc78def
commit 010d7fe551
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -262,34 +262,48 @@ where
type_id: _, type_id: _,
} => storage_class_requirement(storage_class), } => storage_class_requirement(storage_class),
Instruction::Capability(cap) => capability_requirement(cap), Instruction::Capability(cap) => capability_requirement(cap),
_ => DeviceRequirement::None, _ => &[],
} }
}; };
match dev_req { if dev_req.len() == 0 {
DeviceRequirement::None => continue, continue;
DeviceRequirement::Features(features) => {
for feature in features {
let ident = Ident::new(feature, Span::call_site());
cap_checks.push(quote! {
if !device.enabled_features().#ident {
panic!("Device feature {:?} required", #feature);
} }
});
} let (conditions, messages): (Vec<_>, Vec<_>) = dev_req
} .iter()
DeviceRequirement::Extensions(extensions) => { .map(|req| match req {
for extension in extensions { DeviceRequirement::Extension(extension) => {
let ident = Ident::new(extension, Span::call_site()); let ident = Ident::new(extension, Span::call_site());
(
quote! { device.enabled_extensions().#ident },
format!("extension {}", extension),
)
}
DeviceRequirement::Feature(feature) => {
let ident = Ident::new(feature, Span::call_site());
(
quote! { device.enabled_features().#ident },
format!("feature {}", feature),
)
}
DeviceRequirement::Version(major, minor) => {
let ident = format_ident!("V{}_{}", major, minor);
(
quote! { device.api_version() >= crate::Version::#ident },
format!("API version {}.{}", major, minor),
)
}
})
.unzip();
let messages = messages.join(", ");
cap_checks.push(quote! { cap_checks.push(quote! {
if !device.enabled_extensions().#ident { if !std::array::IntoIter::new([#(#conditions),*]).all(|x| x) {
panic!("Device extension {:?} required", #extension); panic!("One of the following must be enabled on the device: {}", #messages);
} }
}); });
} }
}
}
}
// writing one method for each entry point of this module // writing one method for each entry point of this module
let mut entry_points_inside_impl: Vec<TokenStream> = vec![]; let mut entry_points_inside_impl: Vec<TokenStream> = vec![];
@ -428,103 +442,154 @@ impl From<ParseError> for Error {
} }
/// Returns the Vulkan device requirement for a SPIR-V `OpCapability`. /// Returns the Vulkan device requirement for a SPIR-V `OpCapability`.
// TODO: this function is a draft, as the actual names may not be the same #[rustfmt::skip]
fn capability_requirement(cap: &Capability) -> DeviceRequirement { fn capability_requirement(cap: &Capability) -> &'static [DeviceRequirement] {
match *cap { match *cap {
Capability::Matrix => DeviceRequirement::None, Capability::Matrix => &[],
Capability::Shader => DeviceRequirement::None, Capability::Shader => &[],
Capability::Geometry => DeviceRequirement::Features(&["geometry_shader"]), Capability::InputAttachment => &[],
Capability::Tessellation => DeviceRequirement::Features(&["tessellation_shader"]), Capability::Sampled1D => &[],
Capability::Addresses => panic!(), // not supported Capability::Image1D => &[],
Capability::Linkage => panic!(), // not supported Capability::SampledBuffer => &[],
Capability::Kernel => panic!(), // not supported Capability::ImageBuffer => &[],
Capability::Vector16 => panic!(), // not supported Capability::ImageQuery => &[],
Capability::Float16Buffer => panic!(), // not supported Capability::DerivativeControl => &[],
Capability::Float16 => panic!(), // not supported Capability::Geometry => &[DeviceRequirement::Feature("geometry_shader")],
Capability::Float64 => DeviceRequirement::Features(&["shader_float64"]), Capability::Tessellation => &[DeviceRequirement::Feature("tessellation_shader")],
Capability::Int64 => DeviceRequirement::Features(&["shader_int64"]), Capability::Float64 => &[DeviceRequirement::Feature("shader_float64")],
Capability::Int64Atomics => panic!(), // not supported Capability::Int64 => &[DeviceRequirement::Feature("shader_int64")],
Capability::ImageBasic => panic!(), // not supported Capability::Int64Atomics => &[
Capability::ImageReadWrite => panic!(), // not supported DeviceRequirement::Feature("shader_buffer_int64_atomics"),
Capability::ImageMipmap => panic!(), // not supported DeviceRequirement::Feature("shader_shared_int64_atomics"),
Capability::Pipes => panic!(), // not supported DeviceRequirement::Feature("shader_image_int64_atomics"),
Capability::Groups => panic!(), // not supported ],
Capability::DeviceEnqueue => panic!(), // not supported /* Capability::AtomicFloat16AddEXT => &[
Capability::LiteralSampler => panic!(), // not supported DeviceRequirement::Feature("shader_buffer_float16_atomic_add"),
Capability::AtomicStorage => panic!(), // not supported DeviceRequirement::Feature("shader_shared_float16_atomic_add"),
Capability::Int16 => DeviceRequirement::Features(&["shader_int16"]), ], */
Capability::TessellationPointSize => { /* Capability::AtomicFloat32AddEXT => &[
DeviceRequirement::Features(&["shader_tessellation_and_geometry_point_size"]) DeviceRequirement::Feature("shader_buffer_float32_atomic_add"),
} DeviceRequirement::Feature("shader_shared_float32_atomic_add"),
Capability::GeometryPointSize => { DeviceRequirement::Feature("shader_image_float32_atomic_add"),
DeviceRequirement::Features(&["shader_tessellation_and_geometry_point_size"]) ], */
} /* Capability::AtomicFloat64AddEXT => &[
DeviceRequirement::Feature("shader_buffer_float64_atomic_add"),
DeviceRequirement::Feature("shader_shared_float64_atomic_add"),
], */
/* Capability::AtomicFloat16MinMaxEXT => &[
DeviceRequirement::Feature("shader_buffer_float16_atomic_min_max"),
DeviceRequirement::Feature("shader_shared_float16_atomic_min_max"),
], */
/* Capability::AtomicFloat32MinMaxEXT => &[
DeviceRequirement::Feature("shader_buffer_float32_atomic_min_max"),
DeviceRequirement::Feature("shader_shared_float32_atomic_min_max"),
DeviceRequirement::Feature("shader_image_float32_atomic_min_max"),
], */
/* Capability::AtomicFloat64MinMaxEXT => &[
DeviceRequirement::Feature("shader_buffer_float64_atomic_min_max"),
DeviceRequirement::Feature("shader_shared_float64_atomic_min_max"),
], */
// Capability::Int64ImageEXT => &[DeviceRequirement::Feature("shader_image_int64_atomics")],
Capability::Int16 => &[DeviceRequirement::Feature("shader_int16")],
Capability::TessellationPointSize => &[DeviceRequirement::Feature(
"shader_tessellation_and_geometry_point_size",
)],
Capability::GeometryPointSize => &[DeviceRequirement::Feature(
"shader_tessellation_and_geometry_point_size",
)],
Capability::ImageGatherExtended => { Capability::ImageGatherExtended => {
DeviceRequirement::Features(&["shader_image_gather_extended"]) &[DeviceRequirement::Feature("shader_image_gather_extended")]
} }
Capability::StorageImageMultisample => { Capability::StorageImageMultisample => &[DeviceRequirement::Feature(
DeviceRequirement::Features(&["shader_storage_image_multisample"]) "shader_storage_image_multisample",
)],
Capability::UniformBufferArrayDynamicIndexing => &[DeviceRequirement::Feature(
"shader_uniform_buffer_array_dynamic_indexing",
)],
Capability::SampledImageArrayDynamicIndexing => &[DeviceRequirement::Feature(
"shader_sampled_image_array_dynamic_indexing",
)],
Capability::StorageBufferArrayDynamicIndexing => &[DeviceRequirement::Feature(
"shader_storage_buffer_array_dynamic_indexing",
)],
Capability::StorageImageArrayDynamicIndexing => &[DeviceRequirement::Feature(
"shader_storage_image_array_dynamic_indexing",
)],
Capability::ClipDistance => &[DeviceRequirement::Feature("shader_clip_distance")],
Capability::CullDistance => &[DeviceRequirement::Feature("shader_cull_distance")],
Capability::ImageCubeArray => &[DeviceRequirement::Feature("image_cube_array")],
Capability::SampleRateShading => &[DeviceRequirement::Feature("sample_rate_shading")],
Capability::SparseResidency => &[DeviceRequirement::Feature("shader_resource_residency")],
Capability::MinLod => &[DeviceRequirement::Feature("shader_resource_min_lod")],
Capability::SampledCubeArray => &[DeviceRequirement::Feature("image_cube_array")],
Capability::ImageMSArray => &[DeviceRequirement::Feature(
"shader_storage_image_multisample",
)],
Capability::StorageImageExtendedFormats => &[],
Capability::InterpolationFunction => &[DeviceRequirement::Feature("sample_rate_shading")],
Capability::StorageImageReadWithoutFormat => &[DeviceRequirement::Feature(
"shader_storage_image_read_without_format",
)],
Capability::StorageImageWriteWithoutFormat => &[DeviceRequirement::Feature(
"shader_storage_image_write_without_format",
)],
Capability::MultiViewport => &[DeviceRequirement::Feature("multi_viewport")],
Capability::DrawParameters => &[
DeviceRequirement::Feature("shader_draw_parameters"),
DeviceRequirement::Extension("khr_shader_draw_parameters"),
],
Capability::MultiView => &[DeviceRequirement::Feature("multiview")],
Capability::DeviceGroup => &[
DeviceRequirement::Version(1, 1),
DeviceRequirement::Extension("khr_device_group"),
],
Capability::VariablePointersStorageBuffer => &[DeviceRequirement::Feature(
"variable_pointers_storage_buffer",
)],
Capability::VariablePointers => &[DeviceRequirement::Feature("variable_pointers")],
Capability::ShaderClockKHR => &[DeviceRequirement::Extension("khr_shader_clock")],
Capability::StencilExportEXT => {
&[DeviceRequirement::Extension("ext_shader_stencil_export")]
} }
Capability::UniformBufferArrayDynamicIndexing => { Capability::SubgroupBallotKHR => {
DeviceRequirement::Features(&["shader_uniform_buffer_array_dynamic_indexing"]) &[DeviceRequirement::Extension("ext_shader_subgroup_ballot")]
} }
Capability::SampledImageArrayDynamicIndexing => { Capability::SubgroupVoteKHR => &[DeviceRequirement::Extension("ext_shader_subgroup_vote")],
DeviceRequirement::Features(&["shader_sampled_image_array_dynamic_indexing"]) Capability::ImageReadWriteLodAMD => &[DeviceRequirement::Extension(
"amd_shader_image_load_store_lod",
)],
Capability::ImageGatherBiasLodAMD => {
&[DeviceRequirement::Extension("amd_texture_gather_bias_lod")]
} }
Capability::StorageBufferArrayDynamicIndexing => { Capability::FragmentMaskAMD => &[DeviceRequirement::Extension("amd_shader_fragment_mask")],
DeviceRequirement::Features(&["shader_storage_buffer_array_dynamic_indexing"]) Capability::SampleMaskOverrideCoverageNV => &[DeviceRequirement::Extension(
"nv_sample_mask_override_coverage",
)],
Capability::GeometryShaderPassthroughNV => &[DeviceRequirement::Extension(
"nv_geometry_shader_passthrough",
)],
Capability::ShaderViewportIndex => {
&[DeviceRequirement::Feature("shader_output_viewport_index")]
} }
Capability::StorageImageArrayDynamicIndexing => { Capability::ShaderLayer => &[DeviceRequirement::Feature("shader_output_layer")],
DeviceRequirement::Features(&["shader_storage_image_array_dynamic_indexing"]) Capability::ShaderViewportIndexLayerEXT => &[
} DeviceRequirement::Extension("ext_shader_viewport_index_layer"),
Capability::ClipDistance => DeviceRequirement::Features(&["shader_clip_distance"]), DeviceRequirement::Extension("nv_viewport_array2"),
Capability::CullDistance => DeviceRequirement::Features(&["shader_cull_distance"]), ],
Capability::ImageCubeArray => DeviceRequirement::Features(&["image_cube_array"]), Capability::ShaderViewportMaskNV => &[DeviceRequirement::Extension("nv_viewport_array2")],
Capability::SampleRateShading => DeviceRequirement::Features(&["sample_rate_shading"]), Capability::PerViewAttributesNV => &[DeviceRequirement::Extension(
Capability::ImageRect => panic!(), // not supported "nvx_multiview_per_view_attributes",
Capability::SampledRect => panic!(), // not supported )],
Capability::GenericPointer => panic!(), // not supported
Capability::Int8 => DeviceRequirement::Extensions(&["khr_8bit_storage"]),
Capability::InputAttachment => DeviceRequirement::None,
Capability::SparseResidency => DeviceRequirement::Features(&["shader_resource_residency"]),
Capability::MinLod => DeviceRequirement::Features(&["shader_resource_min_lod"]),
Capability::Sampled1D => DeviceRequirement::None,
Capability::Image1D => DeviceRequirement::None,
Capability::SampledCubeArray => DeviceRequirement::Features(&["image_cube_array"]),
Capability::SampledBuffer => DeviceRequirement::None,
Capability::ImageBuffer => DeviceRequirement::None,
Capability::ImageMSArray => {
DeviceRequirement::Features(&["shader_storage_image_multisample"])
}
Capability::StorageImageExtendedFormats => {
DeviceRequirement::Features(&["shader_storage_image_extended_formats"])
}
Capability::ImageQuery => DeviceRequirement::None,
Capability::DerivativeControl => DeviceRequirement::None,
Capability::InterpolationFunction => DeviceRequirement::Features(&["sample_rate_shading"]),
Capability::TransformFeedback => panic!(), // not supported
Capability::GeometryStreams => panic!(), // not supported
Capability::StorageImageReadWithoutFormat => {
DeviceRequirement::Features(&["shader_storage_image_read_without_format"])
}
Capability::StorageImageWriteWithoutFormat => {
DeviceRequirement::Features(&["shader_storage_image_write_without_format"])
}
Capability::MultiViewport => DeviceRequirement::Features(&["multi_viewport"]),
Capability::DrawParameters => DeviceRequirement::Features(&["shader_draw_parameters"]),
Capability::StorageBuffer16BitAccess => { Capability::StorageBuffer16BitAccess => {
DeviceRequirement::Extensions(&["khr_16bit_storage"]) &[DeviceRequirement::Feature("storage_buffer16_bit_access")]
} }
Capability::UniformAndStorageBuffer16BitAccess => { Capability::UniformAndStorageBuffer16BitAccess => &[DeviceRequirement::Feature(
DeviceRequirement::Extensions(&["khr_16bit_storage"]) "uniform_and_storage_buffer16_bit_access",
)],
Capability::StoragePushConstant16 => {
&[DeviceRequirement::Feature("storage_push_constant16")]
} }
Capability::StoragePushConstant16 => DeviceRequirement::Extensions(&["khr_16bit_storage"]), Capability::StorageInputOutput16 => &[DeviceRequirement::Feature("storage_input_output16")],
Capability::StorageInputOutput16 => DeviceRequirement::Extensions(&["khr_16bit_storage"]),
Capability::MultiView => DeviceRequirement::Features(&["multiview"]),
Capability::StoragePushConstant8 => DeviceRequirement::Extensions(&["khr_8bit_storage"]),
Capability::SubgroupDispatch => todo!(),
Capability::NamedBarrier => todo!(),
Capability::PipeStorage => todo!(),
Capability::GroupNonUniform => todo!(), Capability::GroupNonUniform => todo!(),
Capability::GroupNonUniformVote => todo!(), Capability::GroupNonUniformVote => todo!(),
Capability::GroupNonUniformArithmetic => todo!(), Capability::GroupNonUniformArithmetic => todo!(),
@ -533,98 +598,170 @@ fn capability_requirement(cap: &Capability) -> DeviceRequirement {
Capability::GroupNonUniformShuffleRelative => todo!(), Capability::GroupNonUniformShuffleRelative => todo!(),
Capability::GroupNonUniformClustered => todo!(), Capability::GroupNonUniformClustered => todo!(),
Capability::GroupNonUniformQuad => todo!(), Capability::GroupNonUniformQuad => todo!(),
Capability::ShaderLayer => todo!(), Capability::GroupNonUniformPartitionedNV => todo!(),
Capability::ShaderViewportIndex => todo!(), Capability::SampleMaskPostDepthCoverage => {
Capability::SubgroupBallotKHR => todo!(), &[DeviceRequirement::Extension("ext_post_depth_coverage")]
Capability::SubgroupVoteKHR => todo!(),
Capability::DeviceGroup => todo!(),
Capability::VariablePointersStorageBuffer => todo!(),
Capability::VariablePointers => todo!(),
Capability::AtomicStorageOps => todo!(),
Capability::SampleMaskPostDepthCoverage => todo!(),
Capability::StorageBuffer8BitAccess => todo!(),
Capability::UniformAndStorageBuffer8BitAccess => {
DeviceRequirement::Extensions(&["khr_8bit_storage"])
} }
Capability::ShaderNonUniform => &[
DeviceRequirement::Version(1, 2),
DeviceRequirement::Extension("ext_descriptor_indexing"),
],
Capability::RuntimeDescriptorArray => {
&[DeviceRequirement::Feature("runtime_descriptor_array")]
}
Capability::InputAttachmentArrayDynamicIndexing => &[DeviceRequirement::Feature(
"shader_input_attachment_array_dynamic_indexing",
)],
Capability::UniformTexelBufferArrayDynamicIndexing => &[DeviceRequirement::Feature(
"shader_uniform_texel_buffer_array_dynamic_indexing",
)],
Capability::StorageTexelBufferArrayDynamicIndexing => &[DeviceRequirement::Feature(
"shader_storage_texel_buffer_array_dynamic_indexing",
)],
Capability::UniformBufferArrayNonUniformIndexing => &[DeviceRequirement::Feature(
"shader_uniform_buffer_array_non_uniform_indexing",
)],
Capability::SampledImageArrayNonUniformIndexing => &[DeviceRequirement::Feature(
"shader_sampled_image_array_non_uniform_indexing",
)],
Capability::StorageBufferArrayNonUniformIndexing => &[DeviceRequirement::Feature(
"shader_storage_buffer_array_non_uniform_indexing",
)],
Capability::StorageImageArrayNonUniformIndexing => &[DeviceRequirement::Feature(
"shader_storage_image_array_non_uniform_indexing",
)],
Capability::InputAttachmentArrayNonUniformIndexing => &[DeviceRequirement::Feature(
"shader_input_attachment_array_non_uniform_indexing",
)],
Capability::UniformTexelBufferArrayNonUniformIndexing => &[DeviceRequirement::Feature(
"shader_uniform_texel_buffer_array_non_uniform_indexing",
)],
Capability::StorageTexelBufferArrayNonUniformIndexing => &[DeviceRequirement::Feature(
"shader_storage_texel_buffer_array_non_uniform_indexing",
)],
Capability::Float16 => &[
DeviceRequirement::Feature("shader_float16"),
DeviceRequirement::Extension("amd_gpu_shader_half_float"),
],
Capability::Int8 => &[DeviceRequirement::Feature("shader_int8")],
Capability::StorageBuffer8BitAccess => {
&[DeviceRequirement::Feature("storage_buffer8_bit_access")]
}
Capability::UniformAndStorageBuffer8BitAccess => &[DeviceRequirement::Feature(
"uniform_and_storage_buffer8_bit_access",
)],
Capability::StoragePushConstant8 => &[DeviceRequirement::Feature("storage_push_constant8")],
Capability::VulkanMemoryModel => &[DeviceRequirement::Feature("vulkan_memory_model")],
Capability::VulkanMemoryModelDeviceScope => &[DeviceRequirement::Feature(
"vulkan_memory_model_device_scope",
)],
Capability::DenormPreserve => todo!(), Capability::DenormPreserve => todo!(),
Capability::DenormFlushToZero => todo!(), Capability::DenormFlushToZero => todo!(),
Capability::SignedZeroInfNanPreserve => todo!(), Capability::SignedZeroInfNanPreserve => todo!(),
Capability::RoundingModeRTE => todo!(), Capability::RoundingModeRTE => todo!(),
Capability::RoundingModeRTZ => todo!(), Capability::RoundingModeRTZ => todo!(),
Capability::RayQueryProvisionalKHR => todo!(), Capability::ComputeDerivativeGroupQuadsNV => {
Capability::RayTraversalPrimitiveCullingProvisionalKHR => todo!(), &[DeviceRequirement::Feature("compute_derivative_group_quads")]
Capability::Float16ImageAMD => todo!(), }
Capability::ImageGatherBiasLodAMD => todo!(), Capability::ComputeDerivativeGroupLinearNV => &[DeviceRequirement::Feature(
Capability::FragmentMaskAMD => todo!(), "compute_derivative_group_linear",
Capability::StencilExportEXT => todo!(), )],
Capability::ImageReadWriteLodAMD => todo!(), Capability::FragmentBarycentricNV => {
Capability::ShaderClockKHR => todo!(), &[DeviceRequirement::Feature("fragment_shader_barycentric")]
Capability::SampleMaskOverrideCoverageNV => todo!(), }
Capability::GeometryShaderPassthroughNV => todo!(), Capability::ImageFootprintNV => &[DeviceRequirement::Feature("image_footprint")],
Capability::ShaderViewportIndexLayerEXT => todo!(), Capability::MeshShadingNV => &[DeviceRequirement::Extension("nv_mesh_shader")],
Capability::ShaderViewportMaskNV => todo!(), Capability::RayTracingProvisionalKHR => {
Capability::ShaderStereoViewNV => todo!(), &[DeviceRequirement::Feature("ray_tracing_pipeline")]
Capability::PerViewAttributesNV => todo!(), }
Capability::FragmentFullyCoveredEXT => todo!(), Capability::RayQueryProvisionalKHR => &[DeviceRequirement::Feature("ray_query")],
Capability::MeshShadingNV => todo!(), Capability::RayTraversalPrimitiveCullingProvisionalKHR => &[DeviceRequirement::Feature(
Capability::ImageFootprintNV => todo!(), "ray_traversal_primitive_culling",
Capability::FragmentBarycentricNV => todo!(), )],
Capability::ComputeDerivativeGroupQuadsNV => todo!(), Capability::RayTracingNV => &[DeviceRequirement::Extension("nv_ray_tracing")],
Capability::FragmentDensityEXT => todo!(), // Capability::RayTracingMotionBlurNV => &[DeviceRequirement::Feature("ray_tracing_motion_blur")],
Capability::GroupNonUniformPartitionedNV => todo!(), Capability::TransformFeedback => &[DeviceRequirement::Feature("transform_feedback")],
Capability::ShaderNonUniform => todo!(), Capability::GeometryStreams => &[DeviceRequirement::Feature("geometry_streams")],
Capability::RuntimeDescriptorArray => todo!(), Capability::FragmentDensityEXT => &[
Capability::InputAttachmentArrayDynamicIndexing => todo!(), DeviceRequirement::Feature("fragment_density_map"),
Capability::UniformTexelBufferArrayDynamicIndexing => todo!(), DeviceRequirement::Feature("shading_rate_image"),
Capability::StorageTexelBufferArrayDynamicIndexing => todo!(), ],
Capability::UniformBufferArrayNonUniformIndexing => todo!(), Capability::PhysicalStorageBufferAddresses => {
Capability::SampledImageArrayNonUniformIndexing => todo!(), &[DeviceRequirement::Feature("buffer_device_address")]
Capability::StorageBufferArrayNonUniformIndexing => todo!(), }
Capability::StorageImageArrayNonUniformIndexing => todo!(), Capability::CooperativeMatrixNV => &[DeviceRequirement::Feature("cooperative_matrix")],
Capability::InputAttachmentArrayNonUniformIndexing => todo!(), Capability::IntegerFunctions2INTEL => {
Capability::UniformTexelBufferArrayNonUniformIndexing => todo!(), &[DeviceRequirement::Feature("shader_integer_functions2")]
Capability::StorageTexelBufferArrayNonUniformIndexing => todo!(), }
Capability::RayTracingNV => todo!(), Capability::ShaderSMBuiltinsNV => &[DeviceRequirement::Feature("shader_sm_builtins")],
Capability::VulkanMemoryModel => todo!(), Capability::FragmentShaderSampleInterlockEXT => &[DeviceRequirement::Feature(
Capability::VulkanMemoryModelDeviceScope => todo!(), "fragment_shader_sample_interlock",
Capability::PhysicalStorageBufferAddresses => todo!(), )],
Capability::ComputeDerivativeGroupLinearNV => todo!(), Capability::FragmentShaderPixelInterlockEXT => &[DeviceRequirement::Feature(
Capability::RayTracingProvisionalKHR => todo!(), "fragment_shader_pixel_interlock",
Capability::CooperativeMatrixNV => todo!(), )],
Capability::FragmentShaderSampleInterlockEXT => todo!(), Capability::FragmentShaderShadingRateInterlockEXT => &[
Capability::FragmentShaderShadingRateInterlockEXT => todo!(), DeviceRequirement::Feature("fragment_shader_shading_rate_interlock"),
Capability::ShaderSMBuiltinsNV => todo!(), DeviceRequirement::Feature("shading_rate_image"),
Capability::FragmentShaderPixelInterlockEXT => todo!(), ],
Capability::DemoteToHelperInvocationEXT => todo!(), Capability::DemoteToHelperInvocationEXT => &[DeviceRequirement::Feature(
Capability::SubgroupShuffleINTEL => todo!(), "shader_demote_to_helper_invocation",
Capability::SubgroupBufferBlockIOINTEL => todo!(), )],
Capability::SubgroupImageBlockIOINTEL => todo!(), // Capability::FragmentShadingRateKHR => &[DeviceRequirement::Feature("pipeline_fragment_shading_rate"), DeviceRequirement::Feature("primitive_fragment_shading_rate"), DeviceRequirement::Feature("attachment_fragment_shading_rate")],
Capability::SubgroupImageMediaBlockIOINTEL => todo!(), // Capability::WorkgroupMemoryExplicitLayoutKHR => &[DeviceRequirement::Feature("workgroup_memory_explicit_layout")],
Capability::IntegerFunctions2INTEL => todo!(), // Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR => &[DeviceRequirement::Feature("workgroup_memory_explicit_layout8_bit_access")],
Capability::SubgroupAvcMotionEstimationINTEL => todo!(), // Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR => &[DeviceRequirement::Feature("workgroup_memory_explicit_layout16_bit_access")],
Capability::SubgroupAvcMotionEstimationIntraINTEL => todo!(), Capability::Addresses => panic!(), // not supported
Capability::SubgroupAvcMotionEstimationChromaINTEL => todo!(), Capability::Linkage => panic!(), // not supported
Capability::Kernel => panic!(), // not supported
Capability::Vector16 => panic!(), // not supported
Capability::Float16Buffer => panic!(), // not supported
Capability::ImageBasic => panic!(), // not supported
Capability::ImageReadWrite => panic!(), // not supported
Capability::ImageMipmap => panic!(), // not supported
Capability::Pipes => panic!(), // not supported
Capability::Groups => panic!(), // not supported
Capability::DeviceEnqueue => panic!(), // not supported
Capability::LiteralSampler => panic!(), // not supported
Capability::AtomicStorage => panic!(), // not supported
Capability::ImageRect => panic!(), // not supported
Capability::SampledRect => panic!(), // not supported
Capability::GenericPointer => panic!(), // not supported
Capability::SubgroupDispatch => panic!(), // not supported,
Capability::NamedBarrier => panic!(), // not supported,
Capability::PipeStorage => panic!(), // not supported,
Capability::AtomicStorageOps => panic!(), // not supported,
Capability::Float16ImageAMD => panic!(), // not supported,
Capability::ShaderStereoViewNV => panic!(), // not supported,
Capability::FragmentFullyCoveredEXT => panic!(), // not supported,
Capability::SubgroupShuffleINTEL => panic!(), // not supported,
Capability::SubgroupBufferBlockIOINTEL => panic!(), // not supported,
Capability::SubgroupImageBlockIOINTEL => panic!(), // not supported,
Capability::SubgroupImageMediaBlockIOINTEL => panic!(), // not supported,
Capability::SubgroupAvcMotionEstimationINTEL => panic!(), // not supported,
Capability::SubgroupAvcMotionEstimationIntraINTEL => panic!(), // not supported,
Capability::SubgroupAvcMotionEstimationChromaINTEL => panic!(), // not supported,
} }
} }
/// Returns the Vulkan device requirement for a SPIR-V storage class. /// Returns the Vulkan device requirement for a SPIR-V storage class.
fn storage_class_requirement(storage_class: &StorageClass) -> DeviceRequirement { fn storage_class_requirement(storage_class: &StorageClass) -> &'static [DeviceRequirement] {
match *storage_class { match *storage_class {
StorageClass::UniformConstant => DeviceRequirement::None, StorageClass::UniformConstant => &[],
StorageClass::Input => DeviceRequirement::None, StorageClass::Input => &[],
StorageClass::Uniform => DeviceRequirement::None, StorageClass::Uniform => &[],
StorageClass::Output => DeviceRequirement::None, StorageClass::Output => &[],
StorageClass::Workgroup => DeviceRequirement::None, StorageClass::Workgroup => &[],
StorageClass::CrossWorkgroup => DeviceRequirement::None, StorageClass::CrossWorkgroup => &[],
StorageClass::Private => DeviceRequirement::None, StorageClass::Private => &[],
StorageClass::Function => DeviceRequirement::None, StorageClass::Function => &[],
StorageClass::Generic => DeviceRequirement::None, StorageClass::Generic => &[],
StorageClass::PushConstant => DeviceRequirement::None, StorageClass::PushConstant => &[],
StorageClass::AtomicCounter => DeviceRequirement::None, StorageClass::AtomicCounter => &[],
StorageClass::Image => DeviceRequirement::None, StorageClass::Image => &[],
StorageClass::StorageBuffer => { StorageClass::StorageBuffer => &[DeviceRequirement::Extension(
DeviceRequirement::Extensions(&["khr_storage_buffer_storage_class"]) "khr_storage_buffer_storage_class",
} )],
StorageClass::CallableDataNV => todo!(), StorageClass::CallableDataNV => todo!(),
StorageClass::IncomingCallableDataNV => todo!(), StorageClass::IncomingCallableDataNV => todo!(),
StorageClass::RayPayloadNV => todo!(), StorageClass::RayPayloadNV => todo!(),
@ -636,9 +773,9 @@ fn storage_class_requirement(storage_class: &StorageClass) -> DeviceRequirement
} }
enum DeviceRequirement { enum DeviceRequirement {
None, Feature(&'static str),
Features(&'static [&'static str]), Extension(&'static str),
Extensions(&'static [&'static str]), Version(u32, u32),
} }
#[cfg(test)] #[cfg(test)]