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.
This commit is contained in:
Hannes Vernooij 2021-10-26 09:15:50 +02:00 committed by GitHub
parent 1fbb2410b6
commit 4831789bbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 247 additions and 0 deletions

View File

@ -78,3 +78,114 @@ pub unsafe fn memory_barrier<
semantics = const SEMANTICS, 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()
},
>();
}

View File

@ -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();
}
}

View File

@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 72 4
OpMemoryBarrier %6 %7
OpLine %8 9 1
OpReturn
OpFunctionEnd

View File

@ -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();
}
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 72 4
OpMemoryBarrier %6 %7
OpLine %8 9 1
OpReturn
OpFunctionEnd

View File

@ -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();
}
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -0,0 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 72 4
OpMemoryBarrier %6 %7
OpLine %8 8 1
OpReturn
OpFunctionEnd

View File

@ -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();
}
}

View File

@ -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