Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix semantics type for control barriers to support multiple flags #598

Merged
merged 3 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions crates/spirv-std/src/arch/barrier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use crate::memory::{Scope, Semantics};
/// this instruction. When Execution is Subgroup or Invocation, the behavior of
/// this instruction in non-uniform control flow is defined by the client API.
///
/// If [`Semantics`] is not [`Semantics::None`], this instruction also serves as
/// If [`Semantics`] is not [`Semantics::NONE`], this instruction also serves as
/// an [`memory_barrier`] function call, and also performs and adheres to the
/// description and semantics of an [`memory_barrier`] function with the same
/// `MEMORY` and `SEMANTICS` operands. This allows atomically specifying both a
/// control barrier and a memory barrier (that is, without needing two
/// instructions). If [`Semantics`] is [`Semantics::None`], `MEMORY` is ignored.
/// instructions). If [`Semantics`] is [`Semantics::NONE`], `MEMORY` is ignored.
///
/// Before SPIRV-V version 1.3, it is only valid to use this instruction with
/// `TessellationControl`, `GLCompute`, or `Kernel` execution models. There is
Expand All @@ -43,7 +43,7 @@ pub unsafe fn control_barrier<
"OpControlBarrier %execution %memory %semantics",
execution = const EXECUTION as u8,
memory = const MEMORY as u8,
semantics = const SEMANTICS as u8,
semantics = const SEMANTICS.bits(),
}
}

Expand All @@ -66,13 +66,13 @@ pub unsafe fn control_barrier<
#[doc(alias = "OpMemoryBarrier")]
#[inline]
// FIXME(eddyb) use a `bitflags!` `Semantics` for `SEMANTICS`.
pub unsafe fn memory_barrier<const MEMORY: Scope, const SEMANTICS: u32>() {
pub unsafe fn memory_barrier<const MEMORY: Scope, const SEMANTICS: Semantics>() {
asm! {
"%u32 = OpTypeInt 32 0",
"%memory = OpConstant %u32 {memory}",
"%semantics = OpConstant %u32 {semantics}",
"OpMemoryBarrier %memory %semantics",
memory = const MEMORY as u8,
semantics = const SEMANTICS,
semantics = const SEMANTICS.bits(),
}
}
138 changes: 69 additions & 69 deletions crates/spirv-std/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,73 +21,73 @@ pub enum Scope {
QueueFamily = 5,
}

// FIXME(eddyb) use `bitflags!` for this.
#[derive(Debug, PartialEq, Eq)]
pub enum Semantics {
/// No memory semantics.
None = 0,

/// On an atomic instruction, orders memory operations provided in program
/// order after this atomic instruction against this atomic instruction. On
/// a barrier, orders memory operations provided in program order after this
/// barrier against atomic instructions before this barrier.
Acquire = 0x2,

/// On an atomic instruction, orders memory operations provided in program
/// order before this atomic instruction against this atomic instruction. On
/// a barrier, orders memory operations provided in program order before
/// this barrier against atomic instructions after this barrier.
Release = 0x4,

/// Has the properties of both [`Self::Acquire`] and [`Self::Release`] semantics. It
/// is used for read-modify-write operations.
AcquireRelease = 0x8,

/// All observers see this memory access in the same order with respect to
/// other sequentially-consistent memory accesses from this invocation.
/// If the declared memory model is `vulkan`, `SequentiallyConsistent` must
/// not be used.
SequentiallyConsistent = 0x10,

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::StorageBuffer`],
/// [`crate::storage_class::PhysicalStorageBuffer`], or
/// [`crate::storage_class::Uniform`] Storage Class memory.
UniformMemory = 0x40,

/// Apply the memory-ordering constraints to subgroup memory.
SubgroupMemory = 0x80,

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::Workgroup`] Storage Class memory.
WorkgroupMemory = 0x100,

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::CrossWorkgroup`] Storage Class memory.
CrossWorkgroupMemory = 0x200,

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::AtomicCounter`] Storage Class memory.
AtomicCounterMemory = 0x400,

/// Apply the memory-ordering constraints to image contents (types declared
/// by `OpTypeImage`), or to accesses done through pointers to the
/// [`crate::storage_class::Image`] Storage Class.
ImageMemory = 0x800,

/// Apply the memory-ordering constraints to the
/// [`crate::storage_class::Output`] Storage Class memory.
OutputMemory = 0x1000,

/// Perform an availability operation on all references in the selected
/// storage classes.
MakeAvailable = 0x2000,

/// Perform a visibility operation on all references in the selected
/// storage classes.
MakeVisible = 0x4000,

/// This access cannot be eliminated, duplicated, or combined with
/// other accesses.
Volatile = 0x8000,
bitflags::bitflags! {
pub struct Semantics: u32 {
/// No memory semantics.
const NONE = 0;

/// On an atomic instruction, orders memory operations provided in program
/// order after this atomic instruction against this atomic instruction. On
/// a barrier, orders memory operations provided in program order after this
/// barrier against atomic instructions before this barrier.
const ACQUIRE = 0x2;

/// On an atomic instruction, orders memory operations provided in program
/// order before this atomic instruction against this atomic instruction. On
/// a barrier, orders memory operations provided in program order before
/// this barrier against atomic instructions after this barrier.
const RELEASE = 0x4;

/// Has the properties of both [`Self::ACQUIRE`] and [`Self::RELEASE`] semantics. It
/// is used for read-modify-write operations.
const ACQUIRE_RELEASE = 0x8;

/// All observers see this memory access in the same order with respect to
/// other sequentially-consistent memory accesses from this invocation.
/// If the declared memory model is `vulkan`, `SEQUENTIALLY_CONST` must
/// not be used.
const SEQUENTIALLY_CONST = 0x10;

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::StorageBuffer`],
/// [`crate::storage_class::PhysicalStorageBuffer`], or
/// [`crate::storage_class::Uniform`] Storage Class memory.
const UNIFORM_MEMORY = 0x40;

/// Apply the memory-ordering constraints to subgroup memory.
const SUBGROUP_MEMORY = 0x80;

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::Workgroup`] Storage Class memory.
const WORKGROUP_MEMORY = 0x100;

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::CrossWorkgroup`] Storage Class memory.
const CROSS_WORKGROUP_MEMORY = 0x200;

/// Apply the memory-ordering constraints to
/// [`crate::storage_class::AtomicCounter`] Storage Class memory.
const ATOMIC_COUNTER_MEMORY = 0x400;

/// Apply the memory-ordering constraints to image contents (types declared
/// by `OpTypeImage`), or to accesses done through pointers to the
/// [`crate::storage_class::Image`] Storage Class.
const IMAGE_MEMORY = 0x800;

/// Apply the memory-ordering constraints to the
/// [`crate::storage_class::Output`] Storage Class memory.
const OUTPUT_MEMORY = 0x1000;

/// Perform an availability operation on all references in the selected
/// storage classes.
const MAKE_AVAILABLE = 0x2000;

/// Perform a visibility operation on all references in the selected
/// storage classes.
const MAKE_VISIBLE = 0x4000;

/// This access cannot be eliminated, duplicated, or combined with
/// other accesses.
const VOLATILE = 0x8000;
}
}
2 changes: 1 addition & 1 deletion tests/ui/arch/control_barrier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub fn main() {
spirv_std::arch::control_barrier::<
{ Scope::Subgroup },
{ Scope::Subgroup },
{ Semantics::None },
{ Semantics::NONE },
>();
}
}
6 changes: 5 additions & 1 deletion tests/ui/arch/memory_barrier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ pub fn main() {
unsafe {
spirv_std::arch::memory_barrier::<
{ Scope::Subgroup },
{ (Semantics::AcquireRelease as u32) | (Semantics::UniformMemory as u32) },
{
Semantics::from_bits_truncate(
Semantics::ACQUIRE_RELEASE.bits() | Semantics::UNIFORM_MEMORY.bits(),
)
},
>();
}
}