From ee6b5fbe3612b7adb6ec597466f6ca425dea539c Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 29 Jun 2025 15:21:34 -0400 Subject: [PATCH 01/12] Remove unsafe from subgroup operations for which no undefined results are possible --- crates/spirv-std/src/arch/subgroup.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index 1a2af74245..e063956be3 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -67,7 +67,7 @@ pub enum GroupOperation { #[spirv_std_macros::gpu_only] #[doc(alias = "subgroupBarrier")] #[inline] -pub unsafe fn subgroup_barrier() { +pub fn subgroup_barrier() { unsafe { barrier::control_barrier::< SUBGROUP, @@ -92,7 +92,7 @@ pub unsafe fn subgroup_barrier() { #[spirv_std_macros::gpu_only] #[doc(alias = "subgroupMemoryBarrier")] #[inline] -pub unsafe fn subgroup_memory_barrier() { +pub fn subgroup_memory_barrier() { unsafe { barrier::memory_barrier::< SUBGROUP, @@ -116,7 +116,7 @@ pub unsafe fn subgroup_memory_barrier() { #[spirv_std_macros::gpu_only] #[doc(alias = "subgroupMemoryBarrierBuffer")] #[inline] -pub unsafe fn subgroup_memory_barrier_buffer() { +pub fn subgroup_memory_barrier_buffer() { unsafe { barrier::memory_barrier::< SUBGROUP, @@ -137,7 +137,7 @@ pub unsafe fn subgroup_memory_barrier_buffer() { #[spirv_std_macros::gpu_only] #[doc(alias = "subgroupMemoryBarrierShared")] #[inline] -pub unsafe fn subgroup_memory_barrier_shared() { +pub fn subgroup_memory_barrier_shared() { unsafe { barrier::memory_barrier::< SUBGROUP, @@ -156,7 +156,7 @@ pub unsafe fn subgroup_memory_barrier_shared() { #[spirv_std_macros::gpu_only] #[doc(alias = "subgroupMemoryBarrierImage")] #[inline] -pub unsafe fn subgroup_memory_barrier_image() { +pub fn subgroup_memory_barrier_image() { unsafe { barrier::memory_barrier::< SUBGROUP, @@ -175,7 +175,7 @@ pub unsafe fn subgroup_memory_barrier_image() { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformElect")] #[inline] -pub unsafe fn subgroup_elect() -> bool { +pub fn subgroup_elect() -> bool { let mut result = false; unsafe { @@ -205,7 +205,7 @@ pub unsafe fn subgroup_elect() -> bool { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformAll")] #[inline] -pub unsafe fn subgroup_all(predicate: bool) -> bool { +pub fn subgroup_all(predicate: bool) -> bool { let mut result = false; unsafe { @@ -237,7 +237,7 @@ pub unsafe fn subgroup_all(predicate: bool) -> bool { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformAny")] #[inline] -pub unsafe fn subgroup_any(predicate: bool) -> bool { +pub fn subgroup_any(predicate: bool) -> bool { let mut result = false; unsafe { @@ -269,7 +269,7 @@ pub unsafe fn subgroup_any(predicate: bool) -> bool { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformAllEqual")] #[inline] -pub unsafe fn subgroup_all_equal(value: T) -> bool { +pub fn subgroup_all_equal(value: T) -> bool { let mut result = false; unsafe { @@ -340,7 +340,7 @@ pub unsafe fn subgroup_broadcast(value: T, id: u32) -> T { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBroadcastFirst")] #[inline] -pub unsafe fn subgroup_broadcast_first(value: T) -> T { +pub fn subgroup_broadcast_first(value: T) -> T { let mut result = T::default(); unsafe { @@ -373,7 +373,7 @@ pub unsafe fn subgroup_broadcast_first(value: T) -> T { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallot")] #[inline] -pub unsafe fn subgroup_ballot(predicate: bool) -> SubgroupMask { +pub fn subgroup_ballot(predicate: bool) -> SubgroupMask { let mut result = SubgroupMask::default(); unsafe { @@ -487,7 +487,7 @@ macro_rules! macro_subgroup_ballot_bit_count { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotBitCount")] #[inline] - pub unsafe fn $name(subgroup_mask: SubgroupMask) -> u32 { + pub fn $name(subgroup_mask: SubgroupMask) -> u32 { let mut result = 0; unsafe { @@ -739,7 +739,7 @@ macro_rules! macro_subgroup_op { #[spirv_std_macros::gpu_only] #[doc(alias = $asm_op)] #[inline] - pub unsafe fn $name>( + pub fn $name>( value: I, ) -> I { let mut result = I::default(); From 31bffd9a53ce2161086d5d37cc3a65910be811ab Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 29 Jun 2025 15:25:11 -0400 Subject: [PATCH 02/12] Remove unsafe from subgroup_ballot_bit_extract: undefined result possible, but not undefined behavior --- crates/spirv-std/src/arch/subgroup.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index e063956be3..3b1ff4fd9f 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -447,7 +447,7 @@ pub unsafe fn subgroup_inverse_ballot(subgroup_mask: SubgroupMask) -> bool { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotBitExtract")] #[inline] -pub unsafe fn subgroup_ballot_bit_extract(subgroup_mask: SubgroupMask, id: u32) -> bool { +pub fn subgroup_ballot_bit_extract(subgroup_mask: SubgroupMask, id: u32) -> bool { let mut result = false; unsafe { From c68f0d702932194d0df85663457f26185e3f71cf Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 29 Jun 2025 15:25:57 -0400 Subject: [PATCH 03/12] Remove unsafe from subgroup_ballot_find_{l,m}sb: undefined result possible, but not undefined behavior --- crates/spirv-std/src/arch/subgroup.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index 3b1ff4fd9f..b2f05765bd 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -533,7 +533,7 @@ macro_subgroup_ballot_bit_count!( #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotFindLSB")] #[inline] -pub unsafe fn subgroup_ballot_find_lsb(subgroup_mask: SubgroupMask) -> u32 { +pub fn subgroup_ballot_find_lsb(subgroup_mask: SubgroupMask) -> u32 { let mut result = 0; unsafe { @@ -566,7 +566,7 @@ pub unsafe fn subgroup_ballot_find_lsb(subgroup_mask: SubgroupMask) -> u32 { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotFindMSB")] #[inline] -pub unsafe fn subgroup_ballot_find_msb(subgroup_mask: SubgroupMask) -> u32 { +pub fn subgroup_ballot_find_msb(subgroup_mask: SubgroupMask) -> u32 { let mut result = 0; unsafe { From 4215dddb2122cabf0b0a87719a372bbf0c4418b0 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 29 Jun 2025 15:26:27 -0400 Subject: [PATCH 04/12] Remove unsafe from subgroup_shuffle{,_xor,_up,_down}: undefined result possible, but not undefined behavior --- crates/spirv-std/src/arch/subgroup.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index b2f05765bd..bc8c8fc69c 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -601,7 +601,7 @@ pub fn subgroup_ballot_find_msb(subgroup_mask: SubgroupMask) -> u32 { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffle")] #[inline] -pub unsafe fn subgroup_shuffle(value: T, id: u32) -> T { +pub fn subgroup_shuffle(value: T, id: u32) -> T { let mut result = T::default(); unsafe { @@ -638,7 +638,7 @@ pub unsafe fn subgroup_shuffle(value: T, id: u32) -> T { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffleXor")] #[inline] -pub unsafe fn subgroup_shuffle_xor(value: T, mask: u32) -> T { +pub fn subgroup_shuffle_xor(value: T, mask: u32) -> T { let mut result = T::default(); unsafe { @@ -675,7 +675,7 @@ pub unsafe fn subgroup_shuffle_xor(value: T, mask: u32) -> T #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffleUp")] #[inline] -pub unsafe fn subgroup_shuffle_up(value: T, delta: u32) -> T { +pub fn subgroup_shuffle_up(value: T, delta: u32) -> T { let mut result = T::default(); unsafe { @@ -712,7 +712,7 @@ pub unsafe fn subgroup_shuffle_up(value: T, delta: u32) -> T #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffleDown")] #[inline] -pub unsafe fn subgroup_shuffle_down(value: T, delta: u32) -> T { +pub fn subgroup_shuffle_down(value: T, delta: u32) -> T { let mut result = T::default(); unsafe { From c7adc3cd45e10301e4cc6fca346c2b541a67f71e Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 29 Jun 2025 15:52:16 -0400 Subject: [PATCH 05/12] Remove unsafe from subgroup_quad_swap: undefined result possible, but not undefined behavior --- crates/spirv-std/src/arch/subgroup.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index bc8c8fc69c..3cf4607278 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -1356,7 +1356,7 @@ pub enum QuadDirection { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformQuadSwap")] #[inline] -pub unsafe fn subgroup_quad_swap(value: T) -> T { +pub fn subgroup_quad_swap(value: T) -> T { let mut result = T::default(); unsafe { From 54acee16240ba47a047d79a02dcf31960ec44873 Mon Sep 17 00:00:00 2001 From: Firestar99 Date: Mon, 30 Jun 2025 11:22:55 +0200 Subject: [PATCH 06/12] rename args to match spec docs --- crates/spirv-std/src/arch/subgroup.rs | 52 +++++++++++++-------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index 3cf4607278..a2e800cc00 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -409,7 +409,7 @@ pub fn subgroup_ballot(predicate: bool) -> SubgroupMask { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformInverseBallot")] #[inline] -pub unsafe fn subgroup_inverse_ballot(subgroup_mask: SubgroupMask) -> bool { +pub unsafe fn subgroup_inverse_ballot(value: SubgroupMask) -> bool { let mut result = false; unsafe { @@ -417,11 +417,11 @@ pub unsafe fn subgroup_inverse_ballot(subgroup_mask: SubgroupMask) -> bool { "%bool = OpTypeBool", "%u32 = OpTypeInt 32 0", "%subgroup = OpConstant %u32 {subgroup}", - "%subgroup_mask = OpLoad _ {subgroup_mask}", - "%result = OpGroupNonUniformInverseBallot %bool %subgroup %subgroup_mask", + "%value = OpLoad _ {value}", + "%result = OpGroupNonUniformInverseBallot %bool %subgroup %value", "OpStore {result} %result", subgroup = const SUBGROUP, - subgroup_mask = in(reg) &subgroup_mask, + value = in(reg) &value, result = in(reg) &mut result, } } @@ -447,7 +447,7 @@ pub unsafe fn subgroup_inverse_ballot(subgroup_mask: SubgroupMask) -> bool { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotBitExtract")] #[inline] -pub fn subgroup_ballot_bit_extract(subgroup_mask: SubgroupMask, id: u32) -> bool { +pub fn subgroup_ballot_bit_extract(value: SubgroupMask, index: u32) -> bool { let mut result = false; unsafe { @@ -455,13 +455,13 @@ pub fn subgroup_ballot_bit_extract(subgroup_mask: SubgroupMask, id: u32) -> bool "%bool = OpTypeBool", "%u32 = OpTypeInt 32 0", "%subgroup = OpConstant %u32 {subgroup}", - "%subgroup_mask = OpLoad _ {subgroup_mask}", - "%id = OpLoad _ {id}", - "%result = OpGroupNonUniformBallotBitExtract %bool %subgroup %subgroup_mask %id", + "%value = OpLoad _ {value}", + "%index = OpLoad _ {index}", + "%result = OpGroupNonUniformBallotBitExtract %bool %subgroup %value %index", "OpStore {result} %result", subgroup = const SUBGROUP, - subgroup_mask = in(reg) &subgroup_mask, - id = in(reg) &id, + value = in(reg) &value, + index = in(reg) &index, result = in(reg) &mut result, } } @@ -487,19 +487,19 @@ macro_rules! macro_subgroup_ballot_bit_count { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotBitCount")] #[inline] - pub fn $name(subgroup_mask: SubgroupMask) -> u32 { + pub fn $name(value: 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", + "%value = OpLoad _ {value}", + "%result = OpGroupNonUniformBallotBitCount %u32 %subgroup {groupop} %value", "OpStore {result} %result", subgroup = const SUBGROUP, groupop = const ($group_op as u32), - subgroup_mask = in(reg) &subgroup_mask, + value = in(reg) &value, result = in(reg) &mut result, } } @@ -533,18 +533,18 @@ macro_subgroup_ballot_bit_count!( #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotFindLSB")] #[inline] -pub fn subgroup_ballot_find_lsb(subgroup_mask: SubgroupMask) -> u32 { +pub fn subgroup_ballot_find_lsb(value: SubgroupMask) -> u32 { let mut result = 0; unsafe { asm! { "%u32 = OpTypeInt 32 0", "%subgroup = OpConstant %u32 {subgroup}", - "%subgroup_mask = OpLoad _ {subgroup_mask}", - "%result = OpGroupNonUniformBallotFindLSB %u32 %subgroup %subgroup_mask", + "%value = OpLoad _ {value}", + "%result = OpGroupNonUniformBallotFindLSB %u32 %subgroup %value", "OpStore {result} %result", subgroup = const SUBGROUP, - subgroup_mask = in(reg) &subgroup_mask, + value = in(reg) &value, result = in(reg) &mut result, } } @@ -566,18 +566,18 @@ pub fn subgroup_ballot_find_lsb(subgroup_mask: SubgroupMask) -> u32 { #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotFindMSB")] #[inline] -pub fn subgroup_ballot_find_msb(subgroup_mask: SubgroupMask) -> u32 { +pub fn subgroup_ballot_find_msb(value: SubgroupMask) -> u32 { let mut result = 0; unsafe { asm! { "%u32 = OpTypeInt 32 0", "%subgroup = OpConstant %u32 {subgroup}", - "%subgroup_mask = OpLoad _ {subgroup_mask}", - "%result = OpGroupNonUniformBallotFindMSB %u32 %subgroup %subgroup_mask", + "%value = OpLoad _ {value}", + "%result = OpGroupNonUniformBallotFindMSB %u32 %subgroup %value", "OpStore {result} %result", subgroup = const SUBGROUP, - subgroup_mask = in(reg) &subgroup_mask, + value = in(reg) &value, result = in(reg) &mut result, } } @@ -1277,7 +1277,7 @@ Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformQuadBroadcast")] #[inline] -pub unsafe fn subgroup_quad_broadcast(value: T, id: u32) -> T { +pub unsafe fn subgroup_quad_broadcast(value: T, index: u32) -> T { let mut result = T::default(); unsafe { @@ -1285,12 +1285,12 @@ pub unsafe fn subgroup_quad_broadcast(value: T, id: u32) -> T "%u32 = OpTypeInt 32 0", "%subgroup = OpConstant %u32 {subgroup}", "%value = OpLoad _ {value}", - "%id = OpLoad _ {id}", - "%result = OpGroupNonUniformQuadBroadcast _ %subgroup %value %id", + "%index = OpLoad _ {index}", + "%result = OpGroupNonUniformQuadBroadcast _ %subgroup %value %index", "OpStore {result} %result", subgroup = const SUBGROUP, value = in(reg) &value, - id = in(reg) &id, + index = in(reg) &index, result = in(reg) &mut result, } } From 8924aa05ce896078de8d7089fd989149f195d2d7 Mon Sep 17 00:00:00 2001 From: Firestar99 Date: Mon, 30 Jun 2025 11:32:13 +0200 Subject: [PATCH 07/12] docs: put arg references within markdown code blocks --- crates/spirv-std/src/arch/subgroup.rs | 254 +++++++++++++------------- 1 file changed, 122 insertions(+), 132 deletions(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index a2e800cc00..fba2c5ce74 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -54,9 +54,7 @@ pub enum GroupOperation { PartitionedExclusiveScanNV = 8, } -/// Only usable if the extension GL_KHR_shader_subgroup_basic is enabled. -/// -/// The function subgroupBarrier() enforces that all active invocations within a +/// The function `subgroupBarrier()` enforces that all active invocations within a /// subgroup must execute this function before any are allowed to continue their /// execution, and the results of any memory stores performed using coherent /// variables performed prior to the call will be visible to any future @@ -82,9 +80,7 @@ pub fn subgroup_barrier() { } } -/// Only usable if the extension GL_KHR_shader_subgroup_basic is enabled. -/// -/// The function subgroupMemoryBarrier() enforces the ordering of all memory +/// The function `subgroupMemoryBarrier()` enforces the ordering of all memory /// transactions issued within a single shader invocation, as viewed by other /// invocations in the same subgroup. /// @@ -106,9 +102,7 @@ pub fn subgroup_memory_barrier() { } } -/// Only usable if the extension GL_KHR_shader_subgroup_basic is enabled. -/// -/// The function subgroupMemoryBarrierBuffer() enforces the ordering of all +/// The function `subgroupMemoryBarrierBuffer()` enforces the ordering of all /// memory transactions to buffer variables issued within a single shader /// invocation, as viewed by other invocations in the same subgroup. /// @@ -125,9 +119,7 @@ pub fn subgroup_memory_barrier_buffer() { } } -/// Only usable if the extension GL_KHR_shader_subgroup_basic is enabled. -/// -/// The function subgroupMemoryBarrierShared() enforces the ordering of all +/// The function `subgroupMemoryBarrierShared()` enforces the ordering of all /// memory transactions to shared variables issued within a single shader /// invocation, as viewed by other invocations in the same subgroup. /// @@ -146,9 +138,7 @@ pub fn subgroup_memory_barrier_shared() { } } -/// Only usable if the extension GL_KHR_shader_subgroup_basic is enabled. -/// -/// The function subgroupMemoryBarrierImage() enforces the ordering of all +/// The function `subgroupMemoryBarrierImage()` enforces the ordering of all /// memory transactions to images issued within a single shader invocation, as /// viewed by other invocations in the same subgroup. /// @@ -193,13 +183,13 @@ pub fn subgroup_elect() -> bool { result } -/// Evaluates a predicate for all active invocations in the group, resulting in true if predicate evaluates to true for all active invocations in the group, otherwise the result is false. +/// Evaluates a `predicate` for all active invocations in the group, resulting in true if `predicate` evaluates to true for all active invocations in the group, otherwise the result is false. /// /// Result Type must be a Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// Predicate must be a Boolean type. +/// `predicate` must be a Boolean type. /// /// Requires Capability `GroupNonUniformVote`. #[spirv_std_macros::gpu_only] @@ -225,13 +215,13 @@ pub fn subgroup_all(predicate: bool) -> bool { result } -/// Evaluates a predicate for all active invocations in the group, resulting in true if predicate evaluates to true for any active invocation in the group, otherwise the result is false. +/// Evaluates a `predicate` for all active invocations in the group, resulting in true if `predicate` evaluates to true for any active invocation in the group, otherwise the result is false. /// /// Result Type must be a Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// Predicate must be a Boolean type. +/// `predicate` must be a Boolean type. /// /// Requires Capability `GroupNonUniformVote`. #[spirv_std_macros::gpu_only] @@ -257,13 +247,13 @@ pub fn subgroup_any(predicate: bool) -> bool { result } -/// Evaluates a value for all active invocations in the group. The result is true if Value is equal for all active invocations in the group. Otherwise, the result is false. +/// Evaluates a `value` for all active invocations in the group. The result is true if `value` is equal for all active invocations in the group. Otherwise, the result is false. /// /// Result Type must be a Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// Value must be a scalar or vector of floating-point type, integer type, or Boolean type. The compare operation is based on this type, and if it is a floating-point type, an ordered-and-equal compare is used. +/// `value` must be a scalar or vector of floating-point type, integer type, or Boolean type. The compare operation is based on this type, and if it is a floating-point type, an ordered-and-equal compare is used. /// /// Requires Capability `GroupNonUniformVote`. #[spirv_std_macros::gpu_only] @@ -289,19 +279,19 @@ pub fn subgroup_all_equal(value: T) -> bool { result } -/// Result is the Value of the invocation identified by the id Id to all active invocations in the group. +/// Result is the `value` of the invocation identified by the id `id` to all active invocations in the group. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// -/// Id must be a scalar of integer type, whose Signedness operand is 0. +/// `id` must be a scalar of integer type, whose Signedness operand is 0. /// -/// Before version 1.5, Id must come from a constant instruction. Starting with version 1.5, this restriction is lifted. However, behavior is undefined when Id is not dynamically uniform. +/// Before version 1.5, `id` must come from a constant instruction. Starting with version 1.5, this restriction is lifted. However, behavior is undefined when `id` is not dynamically uniform. /// -/// The resulting value is undefined if Id is an inactive invocation, or is greater than or equal to the size of the group. +/// The resulting value is undefined if `id` is an inactive invocation, or is greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformBallot`. #[spirv_std_macros::gpu_only] @@ -328,13 +318,13 @@ pub unsafe fn subgroup_broadcast(value: T, id: u32) -> T { result } -/// Result is the Value of the invocation from the active invocation with the lowest id in the group to all active invocations in the group. +/// Result is the `value` of the invocation from the active invocation with the lowest id in the group to all active invocations in the group. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// /// Requires Capability `GroupNonUniformBallot`. #[spirv_std_macros::gpu_only] @@ -359,7 +349,7 @@ pub fn subgroup_broadcast_first(value: T) -> T { result } -/// Result is a bitfield value combining the Predicate value from all invocations in the group that execute the same dynamic instance of this instruction. The bit is set to one if the corresponding invocation is active and the Predicate for that invocation evaluated to true; otherwise, it is set to zero. +/// Result is a bitfield value combining the `predicate` value from all invocations in the group that execute the same dynamic instance of this instruction. The bit is set to one if the corresponding invocation is active and the `predicate` for that invocation evaluated to true; otherwise, it is set to zero. /// /// Result Type must be a vector of four components of integer type scalar, whose Width operand is 32 and whose Signedness operand is 0. /// @@ -367,7 +357,7 @@ pub fn subgroup_broadcast_first(value: T) -> T { /// /// Execution is a Scope that identifies the group of invocations affected by this command. /// -/// Predicate must be a Boolean type. +/// `predicate` must be a Boolean type. /// /// Requires Capability `GroupNonUniformBallot`. #[spirv_std_macros::gpu_only] @@ -393,17 +383,17 @@ pub fn subgroup_ballot(predicate: bool) -> SubgroupMask { result } -/// Evaluates a value for all active invocations in the group, resulting in true if the bit in Value for the corresponding invocation is set to one, otherwise the result is false. +/// Evaluates a `value` for all active invocations in the group, resulting in true if the bit in `value` for the corresponding invocation is set to one, otherwise the result is false. /// /// Result Type must be a Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// Value must be a vector of four components of integer type scalar, whose Width operand is 32 and whose Signedness operand 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. /// -/// Behavior is undefined unless Value is the same for all invocations that execute the same dynamic instance of this instruction. +/// Behavior is undefined unless `value` is the same for all invocations that execute the same dynamic instance of this instruction. /// -/// 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. +/// `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] @@ -429,19 +419,19 @@ pub unsafe fn subgroup_inverse_ballot(value: SubgroupMask) -> bool { result } -/// Evaluates a value for all active invocations in the group, resulting in true if the bit in Value that corresponds to Index is set to one, otherwise the result is false. +/// Evaluates a value for all active invocations in the group, resulting in true if the bit in `value` that corresponds to `index` is set to one, otherwise the result is false. /// /// Result Type must be a Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// Value must be a vector of four components of integer type scalar, whose Width operand is 32 and whose Signedness operand 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. +/// `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. /// -/// Index must be a scalar of integer type, whose Signedness operand is 0. +/// `index` must be a scalar of integer type, whose Signedness operand is 0. /// -/// The resulting value is undefined if Index is greater than or equal to the size of the group. +/// The resulting value is undefined if `index` is greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformBallot`. #[spirv_std_macros::gpu_only] @@ -471,7 +461,7 @@ pub fn subgroup_ballot_bit_extract(value: SubgroupMask, index: u32) -> bool { 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 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. /// @@ -479,9 +469,9 @@ macro_rules! macro_subgroup_ballot_bit_count { /// /// 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` 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. + /// `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] @@ -519,15 +509,15 @@ macro_subgroup_ballot_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. +/// 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. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// Value must be a vector of four components of integer type scalar, whose Width operand is 32 and whose Signedness operand 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. +/// `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] @@ -552,15 +542,15 @@ pub fn subgroup_ballot_find_lsb(value: SubgroupMask) -> u32 { result } -/// Find the most 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. +/// Find the most 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. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// Value must be a vector of four components of integer type scalar, whose Width operand is 32 and whose Signedness operand 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. +/// `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] @@ -585,17 +575,17 @@ pub fn subgroup_ballot_find_msb(value: SubgroupMask) -> u32 { result } -/// Result is the Value of the invocation identified by the id Id. +/// Result is the `value` of the invocation identified by the id `id`. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// -/// Id must be a scalar of integer type, whose Signedness operand is 0. +/// `id` must be a scalar of integer type, whose Signedness operand is 0. /// -/// The resulting value is undefined if Id is an inactive invocation, or is greater than or equal to the size of the group. +/// The resulting value is undefined if `id` is an inactive invocation, or is greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformShuffle`. #[spirv_std_macros::gpu_only] @@ -622,13 +612,13 @@ pub fn subgroup_shuffle(value: T, id: u32) -> T { result } -/// Result is the Value of the invocation identified by the current invocation’s id within the group xor’ed with Mask. +/// Result is the `value` of the invocation identified by the current invocation’s id within the group xor’ed with Mask. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// /// Mask must be a scalar of integer type, whose Signedness operand is 0. /// @@ -659,13 +649,13 @@ pub fn subgroup_shuffle_xor(value: T, mask: u32) -> T { result } -/// Result is the Value of the invocation identified by the current invocation’s id within the group - Delta. +/// Result is the `value` of the invocation identified by the current invocation’s id within the group - Delta. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// /// Delta must be a scalar of integer type, whose Signedness operand is 0. /// @@ -696,13 +686,13 @@ pub fn subgroup_shuffle_up(value: T, delta: u32) -> T { result } -/// Result is the Value of the invocation identified by the current invocation’s id within the group + Delta. +/// Result is the `value` of the invocation identified by the current invocation’s id within the group + Delta. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope that identifies the group of invocations affected by this command. It must be Subgroup. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// /// Delta must be a scalar of integer type, whose Signedness operand is 0. /// @@ -795,7 +785,7 @@ macro_rules! macro_subgroup_op_clustered { // 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. +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. @@ -803,12 +793,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is 0. -The type of Value must be the same as Result Type. +The type of `value` must be the same as Result Type. 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. +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. @@ -816,14 +806,14 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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, "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. +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. @@ -831,12 +821,12 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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`. "); 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. +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. @@ -844,7 +834,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. @@ -853,7 +843,7 @@ Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. // 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. +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. @@ -861,12 +851,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is 1. -The type of Value must be the same as Result Type. +The type of `value` must be the same as Result Type. 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. +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. @@ -874,14 +864,14 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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, "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. +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. @@ -889,12 +879,12 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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`. "); 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. +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. @@ -902,7 +892,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. @@ -911,7 +901,7 @@ Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. // 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. +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. @@ -919,12 +909,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is INT_MAX. -The type of Value must be the same as Result Type. +The type of `value` must be the same as Result Type. 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. +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. @@ -932,14 +922,14 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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, "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. +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. @@ -947,12 +937,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is UINT_MAX. -The type of Value must be the same as Result Type. +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. +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. @@ -960,14 +950,14 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. +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. @@ -975,12 +965,12 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. +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. @@ -988,7 +978,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. @@ -997,7 +987,7 @@ 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. +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. @@ -1005,12 +995,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is INT_MIN. -The type of Value must be the same as Result Type. +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. +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. @@ -1018,14 +1008,14 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. +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. @@ -1033,12 +1023,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is 0. -The type of Value must be the same as Result Type. +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. +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. @@ -1046,14 +1036,14 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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. +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. @@ -1061,12 +1051,12 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. +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. @@ -1074,14 +1064,14 @@ Execution is a Scope that identifies the group of invocations affected by this c 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. +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. +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. @@ -1089,12 +1079,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is ~0. -The type of Value must be the same as Result Type. +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. +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. @@ -1102,7 +1092,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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. @@ -1111,7 +1101,7 @@ 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. +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. @@ -1119,12 +1109,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is 0. -The type of Value must be the same as Result Type. +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. +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. @@ -1132,7 +1122,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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. @@ -1141,7 +1131,7 @@ 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. +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. @@ -1149,12 +1139,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is 0. -The type of Value must be the same as Result Type. +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. +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. @@ -1162,7 +1152,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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. @@ -1171,7 +1161,7 @@ Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. // 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. +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. @@ -1179,12 +1169,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is ~0. -The type of Value must be the same as Result Type. +The type of `value` must be the same as Result Type. 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 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. @@ -1192,7 +1182,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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. @@ -1201,7 +1191,7 @@ Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. // 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. +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. @@ -1209,12 +1199,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is 0. -The type of Value must be the same as Result Type. +The type of `value` must be the same as Result Type. 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. @@ -1222,7 +1212,7 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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. @@ -1231,7 +1221,7 @@ Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. // 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. +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. @@ -1239,12 +1229,12 @@ Execution is a Scope that identifies the group of invocations affected by this c The identity I for Operation is 0. -The type of Value must be the same as Result Type. +The type of `value` must be the same as Result Type. 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. +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. @@ -1252,26 +1242,26 @@ Execution is a Scope that identifies the group of invocations affected by this c 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 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. +/// Result is the `value` of the invocation within the quad with a quad index equal to `index`. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope, but has no effect on the behavior of this instruction. It must be Subgroup. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// -/// Index must be a scalar of integer type, whose Signedness operand is 0. +/// `index` must be a scalar of integer type, whose Signedness operand is 0. /// -/// Before version 1.5, Index must come from a constant instruction. Starting with version 1.5, Index must be dynamically uniform. +/// Before version 1.5, `index` must come from a constant instruction. Starting with version 1.5, `index` must be dynamically uniform. /// -/// If the value of Index is greater than or equal to 4, or refers to an inactive invocation, the resulting value is undefined. +/// If the value of `index` is greater than or equal to 4, or refers to an inactive invocation, the resulting value is undefined. /// /// Requires Capability `GroupNonUniformQuad`. #[spirv_std_macros::gpu_only] @@ -1304,7 +1294,7 @@ pub unsafe fn subgroup_quad_broadcast(value: T, index: u32) - /// /// Direction must come from a constant instruction. /// -/// The value returned in Result is the value provided to Value by another invocation in the same quad scope instance. The invocation providing this value is determined according to Direction. +/// The value returned in Result is the value provided to `value` by another invocation in the same quad scope instance. The invocation providing this `value` is determined according to Direction. /// /// Requires Capability `GroupNonUniformQuad`. pub enum QuadDirection { @@ -1322,13 +1312,13 @@ pub enum QuadDirection { Diagonal = 2, } -/// Swap the Value of the invocation within the quad with another invocation in the quad using Direction. +/// Swap the `value` of the invocation within the quad with another invocation in the quad using Direction. /// /// Result Type must be a scalar or vector of floating-point type, integer type, or Boolean type. /// /// Execution is a Scope, but has no effect on the behavior of this instruction. It must be Subgroup. /// -/// The type of Value must be the same as Result Type. +/// The type of `value` must be the same as Result Type. /// /// Direction is the kind of swap to perform. /// @@ -1336,7 +1326,7 @@ pub enum QuadDirection { /// /// Direction must come from a constant instruction. /// -/// The value returned in Result is the value provided to Value by another invocation in the same quad scope instance. The invocation providing this value is determined according to Direction. +/// The value returned in Result is the value provided to `value` by another invocation in the same quad scope instance. The invocation providing this `value` is determined according to Direction. /// /// A Direction of 0 indicates a horizontal swap; /// - Invocations with quad indices of 0 and 1 swap values @@ -1350,7 +1340,7 @@ pub enum QuadDirection { /// /// Direction must be one of the above values. /// -/// If an active invocation reads Value from an inactive invocation, the resulting value is undefined. +/// If an active invocation reads `value` from an inactive invocation, the resulting value is undefined. /// /// Requires Capability `GroupNonUniformQuad`. #[spirv_std_macros::gpu_only] From db5b5b84708c0c3db8e01c40f1ebde91b65b76b6 Mon Sep 17 00:00:00 2001 From: Firestar99 Date: Mon, 30 Jun 2025 11:33:16 +0200 Subject: [PATCH 08/12] add safety docs, make `subgroup_quad_broadcast` safe --- crates/spirv-std/src/arch/subgroup.rs | 42 ++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index fba2c5ce74..dcaf9a3dab 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -294,6 +294,11 @@ pub fn subgroup_all_equal(value: T) -> bool { /// The resulting value is undefined if `id` is an inactive invocation, or is greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformBallot`. +/// +/// # Safety +/// * `id` must not be dynamically uniform +/// * before 1.5: `id` must be constant +/// * Result is undefined if `id` is an inactive invocation or out of bounds #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBroadcast")] #[inline] @@ -396,6 +401,9 @@ pub fn subgroup_ballot(predicate: bool) -> SubgroupMask { /// `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`. +/// +/// # Safety +/// * `value` must be the same for all dynamic instances of this instruction #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformInverseBallot")] #[inline] @@ -434,6 +442,10 @@ pub unsafe fn subgroup_inverse_ballot(value: SubgroupMask) -> bool { /// The resulting value is undefined if `index` is greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformBallot`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if `id` is out of bounds #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotBitExtract")] #[inline] @@ -520,6 +532,10 @@ macro_subgroup_ballot_bit_count!( /// `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`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if `id` is an inactive invocation or out of bounds #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformBallotFindLSB")] #[inline] @@ -588,6 +604,10 @@ pub fn subgroup_ballot_find_msb(value: SubgroupMask) -> u32 { /// The resulting value is undefined if `id` is an inactive invocation, or is greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformShuffle`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if `id` is an inactive invocation or out of bounds #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffle")] #[inline] @@ -625,6 +645,10 @@ pub fn subgroup_shuffle(value: T, id: u32) -> T { /// The resulting value is undefined if current invocation’s id within the group xor’ed with Mask is an inactive invocation, or is greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformShuffle`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if current invocation’s id within the group xor’ed with `mask` is an inactive invocation or out of bounds #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffleXor")] #[inline] @@ -662,6 +686,10 @@ pub fn subgroup_shuffle_xor(value: T, mask: u32) -> T { /// Delta is treated as unsigned and the resulting value is undefined if Delta is greater than the current invocation’s id within the group or if the selected lane is inactive. /// /// Requires Capability `GroupNonUniformShuffleRelative`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if `delta` is greater than the current invocation’s id within the group or if the selected lane is inactive #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffleUp")] #[inline] @@ -699,6 +727,10 @@ pub fn subgroup_shuffle_up(value: T, delta: u32) -> T { /// Delta is treated as unsigned and the resulting value is undefined if Delta is greater than or equal to the size of the group, or if the current invocation’s id within the group + Delta is either an inactive invocation or greater than or equal to the size of the group. /// /// Requires Capability `GroupNonUniformShuffleRelative`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if `delta` is greater than or equal to the size of the group, or if the current invocation’s id within the group + `delta` is either an inactive invocation or greater than or equal to the size of the group. #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformShuffleDown")] #[inline] @@ -1264,10 +1296,14 @@ Requires Capability `GroupNonUniformArithmetic` and `GroupNonUniformClustered`. /// If the value of `index` is greater than or equal to 4, or refers to an inactive invocation, the resulting value is undefined. /// /// Requires Capability `GroupNonUniformQuad`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if the value of `index` is greater than or equal to 4, or refers to an inactive invocation #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformQuadBroadcast")] #[inline] -pub unsafe fn subgroup_quad_broadcast(value: T, index: u32) -> T { +pub fn subgroup_quad_broadcast(value: T, index: u32) -> T { let mut result = T::default(); unsafe { @@ -1343,6 +1379,10 @@ pub enum QuadDirection { /// If an active invocation reads `value` from an inactive invocation, the resulting value is undefined. /// /// Requires Capability `GroupNonUniformQuad`. +/// +/// # Safety +/// * This function is safe +/// * Result is undefined if an active invocation reads `value` from an inactive invocation #[spirv_std_macros::gpu_only] #[doc(alias = "OpGroupNonUniformQuadSwap")] #[inline] From 1590c7097a0026092be560369db6cd2d2e9984f1 Mon Sep 17 00:00:00 2001 From: Firestar99 Date: Mon, 30 Jun 2025 11:50:01 +0200 Subject: [PATCH 09/12] bless compiletests --- tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr | 4 ++-- .../ui/arch/subgroup/subgroup_ballot_bit_count.stderr | 2 +- .../ui/arch/subgroup/subgroup_broadcast_first.stderr | 2 +- tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr | 2 +- .../ui/arch/subgroup/subgroup_i_add_clustered.stderr | 2 +- .../ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr | 2 +- .../ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr | 2 +- .../ui/arch/subgroup/subgroup_i_add_reduce.stderr | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr index 2d7b71e12c..eb775c3cfd 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr @@ -1,9 +1,9 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 380 8 +OpLine %6 375 8 %7 = OpGroupNonUniformBallot %8 %9 %4 -OpLine %6 416 8 +OpLine %6 414 8 %10 = OpGroupNonUniformInverseBallot %2 %9 %7 OpNoLine OpReturnValue %10 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr index 49ff494bc1..9ba359f7b6 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %5 %6 = OpLabel -OpLine %7 512 0 +OpLine %7 514 0 %8 = OpGroupNonUniformBallotBitCount %2 %9 Reduce %4 OpNoLine OpReturnValue %8 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr index 6836a0fd14..8656702259 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 347 8 +OpLine %6 342 8 %7 = OpGroupNonUniformBroadcastFirst %2 %8 %4 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr index 0cbeb7590b..4a4dc37f55 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 182 8 +OpLine %5 172 8 %6 = OpGroupNonUniformElect %2 %7 OpNoLine OpReturnValue %6 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr index d88cfd3296..c6193ac21a 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 810 0 +OpLine %6 832 0 %7 = OpGroupNonUniformIAdd %2 %8 ClusteredReduce %4 %9 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr index ca83820bf0..1d7eae31bb 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr +++ b/tests/compiletests/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 797 0 +OpLine %6 819 0 %7 = OpGroupNonUniformIAdd %2 %8 ExclusiveScan %4 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr index 93048426c1..19ec4ce9a9 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr +++ b/tests/compiletests/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 797 0 +OpLine %6 819 0 %7 = OpGroupNonUniformIAdd %2 %8 InclusiveScan %4 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr index f382189af7..66be372cf5 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 797 0 +OpLine %6 819 0 %7 = OpGroupNonUniformIAdd %2 %8 Reduce %4 OpNoLine OpReturnValue %7 From 2811c217d32ab88736012c75e8c4b030311c7da6 Mon Sep 17 00:00:00 2001 From: Firestar99 Date: Mon, 30 Jun 2025 12:01:42 +0200 Subject: [PATCH 10/12] subgroup cluster ops: add safety docs, const assert preconditions --- crates/spirv-std/src/arch/subgroup.rs | 60 ++++++++++++++++++- .../ui/arch/subgroup/subgroup_ballot.stderr | 4 +- .../subgroup/subgroup_ballot_bit_count.stderr | 2 +- .../subgroup/subgroup_broadcast_first.stderr | 2 +- .../subgroup/subgroup_cluster_size_0_fail.rs | 17 ++++++ .../subgroup_cluster_size_0_fail.stderr | 37 ++++++++++++ ...roup_cluster_size_non_power_of_two_fail.rs | 17 ++++++ ..._cluster_size_non_power_of_two_fail.stderr | 37 ++++++++++++ .../ui/arch/subgroup/subgroup_elect.stderr | 2 +- .../subgroup/subgroup_i_add_clustered.stderr | 2 +- .../subgroup_i_add_exclusive_scan.stderr | 2 +- .../subgroup_i_add_inclusive_scan.stderr | 2 +- .../subgroup/subgroup_i_add_reduce.stderr | 2 +- 13 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs create mode 100644 tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr create mode 100644 tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs create mode 100644 tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index dcaf9a3dab..5e45388f58 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -1,5 +1,3 @@ -#![allow(clippy::missing_safety_doc)] - #[cfg(target_arch = "spirv")] use crate::arch::barrier; use crate::float::Float; @@ -792,6 +790,16 @@ macro_rules! macro_subgroup_op_clustered { pub unsafe fn $name>( value: I, ) -> I { + const { + assert!(CLUSTER_SIZE >= 1, "`ClusterSize` must be at least 1"); + assert!( + CLUSTER_SIZE.is_power_of_two(), + "`ClusterSize` must be a power of 2" + ); + // Cannot be verified with static assertions: + // `ClusterSize` must not be greater than the size of the group + } + let mut result = I::default(); unsafe { @@ -843,6 +851,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); 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. @@ -871,6 +882,9 @@ The type of `value` must be the same as Result Type. The method used to perform 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // mul @@ -901,6 +915,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); 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. @@ -929,6 +946,9 @@ The type of `value` must be the same as Result Type. The method used to perform 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // min @@ -959,6 +979,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); 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. @@ -987,6 +1010,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); 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. @@ -1015,6 +1041,9 @@ The type of `value` must be the same as Result Type. The method used to perform 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // max @@ -1045,6 +1074,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); 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. @@ -1073,6 +1105,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); 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. @@ -1099,6 +1134,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // and @@ -1129,6 +1167,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // or @@ -1159,6 +1200,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // xor @@ -1189,6 +1233,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // logical and @@ -1219,6 +1266,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // logical or @@ -1249,6 +1299,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); // logical xor @@ -1279,6 +1332,9 @@ 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`. + +# Safety +* `ClusterSize` must not be greater than the size of the group "); /// Result is the `value` of the invocation within the quad with a quad index equal to `index`. diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr index eb775c3cfd..9ce9546076 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr @@ -1,9 +1,9 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 375 8 +OpLine %6 373 8 %7 = OpGroupNonUniformBallot %8 %9 %4 -OpLine %6 414 8 +OpLine %6 412 8 %10 = OpGroupNonUniformInverseBallot %2 %9 %7 OpNoLine OpReturnValue %10 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr index 9ba359f7b6..49ff494bc1 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %5 %6 = OpLabel -OpLine %7 514 0 +OpLine %7 512 0 %8 = OpGroupNonUniformBallotBitCount %2 %9 Reduce %4 OpNoLine OpReturnValue %8 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr index 8656702259..a6ffcdb8a4 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 342 8 +OpLine %6 340 8 %7 = OpGroupNonUniformBroadcastFirst %2 %8 %4 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs new file mode 100644 index 0000000000..8fb68032c6 --- /dev/null +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs @@ -0,0 +1,17 @@ +// build-pass +// compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+GroupNonUniformClustered,+ext:SPV_KHR_vulkan_memory_model + +use glam::UVec3; +use spirv_std::arch::{GroupOperation, SubgroupMask}; +use spirv_std::spirv; + +unsafe fn subgroup_test_fail(value: u32) -> u32 { + spirv_std::arch::subgroup_clustered_i_add::<0, _>(value) +} + +#[spirv(compute(threads(32, 1, 1)))] +pub fn main(#[spirv(local_invocation_id)] local_invocation_id: UVec3) { + unsafe { + subgroup_test_fail(local_invocation_id.x); + } +} diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr new file mode 100644 index 0000000000..b4492e0555 --- /dev/null +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr @@ -0,0 +1,37 @@ +error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<0, u32, u32>::{constant#0}` failed + --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | +840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" +841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. +842 | | +843 | | Result Type must be a scalar or vector of integer type. +... | +856 | | * `ClusterSize` must not be greater than the size of the group +857 | | "); + | |__^ the evaluated program panicked at '`ClusterSize` must be at least 1', /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | + = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | +840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" +841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. +842 | | +843 | | Result Type must be a scalar or vector of integer type. +... | +856 | | * `ClusterSize` must not be greater than the size of the group +857 | | "); + | |__^ + | + = note: this note originates in the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn spirv_std::arch::subgroup_clustered_i_add::<0, u32, u32>` + --> $DIR/subgroup_cluster_size_0_fail.rs:9:5 + | +9 | spirv_std::arch::subgroup_clustered_i_add::<0, _>(value) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs new file mode 100644 index 0000000000..a0fa70081f --- /dev/null +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs @@ -0,0 +1,17 @@ +// build-pass +// compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+GroupNonUniformClustered,+ext:SPV_KHR_vulkan_memory_model + +use glam::UVec3; +use spirv_std::arch::{GroupOperation, SubgroupMask}; +use spirv_std::spirv; + +unsafe fn subgroup_test_fail(value: u32) -> u32 { + spirv_std::arch::subgroup_clustered_i_add::<5, _>(value) +} + +#[spirv(compute(threads(32, 1, 1)))] +pub fn main(#[spirv(local_invocation_id)] local_invocation_id: UVec3) { + unsafe { + subgroup_test_fail(local_invocation_id.x); + } +} diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr new file mode 100644 index 0000000000..d65753396e --- /dev/null +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr @@ -0,0 +1,37 @@ +error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<5, u32, u32>::{constant#0}` failed + --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | +840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" +841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. +842 | | +843 | | Result Type must be a scalar or vector of integer type. +... | +856 | | * `ClusterSize` must not be greater than the size of the group +857 | | "); + | |__^ the evaluated program panicked at '`ClusterSize` must be a power of 2', /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | + = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | +840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" +841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. +842 | | +843 | | Result Type must be a scalar or vector of integer type. +... | +856 | | * `ClusterSize` must not be greater than the size of the group +857 | | "); + | |__^ + | + = note: this note originates in the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn spirv_std::arch::subgroup_clustered_i_add::<5, u32, u32>` + --> $DIR/subgroup_cluster_size_non_power_of_two_fail.rs:9:5 + | +9 | spirv_std::arch::subgroup_clustered_i_add::<5, _>(value) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr index 4a4dc37f55..4bfef562f7 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 172 8 +OpLine %5 170 8 %6 = OpGroupNonUniformElect %2 %7 OpNoLine OpReturnValue %6 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr index c6193ac21a..710c976877 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 832 0 +OpLine %6 840 0 %7 = OpGroupNonUniformIAdd %2 %8 ClusteredReduce %4 %9 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr index 1d7eae31bb..da708505b8 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr +++ b/tests/compiletests/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 819 0 +OpLine %6 827 0 %7 = OpGroupNonUniformIAdd %2 %8 ExclusiveScan %4 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr index 19ec4ce9a9..684d46dec0 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr +++ b/tests/compiletests/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 819 0 +OpLine %6 827 0 %7 = OpGroupNonUniformIAdd %2 %8 InclusiveScan %4 OpNoLine OpReturnValue %7 diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr index 66be372cf5..9430d3452d 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr @@ -1,7 +1,7 @@ %1 = OpFunction %2 None %3 %4 = OpFunctionParameter %2 %5 = OpLabel -OpLine %6 819 0 +OpLine %6 827 0 %7 = OpGroupNonUniformIAdd %2 %8 Reduce %4 OpNoLine OpReturnValue %7 From 79b6baba171d40e4befa846c8dd1c9b1a3277db1 Mon Sep 17 00:00:00 2001 From: Firestar99 Date: Mon, 30 Jun 2025 12:04:18 +0200 Subject: [PATCH 11/12] subgroup cluster ops: put `ClusterSize` in markdown codeblock --- crates/spirv-std/src/arch/subgroup.rs | 60 +++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/crates/spirv-std/src/arch/subgroup.rs b/crates/spirv-std/src/arch/subgroup.rs index 5e45388f58..660c9ee5f3 100644 --- a/crates/spirv-std/src/arch/subgroup.rs +++ b/crates/spirv-std/src/arch/subgroup.rs @@ -844,11 +844,11 @@ 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 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. +`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`. @@ -875,11 +875,11 @@ 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 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. +`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`. @@ -908,11 +908,11 @@ 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 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. +`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`. @@ -939,11 +939,11 @@ 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 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. +`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`. @@ -972,11 +972,11 @@ 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 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. +`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`. @@ -1003,11 +1003,11 @@ Result Type must be a scalar or vector of integer type, whose Signedness operand 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 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. +`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`. @@ -1034,11 +1034,11 @@ 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 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. +`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`. @@ -1067,11 +1067,11 @@ 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 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. +`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`. @@ -1098,11 +1098,11 @@ Result Type must be a scalar or vector of integer type, whose Signedness operand 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 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. +`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`. @@ -1160,11 +1160,11 @@ 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 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. +`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`. @@ -1193,11 +1193,11 @@ 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 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. +`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`. @@ -1226,11 +1226,11 @@ 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 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. +`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`. @@ -1259,11 +1259,11 @@ 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 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. +`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`. @@ -1292,11 +1292,11 @@ 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 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. +`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`. @@ -1325,11 +1325,11 @@ 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 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. +`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`. From 88eb6e3b2cfb30188aa9164d529738eddeaa77dd Mon Sep 17 00:00:00 2001 From: Firestar99 Date: Mon, 30 Jun 2025 12:24:19 +0200 Subject: [PATCH 12/12] normalise spirv-std path --- .../arch/subgroup/subgroup_cluster_size_0_fail.rs | 1 + .../subgroup/subgroup_cluster_size_0_fail.stderr | 14 +++++++------- .../subgroup_cluster_size_non_power_of_two_fail.rs | 1 + ...group_cluster_size_non_power_of_two_fail.stderr | 14 +++++++------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs index 8fb68032c6..4fec2a3db5 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.rs @@ -1,5 +1,6 @@ // build-pass // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+GroupNonUniformClustered,+ext:SPV_KHR_vulkan_memory_model +// normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" use glam::UVec3; use spirv_std::arch::{GroupOperation, SubgroupMask}; diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr index b4492e0555..db4905f35d 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<0, u32, u32>::{constant#0}` failed - --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + --> $SPIRV_STD_SRC/arch/subgroup.rs:840:1 | 840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" 841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. @@ -8,12 +8,12 @@ error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<0, u32, ... | 856 | | * `ClusterSize` must not be greater than the size of the group 857 | | "); - | |__^ the evaluated program panicked at '`ClusterSize` must be at least 1', /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | |__^ the evaluated program panicked at '`ClusterSize` must be at least 1', $SPIRV_STD_SRC/arch/subgroup.rs:840:1 | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + --> $SPIRV_STD_SRC/arch/subgroup.rs:840:1 | 840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" 841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. @@ -27,10 +27,10 @@ note: erroneous constant encountered = note: this note originates in the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn spirv_std::arch::subgroup_clustered_i_add::<0, u32, u32>` - --> $DIR/subgroup_cluster_size_0_fail.rs:9:5 - | -9 | spirv_std::arch::subgroup_clustered_i_add::<0, _>(value) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $DIR/subgroup_cluster_size_0_fail.rs:10:5 + | +10 | spirv_std::arch::subgroup_clustered_i_add::<0, _>(value) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs index a0fa70081f..9184cc25b1 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.rs @@ -1,5 +1,6 @@ // build-pass // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+GroupNonUniformClustered,+ext:SPV_KHR_vulkan_memory_model +// normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" use glam::UVec3; use spirv_std::arch::{GroupOperation, SubgroupMask}; diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr index d65753396e..5442b482b9 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<5, u32, u32>::{constant#0}` failed - --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + --> $SPIRV_STD_SRC/arch/subgroup.rs:840:1 | 840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" 841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. @@ -8,12 +8,12 @@ error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<5, u32, ... | 856 | | * `ClusterSize` must not be greater than the size of the group 857 | | "); - | |__^ the evaluated program panicked at '`ClusterSize` must be a power of 2', /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + | |__^ the evaluated program panicked at '`ClusterSize` must be a power of 2', $SPIRV_STD_SRC/arch/subgroup.rs:840:1 | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> /home/firestar99/workspace/frameworks/rust-gpu/crates/spirv-std/src/arch/subgroup.rs:840:1 + --> $SPIRV_STD_SRC/arch/subgroup.rs:840:1 | 840 | / macro_subgroup_op_clustered!(impl Integer, "OpGroupNonUniformIAdd", subgroup_clustered_i_add; r" 841 | | An integer add group operation of all `value` operands contributed by active invocations in the group. @@ -27,10 +27,10 @@ note: erroneous constant encountered = note: this note originates in the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) note: the above error was encountered while instantiating `fn spirv_std::arch::subgroup_clustered_i_add::<5, u32, u32>` - --> $DIR/subgroup_cluster_size_non_power_of_two_fail.rs:9:5 - | -9 | spirv_std::arch::subgroup_clustered_i_add::<5, _>(value) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $DIR/subgroup_cluster_size_non_power_of_two_fail.rs:10:5 + | +10 | spirv_std::arch::subgroup_clustered_i_add::<5, _>(value) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error