Skip to content

Commit b871ebc

Browse files
committed
Support implicit capability declarations per SPIR-V spec
Per the spec's Capability table "Implicitly Declares" column, declaring a capability transitively declares its dependencies. For example, declaring GroupNonUniformArithmetic implicitly declares GroupNonUniform. Add expand_implicit_capabilities() which computes the transitive closure using grammar data, matching the C++ validator's RegisterCapability(). Also refactor capabilities.rs: - Extract validate_capabilities into focused helper functions - Remove dead code (is_soft_dependency, required_capabilities_for_capability) - Make internal helpers private (aliases, is_vendor_extension, etc.) - Rename functions for clarity (required_extension, required_version) - Deduplicate capability extraction via collect_explicit_capabilities - Simplify capability_operand and capability_satisfied - Update tests to expect success for implicit declarations
1 parent 8a74989 commit b871ebc

File tree

4 files changed

+380
-504
lines changed

4 files changed

+380
-504
lines changed

rust/spirv-tools-core/src/validation/helpers.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -535,18 +535,14 @@ pub fn collect_result_types(module: &Module) -> Result<HashMap<ResultId, TypeId>
535535
Ok(result)
536536
}
537537

538-
/// Collects all declared capabilities.
538+
/// Collects all declared capabilities, including implicitly declared ones.
539+
///
540+
/// Per the SPIR-V spec, declaring a capability implicitly declares its
541+
/// dependencies (transitively). This function returns the effective set.
539542
pub fn collect_declared_capabilities(module: &Module) -> HashSet<Capability> {
540-
module
541-
.capabilities
542-
.iter()
543-
.filter_map(|inst| {
544-
inst.operands.first().and_then(|op| match op {
545-
Operand::Capability(cap) => Some(*cap),
546-
_ => None,
547-
})
548-
})
549-
.collect()
543+
use super::rules::capabilities::{collect_explicit_capabilities, expand_implicit_capabilities};
544+
545+
expand_implicit_capabilities(&collect_explicit_capabilities(module))
550546
}
551547

552548
// ============================================================================

rust/spirv-tools-core/src/validation/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ use helpers::{
9292
collect_result_opcodes, collect_result_types, is_memory_object_declaration,
9393
};
9494
use rules::capabilities::{
95-
capability_operand, capability_satisfied, required_extension_for_capability,
96-
validate_capabilities,
95+
capability_operand, capability_satisfied, required_extension, validate_capabilities,
9796
};
9897
use rules::extensions::{
9998
extension_operand, extension_satisfied, has_extension, validate_extension_allowlist,
@@ -911,7 +910,7 @@ fn validate_instruction_requirements(
911910
// Also check if any of the instruction's required capabilities have enabling extensions
912911
let has_extension_from_cap = !inst.class.capabilities.is_empty()
913912
&& inst.class.capabilities.iter().any(|&cap| {
914-
if let Some(ext) = required_extension_for_capability(cap) {
913+
if let Some(ext) = required_extension(cap) {
915914
extension_satisfied(ext, extensions, target_version)
916915
} else {
917916
false

0 commit comments

Comments
 (0)