Skip to content

Commit 330311b

Browse files
committed
Add memory_barrier and control_barrier
1 parent 2f451ee commit 330311b

File tree

5 files changed

+98
-104
lines changed

5 files changed

+98
-104
lines changed

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

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
1+
use crate::memory::{Scope, Semantics};
2+
13
/// Wait for other invocations of this module to reach the current point
24
/// of execution.
35
///
46
/// All invocations of this module within Execution scope reach this point of
57
/// execution before any invocation proceeds beyond it.
68
///
7-
/// When Execution is [`crate::memory::Scope::Workgroup`] or larger, behavior is
8-
/// undefined unless all invocations within Execution execute the same dynamic
9-
/// instance of this instruction. When Execution is Subgroup or Invocation, the
10-
/// behavior of this instruction in non-uniform control flow is defined by the
11-
/// client API.
9+
/// When Execution is [`Scope::Workgroup`] or larger, behavior is undefined
10+
/// unless all invocations within Execution execute the same dynamic instance of
11+
/// this instruction. When Execution is Subgroup or Invocation, the behavior of
12+
/// this instruction in non-uniform control flow is defined by the client API.
1213
///
13-
/// If [`crate::memory::Semantics`] is not [`crate::memory::Semantics::NONE`],
14-
/// this instruction also serves as an [`memory_barrier`] function call, and
15-
/// also performs and adheres to the description and semantics of an
16-
/// [`memory_barrier`] function with the same `MEMORY` and `SEMANTICS` operands.
17-
/// This allows atomically specifying both a control barrier and a memory
18-
/// barrier (that is, without needing two instructions). If
19-
/// [`crate::memory::Semantics`] is [`crate::memory::Semantics::NONE`], `MEMORY`
20-
/// is ignored.
14+
/// If [`Semantics`] is not [`Semantics::None`], this instruction also serves as
15+
/// an [`memory_barrier`] function call, and also performs and adheres to the
16+
/// description and semantics of an [`memory_barrier`] function with the same
17+
/// `MEMORY` and `SEMANTICS` operands. This allows atomically specifying both a
18+
/// control barrier and a memory barrier (that is, without needing two
19+
/// instructions). If [`Semantics`] is [`Semantics::None`], `MEMORY` is ignored.
2120
///
2221
/// Before SPIRV-V version 1.3, it is only valid to use this instruction with
2322
/// `TessellationControl`, `GLCompute`, or `Kernel` execution models. There is
2423
/// no such restriction starting with version 1.3.
2524
///
2625
/// If used with the `TessellationControl` execution model, it also implicitly
27-
/// synchronizes the `output` storage class: Writes to `output` variables
28-
/// performed by any invocation executed prior to a [`control_barrier`] are
29-
/// visible to any other invocation proceeding beyond that [`control_barrier`].
26+
/// synchronizes the [`crate::storage_class::Output`] Storage Class: Writes to
27+
/// `Output` variables performed by any invocation executed prior to a
28+
/// [`control_barrier`] are visible to any other invocation proceeding beyond
29+
/// that [`control_barrier`].
3030
#[spirv_std_macros::gpu_only]
3131
#[doc(alias = "OpControlBarrier")]
3232
#[inline]
3333
pub unsafe fn control_barrier<
34-
const EXECUTION: u32, // Scope
35-
const MEMORY: u32, // Scope
36-
const SEMANTICS: u32, // Semantics
34+
const EXECUTION: Scope,
35+
const MEMORY: Scope,
36+
const SEMANTICS: Semantics,
3737
>() {
3838
asm! {
3939
"%u32 = OpTypeInt 32 0",
4040
"%execution = OpConstant %u32 {execution}",
4141
"%memory = OpConstant %u32 {memory}",
4242
"%semantics = OpConstant %u32 {semantics}",
4343
"OpControlBarrier %execution %memory %semantics",
44-
execution = const EXECUTION,
45-
memory = const MEMORY,
46-
semantics = const SEMANTICS,
44+
execution = const EXECUTION as u8,
45+
memory = const MEMORY as u8,
46+
semantics = const SEMANTICS as u8,
4747
}
4848
}
4949

@@ -65,16 +65,13 @@ pub unsafe fn control_barrier<
6565
#[spirv_std_macros::gpu_only]
6666
#[doc(alias = "OpMemoryBarrier")]
6767
#[inline]
68-
pub unsafe fn memory_barrier<
69-
const MEMORY: u32, // Scope
70-
const SEMANTICS: u32, // Semantics
71-
>() {
68+
pub unsafe fn memory_barrier<const MEMORY: Scope, const SEMANTICS: Semantics>() {
7269
asm! {
7370
"%u32 = OpTypeInt 32 0",
7471
"%memory = OpConstant %u32 {memory}",
7572
"%semantics = OpConstant %u32 {semantics}",
7673
"OpMemoryBarrier %memory %semantics",
77-
memory = const MEMORY,
78-
semantics = const SEMANTICS,
74+
memory = const MEMORY as u8,
75+
semantics = const SEMANTICS as u8,
7976
}
8077
}

crates/spirv-std/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ pub mod float;
8181
pub mod image;
8282
pub mod integer;
8383
pub mod memory;
84-
pub mod ray_tracing;
85-
mod sampler;
8684
pub mod scalar;
8785
pub(crate) mod sealed;
8886
mod textures;

crates/spirv-std/src/memory.rs

Lines changed: 68 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,73 +21,72 @@ pub enum Scope {
2121
QueueFamily = 5,
2222
}
2323

24-
bitflags::bitflags! {
25-
pub struct Semantics: u32 {
26-
/// No memory semantics.
27-
const NONE = 0;
28-
29-
/// On an atomic instruction, orders memory operations provided in program
30-
/// order after this atomic instruction against this atomic instruction. On
31-
/// a barrier, orders memory operations provided in program order after this
32-
/// barrier against atomic instructions before this barrier.
33-
const ACQUIRE = 0x2;
34-
35-
/// On an atomic instruction, orders memory operations provided in program
36-
/// order before this atomic instruction against this atomic instruction. On
37-
/// a barrier, orders memory operations provided in program order before
38-
/// this barrier against atomic instructions after this barrier.
39-
const RELEASE = 0x4;
40-
41-
/// Has the properties of both [`Self::ACQUIRE`] and [`Self::RELEASE`] semantics. It
42-
/// is used for read-modify-write operations.
43-
const ACQUIRE_RELEASE = 0x8;
44-
45-
/// All observers see this memory access in the same order with respect to
46-
/// other sequentially-consistent memory accesses from this invocation.
47-
/// If the declared memory model is `vulkan`, `SEQUENTIALLY_CONST` must
48-
/// not be used.
49-
const SEQUENTIALLY_CONST = 0x10;
50-
51-
/// Apply the memory-ordering constraints to
52-
/// [`crate::storage_class::StorageBuffer`],
53-
/// [`crate::storage_class::PhysicalStorageBuffer`], or
54-
/// [`crate::storage_class::Uniform`] Storage Class memory.
55-
const UNIFORM_MEMORY = 0x40;
56-
57-
/// Apply the memory-ordering constraints to subgroup memory.
58-
const SUBGROUP_MEMORY = 0x80;
59-
60-
/// Apply the memory-ordering constraints to
61-
/// [`crate::storage_class::Workgroup`] Storage Class memory.
62-
const WORKGROUP_MEMORY = 0x100;
63-
64-
/// Apply the memory-ordering constraints to
65-
/// [`crate::storage_class::CrossWorkgroup`] Storage Class memory.
66-
const CROSS_WORKGROUP_MEMORY = 0x200;
67-
68-
/// Apply the memory-ordering constraints to
69-
/// [`crate::storage_class::AtomicCounter`] Storage Class memory.
70-
const ATOMIC_COUNTER_MEMORY = 0x400;
71-
72-
/// Apply the memory-ordering constraints to image contents (types declared
73-
/// by `OpTypeImage`), or to accesses done through pointers to the
74-
/// [`crate::storage_class::Image`] Storage Class.
75-
const IMAGE_MEMORY = 0x800;
76-
77-
/// Apply the memory-ordering constraints to the
78-
/// [`crate::storage_class::Output`] Storage Class memory.
79-
const OUTPUT_MEMORY = 0x1000;
80-
81-
/// Perform an availability operation on all references in the selected
82-
/// storage classes.
83-
const MAKE_AVAILABLE = 0x2000;
84-
85-
/// Perform a visibility operation on all references in the selected
86-
/// storage classes.
87-
const MAKE_VISIBLE = 0x4000;
88-
89-
/// This access cannot be eliminated, duplicated, or combined with
90-
/// other accesses.
91-
const VOLATILE = 0x8000;
92-
}
24+
#[derive(Debug, PartialEq, Eq)]
25+
pub enum Semantics {
26+
/// No memory semantics.
27+
None = 0,
28+
29+
/// On an atomic instruction, orders memory operations provided in program
30+
/// order after this atomic instruction against this atomic instruction. On
31+
/// a barrier, orders memory operations provided in program order after this
32+
/// barrier against atomic instructions before this barrier.
33+
Acquire = 0x2,
34+
35+
/// On an atomic instruction, orders memory operations provided in program
36+
/// order before this atomic instruction against this atomic instruction. On
37+
/// a barrier, orders memory operations provided in program order before
38+
/// this barrier against atomic instructions after this barrier.
39+
Release = 0x4,
40+
41+
/// Has the properties of both [`Self::Acquire`] and [`Self::Release`] semantics. It
42+
/// is used for read-modify-write operations.
43+
AcquireRelease = 0x8,
44+
45+
/// All observers see this memory access in the same order with respect to
46+
/// other sequentially-consistent memory accesses from this invocation.
47+
/// If the declared memory model is `vulkan`, `SequentiallyConsistent` must
48+
/// not be used.
49+
SequentiallyConsistent = 0x10,
50+
51+
/// Apply the memory-ordering constraints to
52+
/// [`crate::storage_class::StorageBuffer`],
53+
/// [`crate::storage_class::PhysicalStorageBuffer`], or
54+
/// [`crate::storage_class::Uniform`] Storage Class memory.
55+
UniformMemory = 0x40,
56+
57+
/// Apply the memory-ordering constraints to subgroup memory.
58+
SubgroupMemory = 0x80,
59+
60+
/// Apply the memory-ordering constraints to
61+
/// [`crate::storage_class::Workgroup`] Storage Class memory.
62+
WorkgroupMemory = 0x100,
63+
64+
/// Apply the memory-ordering constraints to
65+
/// [`crate::storage_class::CrossWorkgroup`] Storage Class memory.
66+
CrossWorkgroupMemory = 0x200,
67+
68+
/// Apply the memory-ordering constraints to
69+
/// [`crate::storage_class::AtomicCounter`] Storage Class memory.
70+
AtomicCounterMemory = 0x400,
71+
72+
/// Apply the memory-ordering constraints to image contents (types declared
73+
/// by `OpTypeImage`), or to accesses done through pointers to the
74+
/// [`crate::storage_class::Image`] Storage Class.
75+
ImageMemory = 0x800,
76+
77+
/// Apply the memory-ordering constraints to the
78+
/// [`crate::storage_class::Output`] Storage Class memory.
79+
OutputMemory = 0x1000,
80+
81+
/// Perform an availability operation on all references in the selected
82+
/// storage classes.
83+
MakeAvailable = 0x2000,
84+
85+
/// Perform a visibility operation on all references in the selected
86+
/// storage classes.
87+
MakeVisible = 0x4000,
88+
89+
/// This access cannot be eliminated, duplicated, or combined with
90+
/// other accesses.
91+
Volatile = 0x8000,
9392
}

tests/ui/arch/control_barrier.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use spirv_std::memory::{Scope, Semantics};
99
pub fn main() {
1010
unsafe {
1111
spirv_std::arch::control_barrier::<
12-
{ Scope::Subgroup as u32 },
13-
{ Scope::Subgroup as u32 },
14-
{ Semantics::NONE.bits() },
12+
{ Scope::Workgroup },
13+
{ Scope::Workgroup },
14+
{ Semantics::None },
1515
>();
1616
}
1717
}

tests/ui/arch/memory_barrier.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use spirv_std::memory::{Scope, Semantics};
99
pub fn main() {
1010
unsafe {
1111
spirv_std::arch::memory_barrier::<
12-
{ Scope::Subgroup as u32 },
13-
{ Semantics::ACQUIRE_RELEASE.bits() | Semantics::UNIFORM_MEMORY.bits() },
12+
{ Scope::Workgroup },
13+
{ Semantics::None },
1414
>();
1515
}
1616
}

0 commit comments

Comments
 (0)