Skip to content

Commit

Permalink
added memory barrier intrinsics to spirv-std (#769)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
hannes-vernooij authored Oct 26, 2021
1 parent 1fbb241 commit 4831789
Show file tree
Hide file tree
Showing 13 changed files with 247 additions and 0 deletions.
111 changes: 111 additions & 0 deletions crates/spirv-std/src/arch/barrier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,114 @@ pub unsafe fn memory_barrier<
semantics = const SEMANTICS,
}
}

/// Blocks execution of all threads in a group until all group shared accesses have been completed.
///
/// This is an exact implementation of `GroupMemoryBarrier()`.
///
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/groupmemorybarrier>
#[spirv_std_macros::gpu_only]
#[inline]
pub unsafe fn workgroup_memory_barrier() {
memory_barrier::<
{ crate::memory::Scope::Workgroup as u32 },
{
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
},
>();
}

/// 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.
///
/// This is an exact implementation of `GroupMemoryBarrierWithGroupSync()`.
///
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/groupmemorybarrierwithgroupsync>
#[spirv_std_macros::gpu_only]
#[inline]
pub unsafe fn workgroup_memory_barrier_with_group_sync() {
control_barrier::<
{ crate::memory::Scope::Workgroup as u32 },
{ crate::memory::Scope::Workgroup as u32 },
{
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
},
>();
}

/// Blocks execution of all threads in a group until all device memory accesses have been completed.
///
/// This is an exact implementation of `DeviceMemoryBarrier()`.
///
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/devicememorybarrier>
#[spirv_std_macros::gpu_only]
#[inline]
pub unsafe fn device_memory_barrier() {
memory_barrier::<
{ crate::memory::Scope::Device as u32 },
{
crate::memory::Semantics::IMAGE_MEMORY.bits()
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
},
>();
}

/// 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.
///
/// This is an exact implementation of `DeviceMemoryBarrierWithGroupSync()`.
///
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/devicememorybarrierwithgroupsync>
#[spirv_std_macros::gpu_only]
#[inline]
pub unsafe fn device_memory_barrier_with_group_sync() {
control_barrier::<
{ crate::memory::Scope::Workgroup as u32 },
{ crate::memory::Scope::Device as u32 },
{
crate::memory::Semantics::IMAGE_MEMORY.bits()
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
},
>();
}

/// Blocks execution of all threads in a group until all memory accesses have been completed.
///
/// This is an exact implementation of `AllMemoryBarrier()`.
///
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/allmemorybarrier>
#[spirv_std_macros::gpu_only]
#[inline]
pub unsafe fn all_memory_barrier() {
memory_barrier::<
{ crate::memory::Scope::Device as u32 },
{
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
| crate::memory::Semantics::IMAGE_MEMORY.bits()
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
},
>();
}

/// 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.
///
/// This is an exact implementation of `AllMemoryBarrierWithGroupSync()`.
///
/// From <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/allmemorybarrierwithgroupsync>
#[spirv_std_macros::gpu_only]
#[inline]
pub unsafe fn all_memory_barrier_with_group_sync() {
control_barrier::<
{ crate::memory::Scope::Workgroup as u32 },
{ crate::memory::Scope::Device as u32 },
{
crate::memory::Semantics::WORKGROUP_MEMORY.bits()
| crate::memory::Semantics::IMAGE_MEMORY.bits()
| crate::memory::Semantics::UNIFORM_MEMORY.bits()
| crate::memory::Semantics::ACQUIRE_RELEASE.bits()
},
>();
}
16 changes: 16 additions & 0 deletions tests/ui/arch/all_memory_barrier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier::all_memory_barrier

use spirv_std as _;

unsafe fn all_memory_barrier() {
spirv_std::arch::all_memory_barrier();
}

#[spirv(compute(threads(1, 1, 1)))]
pub fn main() {
unsafe {
all_memory_barrier();
}
}
7 changes: 7 additions & 0 deletions tests/ui/arch/all_memory_barrier.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 72 4
OpMemoryBarrier %6 %7
OpLine %8 9 1
OpReturn
OpFunctionEnd
16 changes: 16 additions & 0 deletions tests/ui/arch/all_memory_barrier_with_group_sync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier_with_group_sync::all_memory_barrier_with_group_sync

use spirv_std as _;

unsafe fn all_memory_barrier_with_group_sync() {
spirv_std::arch::all_memory_barrier_with_group_sync();
}

#[spirv(compute(threads(1, 1, 1)))]
pub fn main() {
unsafe {
all_memory_barrier_with_group_sync();
}
}
7 changes: 7 additions & 0 deletions tests/ui/arch/all_memory_barrier_with_group_sync.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 38 4
OpControlBarrier %6 %7 %8
OpLine %9 9 1
OpReturn
OpFunctionEnd
16 changes: 16 additions & 0 deletions tests/ui/arch/device_memory_barrier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier::device_memory_barrier

use spirv_std as _;

unsafe fn device_memory_barrier() {
spirv_std::arch::device_memory_barrier();
}

#[spirv(compute(threads(1, 1, 1)))]
pub fn main() {
unsafe {
device_memory_barrier();
}
}
7 changes: 7 additions & 0 deletions tests/ui/arch/device_memory_barrier.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 72 4
OpMemoryBarrier %6 %7
OpLine %8 9 1
OpReturn
OpFunctionEnd
16 changes: 16 additions & 0 deletions tests/ui/arch/device_memory_barrier_with_group_sync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier_with_group_sync::device_memory_barrier_with_group_sync

use spirv_std as _;

unsafe fn device_memory_barrier_with_group_sync() {
spirv_std::arch::device_memory_barrier_with_group_sync();
}

#[spirv(compute(threads(1, 1, 1)))]
pub fn main() {
unsafe {
device_memory_barrier_with_group_sync();
}
}
7 changes: 7 additions & 0 deletions tests/ui/arch/device_memory_barrier_with_group_sync.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 38 4
OpControlBarrier %6 %7 %8
OpLine %9 9 1
OpReturn
OpFunctionEnd
15 changes: 15 additions & 0 deletions tests/ui/arch/workgroup_memory_barrier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=workgroup_memory_barrier::workgroup_memory_barrier

use spirv_std as _;

unsafe fn workgroup_memory_barrier() {
spirv_std::arch::workgroup_memory_barrier();
}

#[spirv(compute(threads(1, 1, 1)))]
pub fn main() {
unsafe {
workgroup_memory_barrier();
}
}
7 changes: 7 additions & 0 deletions tests/ui/arch/workgroup_memory_barrier.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 72 4
OpMemoryBarrier %6 %7
OpLine %8 8 1
OpReturn
OpFunctionEnd
15 changes: 15 additions & 0 deletions tests/ui/arch/workgroup_memory_barrier_with_group_sync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=workgroup_memory_barrier_with_group_sync::workgroup_memory_barrier_with_group_sync

use spirv_std as _;

unsafe fn workgroup_memory_barrier_with_group_sync() {
spirv_std::arch::workgroup_memory_barrier_with_group_sync();
}

#[spirv(compute(threads(1, 1, 1)))]
pub fn main() {
unsafe {
workgroup_memory_barrier_with_group_sync();
}
}
7 changes: 7 additions & 0 deletions tests/ui/arch/workgroup_memory_barrier_with_group_sync.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 38 4
OpControlBarrier %6 %6 %7
OpLine %8 8 1
OpReturn
OpFunctionEnd

0 comments on commit 4831789

Please sign in to comment.