automatically check for subgroup support when creating a naga Validator

This commit is contained in:
Elabajaba 2024-06-20 02:19:34 -04:00 committed by Teodor Tanasoaia
parent 9b5035cee1
commit 35477dff9a
2 changed files with 28 additions and 22 deletions

View File

@ -124,9 +124,13 @@ bitflags::bitflags! {
/// Support for 64-bit signed and unsigned integers. /// Support for 64-bit signed and unsigned integers.
const SHADER_INT64 = 0x8000; const SHADER_INT64 = 0x8000;
/// Support for subgroup operations. /// Support for subgroup operations.
/// Implies support for subgroup operations in both fragment and compute stages,
/// but not necessarily in the vertex stage, which requires [`Capabilities::SUBGROUP_VERTEX_STAGE`].
const SUBGROUP = 0x10000; const SUBGROUP = 0x10000;
/// Support for subgroup barriers. /// Support for subgroup barriers.
const SUBGROUP_BARRIER = 0x20000; const SUBGROUP_BARRIER = 0x20000;
/// Support for subgroup operations in the vertex stage.
const SUBGROUP_VERTEX_STAGE = 0x40000;
/// Support for [`AtomicFunction::Min`] and [`AtomicFunction::Max`] on /// Support for [`AtomicFunction::Min`] and [`AtomicFunction::Max`] on
/// 64-bit integers in the [`Storage`] address space, when the return /// 64-bit integers in the [`Storage`] address space, when the return
/// value is not used. /// value is not used.
@ -136,9 +140,9 @@ bitflags::bitflags! {
/// [`AtomicFunction::Min`]: crate::AtomicFunction::Min /// [`AtomicFunction::Min`]: crate::AtomicFunction::Min
/// [`AtomicFunction::Max`]: crate::AtomicFunction::Max /// [`AtomicFunction::Max`]: crate::AtomicFunction::Max
/// [`Storage`]: crate::AddressSpace::Storage /// [`Storage`]: crate::AddressSpace::Storage
const SHADER_INT64_ATOMIC_MIN_MAX = 0x40000; const SHADER_INT64_ATOMIC_MIN_MAX = 0x80000;
/// Support for all atomic operations on 64-bit integers. /// Support for all atomic operations on 64-bit integers.
const SHADER_INT64_ATOMIC_ALL_OPS = 0x80000; const SHADER_INT64_ATOMIC_ALL_OPS = 0x100000;
} }
} }
@ -416,11 +420,28 @@ impl crate::TypeInner {
impl Validator { impl Validator {
/// Construct a new validator instance. /// Construct a new validator instance.
pub fn new(flags: ValidationFlags, capabilities: Capabilities) -> Self { pub fn new(flags: ValidationFlags, capabilities: Capabilities) -> Self {
let subgroup_operations = if capabilities.contains(Capabilities::SUBGROUP) {
use SubgroupOperationSet as S;
S::BASIC | S::VOTE | S::ARITHMETIC | S::BALLOT | S::SHUFFLE | S::SHUFFLE_RELATIVE
} else {
SubgroupOperationSet::empty()
};
let subgroup_stages = {
let mut stages = ShaderStages::empty();
if capabilities.contains(Capabilities::SUBGROUP_VERTEX_STAGE) {
stages |= ShaderStages::VERTEX;
}
if capabilities.contains(Capabilities::SUBGROUP) {
stages |= ShaderStages::FRAGMENT | ShaderStages::COMPUTE;
}
stages
};
Validator { Validator {
flags, flags,
capabilities, capabilities,
subgroup_stages: ShaderStages::empty(), subgroup_stages,
subgroup_operations: SubgroupOperationSet::empty(), subgroup_operations,
types: Vec::new(), types: Vec::new(),
layouter: Layouter::default(), layouter: Layouter::default(),
location_mask: BitSet::new(), location_mask: BitSet::new(),

View File

@ -543,25 +543,10 @@ pub fn create_validator(
Caps::SUBGROUP_BARRIER, Caps::SUBGROUP_BARRIER,
features.intersects(wgt::Features::SUBGROUP_BARRIER), features.intersects(wgt::Features::SUBGROUP_BARRIER),
); );
caps.set(
let mut subgroup_stages = naga::valid::ShaderStages::empty(); Caps::SUBGROUP_VERTEX_STAGE,
subgroup_stages.set(
naga::valid::ShaderStages::COMPUTE | naga::valid::ShaderStages::FRAGMENT,
features.contains(wgt::Features::SUBGROUP),
);
subgroup_stages.set(
naga::valid::ShaderStages::VERTEX,
features.contains(wgt::Features::SUBGROUP_VERTEX), features.contains(wgt::Features::SUBGROUP_VERTEX),
); );
let subgroup_operations = if caps.contains(Caps::SUBGROUP) { naga::valid::Validator::new(flags, caps)
use naga::valid::SubgroupOperationSet as S;
S::BASIC | S::VOTE | S::ARITHMETIC | S::BALLOT | S::SHUFFLE | S::SHUFFLE_RELATIVE
} else {
naga::valid::SubgroupOperationSet::empty()
};
let mut validator = naga::valid::Validator::new(flags, caps);
validator.subgroup_stages(subgroup_stages);
validator.subgroup_operations(subgroup_operations);
validator
} }