diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index 564c9be859..1a2af74245 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -1,3 +1,5 @@ +#![allow(clippy::missing_safety_doc)] + #[cfg(target_arch = "spirv")] use crate::arch::barrier; use crate::float::Float; @@ -30,8 +32,14 @@ pub enum GroupOperation { /// A binary operation with an identity I and n (where n is the size of the workgroup) /// elements[a0, a1, … an-1] resulting in [I, a0, (a0 op a1), … (a0 op a1 op … op an-2)]. ExclusiveScan = 2, - // /// See [`GROUP_OPERATION_CLUSTERED_REDUCE`] - // ClusteredReduce = 3, + /// The [`GroupOperation`] `ClusteredReduce`. + /// + /// All instructions with a [`GroupOperation`] require an additional `ClusterSize` parameter when [`GroupOperation`] is + /// `ClusteredReduce`. To map this requirement into rust, all function have a base version accepting [`GroupOperation`] + /// as a const generic, and a `_clustered` variant that is fixed to `ClusteredReduce` and takes the additional + /// `ClusterSize` parameter as a const generic. To not accidentally use a `ClusteredReduce` in the base variant of the + /// function, it was removed from the [`GroupOperation`] enum and instead resides individually. + ClusteredReduce = 3, /// Reserved. /// /// Requires Capability `GroupNonUniformPartitionedNV`. @@ -46,15 +54,6 @@ pub enum GroupOperation { PartitionedExclusiveScanNV = 8, } -/// The [`GroupOperation`] `ClusteredReduce`. -/// -/// All instructions with a [`GroupOperation`] require an additional `ClusterSize` parameter when [`GroupOperation`] is -/// `ClusteredReduce`. To map this requirement into rust, all function have a base version accepting [`GroupOperation`] -/// as a const generic, and a `_clustered` variant that is fixed to `ClusteredReduce` and takes the additional -/// `ClusterSize` parameter as a const generic. To not accidentally use a `ClusteredReduce` in the base variant of the -/// function, it was removed from the [`GroupOperation`] enum and instead resides individually. -pub const GROUP_OPERATION_CLUSTERED_REDUCE: u32 = 3; - /// Only usable if the extension GL_KHR_shader_subgroup_basic is enabled. /// /// The function subgroupBarrier() enforces that all active invocations within a @@ -470,42 +469,56 @@ pub unsafe fn subgroup_ballot_bit_extract(subgroup_mask: SubgroupMask, id: u32) result } -/// Result is the number of bits that are set to 1 in Value, considering only the bits in Value required to represent all bits of the group's invocations. -/// -/// Result Type must be a scalar of integer type, whose Signedness operand is 0. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// Value must be a vector of four components of integer type scalar, whose Width operand is 32 and whose Signedness operand is 0. -/// -/// Value is a set of bitfields where the first invocation is represented in the lowest bit of the first vector component and the last (up to the size of the group) is the higher bit number of the last bitmask needed to represent all bits of the group invocations. -/// -/// Requires Capability `GroupNonUniformBallot`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformBallotBitCount")] -#[inline] -pub unsafe fn subgroup_ballot_bit_count(subgroup_mask: SubgroupMask) -> u32 { - let mut result = 0; - - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%subgroup_mask = OpLoad _ {subgroup_mask}", - "%result = OpGroupNonUniformBallotBitCount %u32 %subgroup {groupop} %subgroup_mask", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - subgroup_mask = in(reg) &subgroup_mask, - result = in(reg) &mut result, +macro_rules! macro_subgroup_ballot_bit_count { + ($name:ident, $group_op:expr) => { + /// Result is the number of bits that are set to 1 in Value, considering only the bits in Value required to represent all bits of the group's invocations. + /// + /// Result Type must be a scalar of integer type, whose Signedness operand is 0. + /// + /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + /// + /// The identity I for Operation is 0. + /// + /// Value must be a vector of four components of integer type scalar, whose Width operand is 32 and whose Signedness operand is 0. + /// + /// Value is a set of bitfields where the first invocation is represented in the lowest bit of the first vector component and the last (up to the size of the group) is the higher bit number of the last bitmask needed to represent all bits of the group invocations. + /// + /// Requires Capability `GroupNonUniformBallot`. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpGroupNonUniformBallotBitCount")] + #[inline] + pub unsafe fn $name(subgroup_mask: SubgroupMask) -> u32 { + let mut result = 0; + + unsafe { + asm! { + "%u32 = OpTypeInt 32 0", + "%subgroup = OpConstant %u32 {subgroup}", + "%subgroup_mask = OpLoad _ {subgroup_mask}", + "%result = OpGroupNonUniformBallotBitCount %u32 %subgroup {groupop} %subgroup_mask", + "OpStore {result} %result", + subgroup = const SUBGROUP, + groupop = const ($group_op as u32), + subgroup_mask = in(reg) &subgroup_mask, + result = in(reg) &mut result, + } + } + + result } - } - - result + }; } +macro_subgroup_ballot_bit_count!(subgroup_ballot_bit_count, GroupOperation::Reduce); +macro_subgroup_ballot_bit_count!( + subgroup_ballot_inclusive_bit_count, + GroupOperation::InclusiveScan +); +macro_subgroup_ballot_bit_count!( + subgroup_ballot_exclusive_bit_count, + GroupOperation::ExclusiveScan +); + /// Find the least significant bit set to 1 in Value, considering only the bits in Value required to represent all bits of the group's invocations. If none of the considered bits is set to 1, the resulting value is undefined. /// /// Result Type must be a scalar of integer type, whose Signedness operand is 0. @@ -720,1285 +733,531 @@ pub unsafe fn subgroup_shuffle_down(value: T, delta: u32) -> result } -/// An integer add group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformIAdd")] -#[inline] -pub unsafe fn subgroup_i_add>( - value: I, -) -> I { - let mut result = I::default(); - - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformIAdd _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, +macro_rules! macro_subgroup_op { + ($scalar:ty, $asm_op:literal, $($name:ident, $group_op:expr),+; $docs:literal) => { $( + #[doc = $docs] + #[spirv_std_macros::gpu_only] + #[doc(alias = $asm_op)] + #[inline] + pub unsafe fn $name>( + value: I, + ) -> I { + let mut result = I::default(); + unsafe { + asm! { + "%u32 = OpTypeInt 32 0", + "%subgroup = OpConstant %u32 {subgroup}", + "%value = OpLoad _ {value}", + concat!("%result = ", $asm_op, " _ %subgroup {groupop} %value"), + "OpStore {result} %result", + subgroup = const SUBGROUP, + groupop = const ($group_op as u32), + value = in(reg) &value, + result = in(reg) &mut result, + } + } + result } - } + )+ }; +} - result +macro_rules! macro_subgroup_op_clustered { + ($scalar:ty, $asm_op:literal, $name:ident; $docs:literal) => { + #[doc = $docs] + #[spirv_std_macros::gpu_only] + #[doc(alias = $asm_op)] + #[inline] + pub unsafe fn $name>( + value: I, + ) -> I { + let mut result = I::default(); + + unsafe { + asm! { + "%u32 = OpTypeInt 32 0", + "%subgroup = OpConstant %u32 {subgroup}", + "%value = OpLoad _ {value}", + "%clustersize = OpConstant %u32 {clustersize}", + concat!("%result = ", $asm_op, " _ %subgroup {groupop} %value %clustersize"), + "OpStore {result} %result", + subgroup = const SUBGROUP, + groupop = const (GroupOperation::ClusteredReduce as u32), + clustersize = const CLUSTER_SIZE, + value = in(reg) &value, + result = in(reg) &mut result, + } + } + + result + } + }; } -/// An integer add group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformIAdd")] -#[inline] -pub unsafe fn subgroup_i_add_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +// add +macro_subgroup_op!(impl Integer, "OpGroupNonUniformIAdd", subgroup_i_add, GroupOperation::Reduce, subgroup_inclusive_i_add, GroupOperation::InclusiveScan, subgroup_exclusive_i_add, GroupOperation::ExclusiveScan; r" +An integer add group operation of all Value operands contributed by active invocations in the group. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformIAdd _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Result Type must be a scalar or vector of integer type. - result -} +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// A floating point add group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFAdd")] -#[inline] -pub unsafe fn subgroup_f_add>( - value: F, -) -> F { - let mut result = F::default(); +The identity I for Operation is 0. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformFAdd _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The type of Value must be the same as Result Type. - result -} +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" +An integer add group operation of all Value operands contributed by active invocations in the group. -/// A floating point add group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFAdd")] -#[inline] -pub unsafe fn subgroup_f_add_clustered< - const CLUSTER_SIZE: u32, - F: VectorOrScalar, ->( - value: F, -) -> F { - let mut result = F::default(); +Result Type must be a scalar or vector of integer type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformFAdd _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - result -} +The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// An integer multiply group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 1. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformIMul")] -#[inline] -pub unsafe fn subgroup_i_mul>( - value: I, -) -> I { - let mut result = I::default(); +The type of Value must be the same as Result Type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformIMul _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. - result -} +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); +macro_subgroup_op!(impl Float, "OpGroupNonUniformFAdd", subgroup_f_add, GroupOperation::Reduce, subgroup_inclusive_f_add, GroupOperation::InclusiveScan, subgroup_exclusive_f_add, GroupOperation::ExclusiveScan; r" +A floating point add group operation of all Value operands contributed by active invocations in the group. -/// An integer multiply group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 1. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformIMul")] -#[inline] -pub unsafe fn subgroup_i_mul_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +Result Type must be a scalar or vector of floating-point type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformIMul _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - result -} +The identity I for Operation is 0. -/// A floating point multiply group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 1. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFMul")] -#[inline] -pub unsafe fn subgroup_f_mul>( - value: F, -) -> F { - let mut result = F::default(); +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformFMul _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Float, "OpGroupNonUniformFAdd", subgroup_clustered_f_add; r" +A floating point add group operation of all Value operands contributed by active invocations in the group. - result -} +Result Type must be a scalar or vector of floating-point type. -/// A floating point multiply group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 1. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFMul")] -#[inline] -pub unsafe fn subgroup_f_mul_clustered< - const CLUSTER_SIZE: u32, - F: VectorOrScalar, ->( - value: F, -) -> F { - let mut result = F::default(); +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformFMul _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. - result -} +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. -/// A signed integer minimum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is INT_MAX. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformSMin")] -#[inline] -pub unsafe fn subgroup_s_min< - const GROUP_OP: u32, - S: VectorOrScalar, ->( - value: S, -) -> S { - let mut result = S::default(); +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformSMin _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); - result -} +// mul +macro_subgroup_op!(impl Integer, "OpGroupNonUniformIMul", subgroup_i_mul, GroupOperation::Reduce, subgroup_inclusive_i_mul, GroupOperation::InclusiveScan, subgroup_exclusive_i_mul, GroupOperation::ExclusiveScan; r" +An integer multiply group operation of all Value operands contributed by active invocations in the group. -/// A signed integer minimum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is INT_MAX. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformSMin")] -#[inline] -pub unsafe fn subgroup_s_min_clustered< - const CLUSTER_SIZE: u32, - S: VectorOrScalar, ->( - value: S, -) -> S { - let mut result = S::default(); +Result Type must be a scalar or vector of integer type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformSMin _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - result -} +The identity I for Operation is 1. -/// An unsigned integer minimum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is UINT_MAX. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformUMin")] -#[inline] -pub unsafe fn subgroup_u_min< - const GROUP_OP: u32, - U: VectorOrScalar, ->( - value: U, -) -> U { - let mut result = U::default(); +The type of Value must be the same as Result Type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformUMin _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIMul", subgroup_clustered_i_mul; r" +An integer multiply group operation of all Value operands contributed by active invocations in the group. - result -} +Result Type must be a scalar or vector of integer type. -/// An unsigned integer minimum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is UINT_MAX. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformUMin")] -#[inline] -pub unsafe fn subgroup_u_min_clustered< - const CLUSTER_SIZE: u32, - U: VectorOrScalar, ->( - value: U, -) -> U { - let mut result = U::default(); +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformUMin _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The identity I for Operation is 1. If Operation is ClusteredReduce, ClusterSize must be present. - result -} +The type of Value must be the same as Result Type. -/// A floating point minimum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is +INF. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFMin")] -#[inline] -pub unsafe fn subgroup_f_min>( - value: F, -) -> F { - let mut result = F::default(); +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformFMin _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); +macro_subgroup_op!(impl Float, "OpGroupNonUniformFMul", subgroup_f_mul, GroupOperation::Reduce, subgroup_inclusive_f_mul, GroupOperation::InclusiveScan, subgroup_exclusive_f_mul, GroupOperation::ExclusiveScan; r" +A floating point multiply group operation of all Value operands contributed by active invocations in the group. - result -} +Result Type must be a scalar or vector of floating-point type. -/// A floating point minimum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is +INF. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFMin")] -#[inline] -pub unsafe fn subgroup_f_min_clustered< - const CLUSTER_SIZE: u32, - F: VectorOrScalar, ->( - value: F, -) -> F { - let mut result = F::default(); +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformFMin _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The identity I for Operation is 1. - result -} +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. -/// A signed integer maximum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is INT_MIN. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformSMax")] -#[inline] -pub unsafe fn subgroup_s_max< - const GROUP_OP: u32, - S: VectorOrScalar, ->( - value: S, -) -> S { - let mut result = S::default(); +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Float, "OpGroupNonUniformFMul", subgroup_clustered_f_mul; r" +A floating point multiply group operation of all Value operands contributed by active invocations in the group. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformSMax _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Result Type must be a scalar or vector of floating-point type. - result -} +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// A signed integer maximum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is INT_MIN. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformSMax")] -#[inline] -pub unsafe fn subgroup_s_max_clustered< - const CLUSTER_SIZE: u32, - S: VectorOrScalar, ->( - value: S, -) -> S { - let mut result = S::default(); +The identity I for Operation is 1. If Operation is ClusteredReduce, ClusterSize must be present. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformSMax _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. - result -} +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// An unsigned integer maximum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformUMax")] -#[inline] -pub unsafe fn subgroup_u_max< - const GROUP_OP: u32, - U: VectorOrScalar, ->( - value: U, -) -> U { - let mut result = U::default(); +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformUMax _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +// min +macro_subgroup_op!(impl SignedInteger, "OpGroupNonUniformSMin", subgroup_s_min, GroupOperation::Reduce, subgroup_inclusive_s_min, GroupOperation::InclusiveScan, subgroup_exclusive_s_min, GroupOperation::ExclusiveScan; r" +A signed integer minimum group operation of all Value operands contributed by active invocations in the group. - result -} +Result Type must be a scalar or vector of integer type. -/// An unsigned integer maximum group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformUMax")] -#[inline] -pub unsafe fn subgroup_u_max_clustered< - const CLUSTER_SIZE: u32, - U: VectorOrScalar, ->( - value: U, -) -> U { - let mut result = U::default(); +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformUMax _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The identity I for Operation is INT_MAX. - result -} +The type of Value must be the same as Result Type. -/// A floating point maximum group operation of all Value operands contributed by active invocations in by group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is -INF. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFMax")] -#[inline] -pub unsafe fn subgroup_f_max>( - value: F, -) -> F { - let mut result = F::default(); +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl SignedInteger, "OpGroupNonUniformSMin", subgroup_clustered_s_min; r" +A signed integer minimum group operation of all Value operands contributed by active invocations in the group. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformFMax _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Result Type must be a scalar or vector of integer type. - result -} +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// A floating point maximum group operation of all Value operands contributed by active invocations in by group. -/// -/// Result Type must be a scalar or vector of floating-point type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is -INF. -/// -/// The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformFMax")] -#[inline] -pub unsafe fn subgroup_f_max_clustered< - const CLUSTER_SIZE: u32, - F: VectorOrScalar, ->( - value: F, -) -> F { - let mut result = F::default(); +The identity I for Operation is INT_MAX. If Operation is ClusteredReduce, ClusterSize must be present. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformFMax _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The type of Value must be the same as Result Type. - result -} +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// A bitwise and group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is ~0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformBitwiseAnd")] -#[inline] -pub unsafe fn subgroup_bitwise_and< - const GROUP_OP: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); +macro_subgroup_op!(impl UnsignedInteger, "OpGroupNonUniformUMin", subgroup_u_min, GroupOperation::Reduce, subgroup_inclusive_u_min, GroupOperation::InclusiveScan, subgroup_exclusive_u_min, GroupOperation::ExclusiveScan; r" +An unsigned integer minimum group operation of all Value operands contributed by active invocations in the group. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformBitwiseAnd _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is UINT_MAX. + +The type of Value must be the same as Result Type. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl UnsignedInteger, "OpGroupNonUniformUMin", subgroup_clustered_u_min; r" +An unsigned integer minimum group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is UINT_MAX. If Operation is ClusteredReduce, ClusterSize must be present. + +The type of Value must be the same as Result Type. + +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); +macro_subgroup_op!(impl Float, "OpGroupNonUniformFMin", subgroup_f_min, GroupOperation::Reduce, subgroup_inclusive_f_min, GroupOperation::InclusiveScan, subgroup_exclusive_f_min, GroupOperation::ExclusiveScan; r" +A floating point minimum group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of floating-point type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is +INF. + +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Float, "OpGroupNonUniformFMin", subgroup_clustered_f_min; r" +A floating point minimum group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of floating-point type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is +INF. If Operation is ClusteredReduce, ClusterSize must be present. + +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. + +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); + +// max +macro_subgroup_op!(impl SignedInteger, "OpGroupNonUniformSMax", subgroup_s_max, GroupOperation::Reduce, subgroup_inclusive_s_max, GroupOperation::InclusiveScan, subgroup_exclusive_s_max, GroupOperation::ExclusiveScan; r" +A signed integer maximum group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is INT_MIN. + +The type of Value must be the same as Result Type. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl SignedInteger, "OpGroupNonUniformSMax", subgroup_clustered_s_max; r" +A signed integer maximum group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is INT_MIN. If Operation is ClusteredReduce, ClusterSize must be present. + +The type of Value must be the same as Result Type. + +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); +macro_subgroup_op!(impl UnsignedInteger, "OpGroupNonUniformUMax", subgroup_u_max, GroupOperation::Reduce, subgroup_inclusive_u_max, GroupOperation::InclusiveScan, subgroup_exclusive_u_max, GroupOperation::ExclusiveScan; r" +An unsigned integer maximum group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is 0. + +The type of Value must be the same as Result Type. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl UnsignedInteger, "OpGroupNonUniformUMax", subgroup_clustered_u_max; r" +An unsigned integer maximum group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type, whose Signedness operand is 0. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. + +The type of Value must be the same as Result Type. + +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); +macro_subgroup_op!(impl Float, "OpGroupNonUniformFMax", subgroup_f_max, GroupOperation::Reduce, subgroup_inclusive_f_max, GroupOperation::InclusiveScan, subgroup_exclusive_f_max, GroupOperation::ExclusiveScan; r" +A floating point maximum group operation of all Value operands contributed by active invocations in by group. + +Result Type must be a scalar or vector of floating-point type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is -INF. + +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Float, "OpGroupNonUniformFMax", subgroup_clustered_f_max; r" +A floating point maximum group operation of all Value operands contributed by active invocations in by group. + +Result Type must be a scalar or vector of floating-point type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is -INF. + +The type of Value must be the same as Result Type. The method used to perform the group operation on the contributed Value(s) from active invocations is implementation defined. From the set of Value(s) provided by active invocations within a subgroup, if for any two Values one of them is a NaN, the other is chosen. If all Value(s) that are used by the current invocation are NaN, then the result is an undefined value. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); + +// and +macro_subgroup_op!(impl Integer, "OpGroupNonUniformBitwiseAnd", subgroup_and, GroupOperation::Reduce, subgroup_inclusive_and, GroupOperation::InclusiveScan, subgroup_exclusive_and, GroupOperation::ExclusiveScan; r" +A bitwise and group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is ~0. + +The type of Value must be the same as Result Type. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformBitwiseAnd", subgroup_clustered_and; r" +A bitwise and group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is ~0. If Operation is ClusteredReduce, ClusterSize must be present. + +The type of Value must be the same as Result Type. + +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); + +// or +macro_subgroup_op!(impl Integer, "OpGroupNonUniformBitwiseOr", subgroup_or, GroupOperation::Reduce, subgroup_inclusive_or, GroupOperation::InclusiveScan, subgroup_exclusive_or, GroupOperation::ExclusiveScan; r" +A bitwise or group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is 0. + +The type of Value must be the same as Result Type. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformBitwiseOr", subgroup_clustered_or; r" +A bitwise or group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. + +The type of Value must be the same as Result Type. + +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); + +// xor +macro_subgroup_op!(impl Integer, "OpGroupNonUniformBitwiseXor", subgroup_xor, GroupOperation::Reduce, subgroup_inclusive_xor, GroupOperation::InclusiveScan, subgroup_exclusive_xor, GroupOperation::ExclusiveScan; r" +A bitwise xor group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is 0. + +The type of Value must be the same as Result Type. + +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformBitwiseXor", subgroup_clustered_xor; r" +A bitwise xor group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of integer type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - result -} +The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// A bitwise and group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is ~0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformBitwiseAnd")] -#[inline] -pub unsafe fn subgroup_bitwise_and_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +The type of Value must be the same as Result Type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformBitwiseAnd _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. - result -} +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); -/// A bitwise or group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformBitwiseOr")] -#[inline] -pub unsafe fn subgroup_bitwise_or>( - value: I, -) -> I { - let mut result = I::default(); +// logical and +macro_subgroup_op!(bool, "OpGroupNonUniformLogicalAnd", subgroup_logical_and, GroupOperation::Reduce, subgroup_inclusive_logical_and, GroupOperation::InclusiveScan, subgroup_exclusive_logical_and, GroupOperation::ExclusiveScan; r" +A logical and group operation of all Value operands contributed by active invocations in the group. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformBitwiseOr _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Result Type must be a scalar or vector of Boolean type. - result -} +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// A bitwise or group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformBitwiseOr")] -#[inline] -pub unsafe fn subgroup_bitwise_or_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +The identity I for Operation is ~0. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformBitwiseOr _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The type of Value must be the same as Result Type. - result -} +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(bool, "OpGroupNonUniformLogicalAnd", subgroup_clustered_logical_and; r" +A logical and group operation of all Value operands contributed by active invocations in the group. -/// A bitwise xor group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformBitwiseXor")] -#[inline] -pub unsafe fn subgroup_bitwise_xor< - const GROUP_OP: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +Result Type must be a scalar or vector of Boolean type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformBitwiseXor _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - result -} +The identity I for Operation is ~0. If Operation is ClusteredReduce, ClusterSize must be present. -/// A bitwise xor group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of integer type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformBitwiseXor")] -#[inline] -pub unsafe fn subgroup_bitwise_xor_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +The type of Value must be the same as Result Type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformBitwiseXor _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. - result -} +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); -/// A logical and group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of Boolean type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is ~0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformLogicalAnd")] -#[inline] -pub unsafe fn subgroup_logical_and>( - value: I, -) -> I { - let mut result = I::default(); +// logical or +macro_subgroup_op!(bool, "OpGroupNonUniformLogicalOr", subgroup_logical_or, GroupOperation::Reduce, subgroup_inclusive_logical_or, GroupOperation::InclusiveScan, subgroup_exclusive_logical_or, GroupOperation::ExclusiveScan; r" +A logical or group operation of all Value operands contributed by active invocations in the group. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformLogicalAnd _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Result Type must be a scalar or vector of Boolean type. - result -} +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// A logical and group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of Boolean type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is ~0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformLogicalAnd")] -#[inline] -pub unsafe fn subgroup_logical_and_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +The identity I for Operation is 0. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformLogicalAnd _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The type of Value must be the same as Result Type. - result -} +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(bool, "OpGroupNonUniformLogicalOr", subgroup_clustered_logical_or; r" +A logical or group operation of all Value operands contributed by active invocations in the group. -/// A logical or group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of Boolean type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformLogicalOr")] -#[inline] -pub unsafe fn subgroup_logical_or>( - value: I, -) -> I { - let mut result = I::default(); +Result Type must be a scalar or vector of Boolean type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformLogicalOr _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. - result -} +The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// A logical or group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of Boolean type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformLogicalOr")] -#[inline] -pub unsafe fn subgroup_logical_or_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +The type of Value must be the same as Result Type. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformLogicalOr _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. - result -} +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); -/// A logical xor group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of Boolean type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. -/// -/// The type of Value must be the same as Result Type. -/// -/// Requires Capability `GroupNonUniformArithmetic`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformLogicalXor")] -#[inline] -pub unsafe fn subgroup_logical_xor>( - value: I, -) -> I { - let mut result = I::default(); +// logical xor +macro_subgroup_op!(bool, "OpGroupNonUniformLogicalXor", subgroup_logical_xor, GroupOperation::Reduce, subgroup_inclusive_logical_xor, GroupOperation::InclusiveScan, subgroup_exclusive_logical_xor, GroupOperation::ExclusiveScan; r" +A logical xor group operation of all Value operands contributed by active invocations in the group. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%result = OpGroupNonUniformLogicalXor _ %subgroup {groupop} %value", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OP, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +Result Type must be a scalar or vector of Boolean type. - result -} +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// A logical xor group operation of all Value operands contributed by active invocations in the group. -/// -/// Result Type must be a scalar or vector of Boolean type. -/// -/// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. -/// -/// The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. -/// -/// The type of Value must be the same as Result Type. -/// -/// ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. -/// -/// Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. -#[spirv_std_macros::gpu_only] -#[doc(alias = "OpGroupNonUniformLogicalXor")] -#[inline] -pub unsafe fn subgroup_logical_xor_clustered< - const CLUSTER_SIZE: u32, - I: VectorOrScalar, ->( - value: I, -) -> I { - let mut result = I::default(); +The identity I for Operation is 0. - unsafe { - asm! { - "%u32 = OpTypeInt 32 0", - "%subgroup = OpConstant %u32 {subgroup}", - "%value = OpLoad _ {value}", - "%clustersize = OpConstant %u32 {clustersize}", - "%result = OpGroupNonUniformLogicalXor _ %subgroup {groupop} %value %clustersize", - "OpStore {result} %result", - subgroup = const SUBGROUP, - groupop = const GROUP_OPERATION_CLUSTERED_REDUCE, - clustersize = const CLUSTER_SIZE, - value = in(reg) &value, - result = in(reg) &mut result, - } - } +The type of Value must be the same as Result Type. - result -} +Requires Capability `GroupNonUniformArithmetic`. +"); +macro_subgroup_op_clustered!(bool, "OpGroupNonUniformLogicalXor", subgroup_clustered_logical_xor; r" +A logical xor group operation of all Value operands contributed by active invocations in the group. + +Result Type must be a scalar or vector of Boolean type. + +Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. + +The identity I for Operation is 0. If Operation is ClusteredReduce, ClusterSize must be present. + +The type of Value must be the same as Result Type. + +ClusterSize is the size of cluster to use. ClusterSize must be a scalar of integer type, whose Signedness operand is 0. ClusterSize must come from a constant instruction. Behavior is undefined unless ClusterSize is at least 1 and a power of 2. If ClusterSize is greater than the size of the group, executing this instruction results in undefined behavior. + +Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. +"); /// Result is the Value of the invocation within the quad with a quad index equal to Index. /// diff --git a/tests/ui/arch/subgroup/subgroup_ballot.stderr b/tests/ui/arch/subgroup/subgroup_ballot.stderr index b0e37a1e11..2d7b71e12c 100644 --- a/tests/ui/arch/subgroup/subgroup_ballot.stderr +++ b/tests/ui/arch/subgroup/subgroup_ballot.stderr @@ -1,9 +1,9 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 381 8 +OpLine %6 380 8 %7 = OpGroupNonUniformBallot %8 %9 %4 -OpLine %6 417 8 +OpLine %6 416 8 %10 = OpGroupNonUniformInverseBallot %2 %9 %7 OpNoLine OpReturnValue %10 diff --git a/tests/ui/arch/subgroup/subgroup_ballot_bit_count.rs b/tests/ui/arch/subgroup/subgroup_ballot_bit_count.rs index 166fdabcbc..ff4b492932 100644 --- a/tests/ui/arch/subgroup/subgroup_ballot_bit_count.rs +++ b/tests/ui/arch/subgroup/subgroup_ballot_bit_count.rs @@ -6,7 +6,7 @@ use spirv_std::arch::{GroupOperation, SubgroupMask}; use spirv_std::spirv; unsafe fn subgroup_ballot_bit_count(ballot: SubgroupMask) -> u32 { - spirv_std::arch::subgroup_ballot_bit_count::<{ GroupOperation::Reduce as u32 }>(ballot) + spirv_std::arch::subgroup_ballot_bit_count(ballot) } #[spirv(compute(threads(1, 1, 1)))] diff --git a/tests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr b/tests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr index 4db8589b64..49ff494bc1 100644 --- a/tests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr +++ b/tests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %5 %6 = OpLabel -OpLine %7 493 8 +OpLine %7 512 0 %8 = OpGroupNonUniformBallotBitCount %2 %9 Reduce %4 OpNoLine OpReturnValue %8 diff --git a/tests/ui/arch/subgroup/subgroup_broadcast_first.stderr b/tests/ui/arch/subgroup/subgroup_broadcast_first.stderr index d0ce7e733b..6836a0fd14 100644 --- a/tests/ui/arch/subgroup/subgroup_broadcast_first.stderr +++ b/tests/ui/arch/subgroup/subgroup_broadcast_first.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 348 8 +OpLine %6 347 8 %7 = OpGroupNonUniformBroadcastFirst %2 %8 %4 OpNoLine OpReturnValue %7 diff --git a/tests/ui/arch/subgroup/subgroup_elect.stderr b/tests/ui/arch/subgroup/subgroup_elect.stderr index b142160f81..0cbeb7590b 100644 --- a/tests/ui/arch/subgroup/subgroup_elect.stderr +++ b/tests/ui/arch/subgroup/subgroup_elect.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 183 8 +OpLine %5 182 8 %6 = OpGroupNonUniformElect %2 %7 OpNoLine OpReturnValue %6 diff --git a/tests/ui/arch/subgroup/subgroup_i_add_clustered.rs b/tests/ui/arch/subgroup/subgroup_i_add_clustered.rs index f4cc511461..880325aa61 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_clustered.rs +++ b/tests/ui/arch/subgroup/subgroup_i_add_clustered.rs @@ -7,7 +7,7 @@ use spirv_std::arch::{GroupOperation, SubgroupMask}; use spirv_std::spirv; unsafe fn subgroup_i_add_clustered(value: u32) -> u32 { - spirv_std::arch::subgroup_i_add_clustered::<8, _>(value) + spirv_std::arch::subgroup_clustered_i_add::<8, _>(value) } #[spirv(compute(threads(32, 1, 1)))] diff --git a/tests/ui/arch/subgroup/subgroup_i_add_clustered.stderr b/tests/ui/arch/subgroup/subgroup_i_add_clustered.stderr index df82e0a5c5..d88cfd3296 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_clustered.stderr +++ b/tests/ui/arch/subgroup/subgroup_i_add_clustered.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 784 8 +OpLine %6 810 0 %7 = OpGroupNonUniformIAdd %2 %8 ClusteredReduce %4 %9 OpNoLine OpReturnValue %7 diff --git a/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.rs b/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.rs index a10d0b3682..feab4bd986 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.rs +++ b/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.rs @@ -7,7 +7,7 @@ use spirv_std::arch::{GroupOperation, SubgroupMask}; use spirv_std::spirv; unsafe fn subgroup_i_add_exclusive_scan(value: u32) -> u32 { - spirv_std::arch::subgroup_i_add::<{ GroupOperation::ExclusiveScan as u32 }, _>(value) + spirv_std::arch::subgroup_exclusive_i_add(value) } #[spirv(compute(threads(32, 1, 1)))] diff --git a/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr b/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr index 1f496bf279..ca83820bf0 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr +++ b/tests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 743 8 +OpLine %6 797 0 %7 = OpGroupNonUniformIAdd %2 %8 ExclusiveScan %4 OpNoLine OpReturnValue %7 diff --git a/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.rs b/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.rs index ba823eac10..e880491793 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.rs +++ b/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.rs @@ -7,7 +7,7 @@ use spirv_std::arch::{GroupOperation, SubgroupMask}; use spirv_std::spirv; unsafe fn subgroup_i_add_inclusive_scan(value: u32) -> u32 { - spirv_std::arch::subgroup_i_add::<{ GroupOperation::InclusiveScan as u32 }, _>(value) + spirv_std::arch::subgroup_inclusive_i_add(value) } #[spirv(compute(threads(32, 1, 1)))] diff --git a/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr b/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr index 15694c1f66..93048426c1 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr +++ b/tests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 743 8 +OpLine %6 797 0 %7 = OpGroupNonUniformIAdd %2 %8 InclusiveScan %4 OpNoLine OpReturnValue %7 diff --git a/tests/ui/arch/subgroup/subgroup_i_add_reduce.rs b/tests/ui/arch/subgroup/subgroup_i_add_reduce.rs index 4a8a42dbf6..7739e0f4bf 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_reduce.rs +++ b/tests/ui/arch/subgroup/subgroup_i_add_reduce.rs @@ -7,7 +7,7 @@ use spirv_std::arch::{GroupOperation, SubgroupMask}; use spirv_std::spirv; unsafe fn subgroup_i_add_reduce(value: u32) -> u32 { - spirv_std::arch::subgroup_i_add::<{ GroupOperation::Reduce as u32 }, _>(value) + spirv_std::arch::subgroup_i_add(value) } #[spirv(compute(threads(32, 1, 1)))] diff --git a/tests/ui/arch/subgroup/subgroup_i_add_reduce.stderr b/tests/ui/arch/subgroup/subgroup_i_add_reduce.stderr index fe9ead48a9..f382189af7 100644 --- a/tests/ui/arch/subgroup/subgroup_i_add_reduce.stderr +++ b/tests/ui/arch/subgroup/subgroup_i_add_reduce.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 743 8 +OpLine %6 797 0 %7 = OpGroupNonUniformIAdd %2 %8 Reduce %4 OpNoLine OpReturnValue %7