Skip to content

Commit

Permalink
Fix semantics type for control barriers to support multiple flags (#598)
Browse files Browse the repository at this point in the history
* Fix semantics type for control barriers to support multiple flags

* spirv-std: convert memory semantics to bitflag

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

Co-authored-by: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com>

Co-authored-by: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com>
  • Loading branch information
msiglreith and XAMPPRocky authored Apr 22, 2021
1 parent d04039e commit 3d710e7
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 76 deletions.
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(),
)
},
>();
}
}

0 comments on commit 3d710e7

Please sign in to comment.