From bbd21e55de44011a7ebf69a9bd9ba2e1b49200a6 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sun, 14 Dec 2025 23:11:35 +0100 Subject: [PATCH] working on events --- src/soft/SoftCommandBuffer.zig | 28 +++++++++++++++++ src/soft/SoftEvent.zig | 56 ++++++++++++++++++++++++++++++++++ src/vulkan/CommandBuffer.zig | 16 ++++++++++ src/vulkan/Event.zig | 20 ++++++++++++ src/vulkan/lib_vulkan.zig | 49 ++++++++++------------------- 5 files changed, 136 insertions(+), 33 deletions(-) diff --git a/src/soft/SoftCommandBuffer.zig b/src/soft/SoftCommandBuffer.zig index 01dfff3..faa5561 100644 --- a/src/soft/SoftCommandBuffer.zig +++ b/src/soft/SoftCommandBuffer.zig @@ -28,6 +28,9 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v .end = end, .fillBuffer = fillBuffer, .reset = reset, + .resetEvent = resetEvent, + .setEvent = setEvent, + .waitEvents = waitEvents, }; self.* = .{ @@ -93,3 +96,28 @@ pub fn copyImage(interface: *Interface, src: *base.Image, dst: *base.Image, regi _ = dst; _ = regions; } + +pub fn resetEvent(interface: *Interface, event: *base.Event, stage: vk.PipelineStageFlags) VkError!void { + // No-op + _ = interface; + _ = event; + _ = stage; +} + +pub fn setEvent(interface: *Interface, event: *base.Event, stage: vk.PipelineStageFlags) VkError!void { + // No-op + _ = interface; + _ = event; + _ = stage; +} + +pub fn waitEvents(interface: *Interface, events: []*const base.Event, src_stage: vk.PipelineStageFlags, dst_stage: vk.PipelineStageFlags, memory_barriers: []const vk.MemoryBarrier, buffer_barriers: []const vk.BufferMemoryBarrier, image_barriers: []const vk.ImageMemoryBarrier) VkError!void { + // No-op + _ = interface; + _ = events; + _ = src_stage; + _ = dst_stage; + _ = memory_barriers; + _ = buffer_barriers; + _ = image_barriers; +} diff --git a/src/soft/SoftEvent.zig b/src/soft/SoftEvent.zig index 8eec713..63c8a52 100644 --- a/src/soft/SoftEvent.zig +++ b/src/soft/SoftEvent.zig @@ -9,6 +9,9 @@ const Self = @This(); pub const Interface = base.Event; interface: Interface, +mutex: std.Thread.Mutex, +condition: std.Thread.Condition, +is_signaled: bool, pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.EventCreateInfo) VkError!*Self { const self = allocator.create(Self) catch return VkError.OutOfHostMemory; @@ -18,10 +21,17 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v interface.vtable = &.{ .destroy = destroy, + .getStatus = getStatus, + .reset = reset, + .signal = signal, + .wait = wait, }; self.* = .{ .interface = interface, + .mutex = std.Thread.Mutex{}, + .condition = std.Thread.Condition{}, + .is_signaled = false, }; return self; } @@ -30,3 +40,49 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); allocator.destroy(self); } + +pub fn getStatus(interface: *Interface) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + + self.mutex.lock(); + defer self.mutex.unlock(); + + if (!self.is_signaled) { + return VkError.EventReset; + } +} + +pub fn reset(interface: *Interface) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + + self.mutex.lock(); + defer self.mutex.unlock(); + + self.is_signaled = false; +} + +pub fn signal(interface: *Interface) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + + self.mutex.lock(); + defer self.mutex.unlock(); + + self.is_signaled = true; + self.condition.broadcast(); +} + +pub fn wait(interface: *Interface, timeout: u64) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + + self.mutex.lock(); + defer self.mutex.unlock(); + + if (self.is_signaled) return; + if (timeout == 0) return VkError.Timeout; + + if (timeout == std.math.maxInt(@TypeOf(timeout))) { + self.condition.wait(&self.mutex); + } else { + self.condition.timedWait(&self.mutex, timeout) catch return VkError.Timeout; + } +} diff --git a/src/vulkan/CommandBuffer.zig b/src/vulkan/CommandBuffer.zig index 25c648e..524add6 100644 --- a/src/vulkan/CommandBuffer.zig +++ b/src/vulkan/CommandBuffer.zig @@ -11,6 +11,7 @@ const Device = @import("Device.zig"); const Buffer = @import("Buffer.zig"); const CommandPool = @import("CommandPool.zig"); +const Event = @import("Event.zig"); const Image = @import("Image.zig"); const COMMAND_BUFFER_BASE_CAPACITY = 256; @@ -45,6 +46,9 @@ pub const DispatchTable = struct { end: *const fn (*Self) VkError!void, fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void, reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void, + resetEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void, + setEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void, + waitEvents: *const fn (*Self, []*const Event, vk.PipelineStageFlags, vk.PipelineStageFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void, }; pub const VTable = struct { @@ -169,3 +173,15 @@ pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, si } }) catch return VkError.OutOfHostMemory; try self.dispatch_table.fillBuffer(self, buffer, offset, size, data); } + +pub inline fn resetEvent(self: *Self, event: *Event, stage: vk.PipelineStageFlags) VkError!void { + try self.dispatch_table.resetEvent(self, event, stage); +} + +pub inline fn setEvent(self: *Self, event: *Event, stage: vk.PipelineStageFlags) VkError!void { + try self.dispatch_table.setEvent(self, event, stage); +} + +pub inline fn waitEvents(self: *Self, events: []*const Event, src_stage: vk.PipelineStageFlags, dst_stage: vk.PipelineStageFlags, memory_barriers: []const vk.MemoryBarrier, buffer_barriers: []const vk.BufferMemoryBarrier, image_barriers: []const vk.ImageMemoryBarrier) VkError!void { + try self.dispatch_table.waitEvents(self, events, src_stage, dst_stage, memory_barriers, buffer_barriers, image_barriers); +} diff --git a/src/vulkan/Event.zig b/src/vulkan/Event.zig index b3af327..059043b 100644 --- a/src/vulkan/Event.zig +++ b/src/vulkan/Event.zig @@ -16,6 +16,10 @@ vtable: *const VTable, pub const VTable = struct { destroy: *const fn (*Self, std.mem.Allocator) void, + getStatus: *const fn (*Self) VkError!void, + reset: *const fn (*Self) VkError!void, + signal: *const fn (*Self) VkError!void, + wait: *const fn (*Self, u64) VkError!void, }; pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.EventCreateInfo) VkError!Self { @@ -30,3 +34,19 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Event pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { self.vtable.destroy(self, allocator); } + +pub inline fn getStatus(self: *Self) VkError!void { + try self.vtable.getStatus(self); +} + +pub inline fn reset(self: *Self) VkError!void { + try self.vtable.reset(self); +} + +pub inline fn signal(self: *Self) VkError!void { + try self.vtable.signal(self); +} + +pub inline fn wait(self: *Self, timeout: u64) VkError!void { + try self.vtable.wait(self, timeout); +} diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index adb2449..ce3ac8f 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -1219,11 +1219,9 @@ pub export fn strollGetEventStatus(p_device: vk.Device, p_event: vk.Event) callc Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err); - notImplementedWarning(); - - _ = p_event; - - return .error_unknown; + const event = NonDispatchable(Event).fromHandleObject(p_event) catch |err| return toVkResult(err); + event.getStatus() catch |err| return toVkResult(err); + return .success; } pub export fn strollGetFenceStatus(p_device: vk.Device, p_fence: vk.Fence) callconv(vk.vulkan_call_conv) vk.Result { @@ -1234,7 +1232,7 @@ pub export fn strollGetFenceStatus(p_device: vk.Device, p_fence: vk.Fence) callc const fence = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err); fence.getStatus() catch |err| return toVkResult(err); - return .success; + return .event_set; } pub export fn strollGetImageMemoryRequirements(p_device: vk.Device, p_image: vk.Image, requirements: *vk.MemoryRequirements) callconv(vk.vulkan_call_conv) void { @@ -1406,11 +1404,9 @@ pub export fn strollResetEvent(p_device: vk.Device, p_event: vk.Fence) callconv( Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err); - notImplementedWarning(); - - _ = p_event; - - return .error_unknown; + const event = NonDispatchable(Event).fromHandleObject(p_event) catch |err| return toVkResult(err); + event.reset() catch |err| return toVkResult(err); + return .success; } pub export fn strollResetFences(p_device: vk.Device, count: u32, p_fences: [*]const vk.Fence) callconv(vk.vulkan_call_conv) vk.Result { @@ -1432,11 +1428,9 @@ pub export fn strollSetEvent(p_device: vk.Device, p_event: vk.Fence) callconv(vk Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err); - notImplementedWarning(); - - _ = p_event; - - return .error_unknown; + const event = NonDispatchable(Event).fromHandleObject(p_event) catch |err| return toVkResult(err); + event.signal() catch |err| return toVkResult(err); + return .success; } pub export fn strollUnmapMemory(p_device: vk.Device, p_memory: vk.DeviceMemory) callconv(vk.vulkan_call_conv) void { @@ -1951,12 +1945,8 @@ pub export fn strollCmdResetEvent(p_cmd: vk.CommandBuffer, p_event: vk.Event, st defer entryPointEndLogTrace(); const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err); - - notImplementedWarning(); - - _ = cmd; - _ = p_event; - _ = stage_mask; + const event = NonDispatchable(Event).fromHandleObject(p_event) catch |err| return errorLogger(err); + cmd.resetEvent(event, stage_mask) catch |err| return errorLogger(err); } pub export fn strollCmdResolveImage( @@ -2031,12 +2021,8 @@ pub export fn strollCmdSetEvent(p_cmd: vk.CommandBuffer, p_event: vk.Event, stag defer entryPointEndLogTrace(); const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err); - - notImplementedWarning(); - - _ = cmd; - _ = p_event; - _ = stage_mask; + const event = NonDispatchable(Event).fromHandleObject(p_event) catch |err| return errorLogger(err); + cmd.setEvent(event, stage_mask) catch |err| return errorLogger(err); } pub export fn strollCmdSetLineWidth(p_cmd: vk.CommandBuffer, width: f32) callconv(vk.vulkan_call_conv) void { @@ -2150,11 +2136,6 @@ pub export fn strollCmdWaitEvents( entryPointBeginLogTrace(.vkCmdWaitEvents); defer entryPointEndLogTrace(); - const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err); - - notImplementedWarning(); - - _ = cmd; _ = count; _ = p_events; _ = src_stage_mask; @@ -2165,6 +2146,8 @@ pub export fn strollCmdWaitEvents( _ = buffer_memory_barriers; _ = image_memory_barrier_count; _ = image_memory_barriers; + const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err); + _ = cmd; } pub export fn strollCmdWriteTimestamp(p_cmd: vk.CommandBuffer, stage: vk.PipelineStageFlags, p_pool: vk.QueryPool, query: u32) callconv(vk.vulkan_call_conv) void {