Skip to content

Commit 4831789

Browse files
added memory barrier intrinsics to spirv-std (#769)
* added memory barrier intrinsics to spirv-std * added function-level docs * added unit-tests constants could not be validated in tests because of the limited output * clippy fixes * improved documentation * Added missing features to device_memory and all_memory barrier intrinsics.
1 parent 1fbb241 commit 4831789

13 files changed

+247
-0
lines changed

crates/spirv-std/src/arch/barrier.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,114 @@ pub unsafe fn memory_barrier<
7878
semantics = const SEMANTICS,
7979
}
8080
}
81+
82+
/// Blocks execution of all threads in a group until all group shared accesses have been completed.
83+
///
84+
/// This is an exact implementation of `GroupMemoryBarrier()`.
85+
///
86+
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/groupmemorybarrier>
87+
#[spirv_std_macros::gpu_only]
88+
#[inline]
89+
pub unsafe fn workgroup_memory_barrier() {
90+
memory_barrier::<
91+
{ crate::memory::Scope::Workgroup as u32 },
92+
{
93+
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
94+
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
95+
},
96+
>();
97+
}
98+
99+
/// Blocks execution of all threads in a group until all group shared accesses have been completed and all threads in the group have reached this call.
100+
///
101+
/// This is an exact implementation of `GroupMemoryBarrierWithGroupSync()`.
102+
///
103+
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/groupmemorybarrierwithgroupsync>
104+
#[spirv_std_macros::gpu_only]
105+
#[inline]
106+
pub unsafe fn workgroup_memory_barrier_with_group_sync() {
107+
control_barrier::<
108+
{ crate::memory::Scope::Workgroup as u32 },
109+
{ crate::memory::Scope::Workgroup as u32 },
110+
{
111+
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
112+
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
113+
},
114+
>();
115+
}
116+
117+
/// Blocks execution of all threads in a group until all device memory accesses have been completed.
118+
///
119+
/// This is an exact implementation of `DeviceMemoryBarrier()`.
120+
///
121+
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/devicememorybarrier>
122+
#[spirv_std_macros::gpu_only]
123+
#[inline]
124+
pub unsafe fn device_memory_barrier() {
125+
memory_barrier::<
126+
{ crate::memory::Scope::Device as u32 },
127+
{
128+
crate::memory::Semantics::IMAGE_MEMORY.bits()
129+
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
130+
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
131+
},
132+
>();
133+
}
134+
135+
/// Blocks execution of all threads in a group until all device memory accesses have been completed and all threads in the group have reached this call.
136+
///
137+
/// This is an exact implementation of `DeviceMemoryBarrierWithGroupSync()`.
138+
///
139+
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/devicememorybarrierwithgroupsync>
140+
#[spirv_std_macros::gpu_only]
141+
#[inline]
142+
pub unsafe fn device_memory_barrier_with_group_sync() {
143+
control_barrier::<
144+
{ crate::memory::Scope::Workgroup as u32 },
145+
{ crate::memory::Scope::Device as u32 },
146+
{
147+
crate::memory::Semantics::IMAGE_MEMORY.bits()
148+
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
149+
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
150+
},
151+
>();
152+
}
153+
154+
/// Blocks execution of all threads in a group until all memory accesses have been completed.
155+
///
156+
/// This is an exact implementation of `AllMemoryBarrier()`.
157+
///
158+
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/allmemorybarrier>
159+
#[spirv_std_macros::gpu_only]
160+
#[inline]
161+
pub unsafe fn all_memory_barrier() {
162+
memory_barrier::<
163+
{ crate::memory::Scope::Device as u32 },
164+
{
165+
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
166+
| crate::memory::Semantics::IMAGE_MEMORY.bits()
167+
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
168+
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
169+
},
170+
>();
171+
}
172+
173+
/// Blocks execution of all threads in a group until all memory accesses have been completed and all threads in the group have reached this call.
174+
///
175+
/// This is an exact implementation of `AllMemoryBarrierWithGroupSync()`.
176+
///
177+
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/allmemorybarrierwithgroupsync>
178+
#[spirv_std_macros::gpu_only]
179+
#[inline]
180+
pub unsafe fn all_memory_barrier_with_group_sync() {
181+
control_barrier::<
182+
{ crate::memory::Scope::Workgroup as u32 },
183+
{ crate::memory::Scope::Device as u32 },
184+
{
185+
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
186+
| crate::memory::Semantics::IMAGE_MEMORY.bits()
187+
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
188+
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
189+
},
190+
>();
191+
}

tests/ui/arch/all_memory_barrier.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// build-pass
2+
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
3+
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier::all_memory_barrier
4+
5+
use spirv_std as _;
6+
7+
unsafe fn all_memory_barrier() {
8+
spirv_std::arch::all_memory_barrier();
9+
}
10+
11+
#[spirv(compute(threads(1, 1, 1)))]
12+
pub fn main() {
13+
unsafe {
14+
all_memory_barrier();
15+
}
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
%1 = OpFunction %2 None %3
2+
%4 = OpLabel
3+
OpLine %5 72 4
4+
OpMemoryBarrier %6 %7
5+
OpLine %8 9 1
6+
OpReturn
7+
OpFunctionEnd
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// build-pass
2+
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
3+
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier_with_group_sync::all_memory_barrier_with_group_sync
4+
5+
use spirv_std as _;
6+
7+
unsafe fn all_memory_barrier_with_group_sync() {
8+
spirv_std::arch::all_memory_barrier_with_group_sync();
9+
}
10+
11+
#[spirv(compute(threads(1, 1, 1)))]
12+
pub fn main() {
13+
unsafe {
14+
all_memory_barrier_with_group_sync();
15+
}
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
%1 = OpFunction %2 None %3
2+
%4 = OpLabel
3+
OpLine %5 38 4
4+
OpControlBarrier %6 %7 %8
5+
OpLine %9 9 1
6+
OpReturn
7+
OpFunctionEnd
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// build-pass
2+
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
3+
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier::device_memory_barrier
4+
5+
use spirv_std as _;
6+
7+
unsafe fn device_memory_barrier() {
8+
spirv_std::arch::device_memory_barrier();
9+
}
10+
11+
#[spirv(compute(threads(1, 1, 1)))]
12+
pub fn main() {
13+
unsafe {
14+
device_memory_barrier();
15+
}
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
%1 = OpFunction %2 None %3
2+
%4 = OpLabel
3+
OpLine %5 72 4
4+
OpMemoryBarrier %6 %7
5+
OpLine %8 9 1
6+
OpReturn
7+
OpFunctionEnd
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// build-pass
2+
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
3+
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier_with_group_sync::device_memory_barrier_with_group_sync
4+
5+
use spirv_std as _;
6+
7+
unsafe fn device_memory_barrier_with_group_sync() {
8+
spirv_std::arch::device_memory_barrier_with_group_sync();
9+
}
10+
11+
#[spirv(compute(threads(1, 1, 1)))]
12+
pub fn main() {
13+
unsafe {
14+
device_memory_barrier_with_group_sync();
15+
}
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
%1 = OpFunction %2 None %3
2+
%4 = OpLabel
3+
OpLine %5 38 4
4+
OpControlBarrier %6 %7 %8
5+
OpLine %9 9 1
6+
OpReturn
7+
OpFunctionEnd
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// build-pass
2+
// compile-flags: -C llvm-args=--disassemble-fn=workgroup_memory_barrier::workgroup_memory_barrier
3+
4+
use spirv_std as _;
5+
6+
unsafe fn workgroup_memory_barrier() {
7+
spirv_std::arch::workgroup_memory_barrier();
8+
}
9+
10+
#[spirv(compute(threads(1, 1, 1)))]
11+
pub fn main() {
12+
unsafe {
13+
workgroup_memory_barrier();
14+
}
15+
}

0 commit comments

Comments
 (0)