diff --git a/lib/std/spirv.zig b/lib/std/spirv.zig index 7a7c4f3d78797a939c29507b1fce43cfb18a7b65..6f9fd74967053ec295ad14882d4abda7eedccc18 100644 --- a/lib/std/spirv.zig +++ b/lib/std/spirv.zig @@ -19,3 +19,66 @@ pub extern const local_invocation_id: @Vector(3, u32) addrspace(.input); pub extern const global_invocation_id: @Vector(3, u32) addrspace(.input); pub extern const vertex_index: u32 addrspace(.input); pub extern const instance_index: u32 addrspace(.input); + +pub const Scope = enum(u32) { + cross_device = 0, + device = 1, + workgroup = 2, + subgroup = 3, + invocation = 4, + queue_family = 5, + shader_call_khr = 6, +}; + +pub const MemorySemantics = packed struct(u32) { + _reserved_bit_0: bool = false, + acquire: bool = false, + release: bool = false, + acquire_release: bool = false, + sequentially_consistent: bool = false, + _reserved_bit_5: bool = false, + uniform_memory: bool = false, + subgroup_memory: bool = false, + workgroup_memory: bool = false, + cross_workgroup_memory: bool = false, + atomic_counter_memory: bool = false, + image_memory: bool = false, + output_memory: bool = false, + make_available: bool = false, + make_visible: bool = false, + @"volatile": bool = false, + _reserved: u16 = 0, + + pub const none: MemorySemantics = .{}; +}; + +pub fn controlBarrier( + comptime execution: Scope, + comptime memory: Scope, + comptime semantics: MemorySemantics, +) void { + asm volatile ( + \\OpControlBarrier %exec %mem %sem + : + : [exec] "" (@as(u32, @intFromEnum(execution))), + [mem] "" (@as(u32, @intFromEnum(memory))), + [sem] "" (@as(u32, @bitCast(semantics))), + ); +} + +pub fn memoryBarrier(comptime memory: Scope, comptime semantics: MemorySemantics) void { + asm volatile ( + \\OpMemoryBarrier %mem %sem + : + : [mem] "" (@as(u32, @intFromEnum(memory))), + [sem] "" (@as(u32, @bitCast(semantics))), + ); +} + +pub fn workgroupBarrier() void { + controlBarrier( + .workgroup, + .workgroup, + .{ .acquire_release = true, .workgroup_memory = true }, + ); +}