implementing binary semaphores
Test / build_and_test (push) Successful in 40s
Build / build (push) Successful in 52s

This commit is contained in:
2026-06-06 11:25:21 +02:00
parent c7a298978a
commit 3fcdc26baf
11 changed files with 250 additions and 70 deletions
+10
View File
@@ -16,6 +16,8 @@ vtable: *const VTable,
pub const VTable = struct {
destroy: *const fn (*Self, std.mem.Allocator) void,
signal: *const fn (*Self) VkError!void,
wait: *const fn (*Self) VkError!void,
};
pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.SemaphoreCreateInfo) VkError!Self {
@@ -30,3 +32,11 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Semap
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
self.vtable.destroy(self, allocator);
}
pub inline fn signal(self: *Self) VkError!void {
try self.vtable.signal(self);
}
pub inline fn wait(self: *Self) VkError!void {
try self.vtable.wait(self);
}
+5
View File
@@ -80,6 +80,7 @@ pub const DispatchTable = struct {
setStencilReference: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
setStencilWriteMask: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
setViewport: *const fn (*Self, u32, []const vk.Viewport) VkError!void,
updateBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, []const u8) VkError!void,
waitEvent: *const fn (*Self, *Event, vk.PipelineStageFlags, vk.PipelineStageFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void,
};
@@ -245,6 +246,10 @@ pub inline fn dispatchIndirect(self: *Self, buffer: *Buffer, offset: vk.DeviceSi
try self.dispatch_table.dispatchIndirect(self, buffer, offset);
}
pub inline fn updateBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, data: []const u8) VkError!void {
try self.dispatch_table.updateBuffer(self, buffer, offset, data);
}
pub inline fn draw(self: *Self, vertex_count: usize, instance_count: usize, first_vertex: usize, first_instance: usize) VkError!void {
try self.dispatch_table.draw(self, vertex_count, instance_count, first_vertex, first_instance);
}
+36 -8
View File
@@ -34,23 +34,43 @@ pub const DispatchTable = struct {
};
pub const SubmitInfo = struct {
wait_semaphores: std.ArrayList(*BinarySemaphore),
command_buffers: std.ArrayList(*CommandBuffer),
signal_semaphores: std.ArrayList(*BinarySemaphore),
// TODO: complete
fn initBlob(allocator: std.mem.Allocator, infos: []const vk.SubmitInfo) VkError!std.ArrayList(SubmitInfo) {
var self = std.ArrayList(SubmitInfo).initCapacity(allocator, infos.len) catch return VkError.OutOfHostMemory;
errdefer self.deinit(allocator);
errdefer deinitBlob(allocator, &self);
loop: for (infos) |info| {
if (info.command_buffer_count == 0) continue :loop;
if (info.p_command_buffers == null) continue :loop;
if (info.wait_semaphore_count == 0 and info.command_buffer_count == 0 and info.signal_semaphore_count == 0) continue :loop;
var submit_info: SubmitInfo = .{
.wait_semaphores = std.ArrayList(*BinarySemaphore).initCapacity(allocator, info.wait_semaphore_count) catch return VkError.OutOfHostMemory,
.command_buffers = std.ArrayList(*CommandBuffer).initCapacity(allocator, info.command_buffer_count) catch return VkError.OutOfHostMemory,
.signal_semaphores = std.ArrayList(*BinarySemaphore).initCapacity(allocator, info.signal_semaphore_count) catch return VkError.OutOfHostMemory,
};
errdefer submit_info.wait_semaphores.deinit(allocator);
errdefer submit_info.command_buffers.deinit(allocator);
errdefer submit_info.signal_semaphores.deinit(allocator);
for (info.p_command_buffers.?[0..info.command_buffer_count]) |vk_command_buffer| {
submit_info.command_buffers.append(allocator, try Dispatchable(CommandBuffer).fromHandleObject(vk_command_buffer)) catch return VkError.OutOfHostMemory;
if (info.p_wait_semaphores) |p_wait_semaphores| {
for (p_wait_semaphores[0..info.wait_semaphore_count]) |p_semaphore| {
submit_info.wait_semaphores.append(allocator, try NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore)) catch return VkError.OutOfHostMemory;
}
}
if (info.p_command_buffers) |p_command_buffers| {
for (p_command_buffers[0..info.command_buffer_count]) |vk_command_buffer| {
submit_info.command_buffers.append(allocator, try Dispatchable(CommandBuffer).fromHandleObject(vk_command_buffer)) catch return VkError.OutOfHostMemory;
}
}
if (info.p_signal_semaphores) |p_signal_semaphores| {
for (p_signal_semaphores[0..info.signal_semaphore_count]) |p_semaphore| {
submit_info.signal_semaphores.append(allocator, try NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore)) catch return VkError.OutOfHostMemory;
}
}
self.append(allocator, submit_info) catch return VkError.OutOfHostMemory;
@@ -60,7 +80,9 @@ pub const SubmitInfo = struct {
fn deinitBlob(allocator: std.mem.Allocator, self: *std.ArrayList(SubmitInfo)) void {
for (self.items) |*submit_info| {
submit_info.wait_semaphores.deinit(allocator);
submit_info.command_buffers.deinit(allocator);
submit_info.signal_semaphores.deinit(allocator);
}
self.deinit(allocator);
}
@@ -95,15 +117,21 @@ pub fn submit(self: *Self, infos: []const vk.SubmitInfo, p_fence: ?*Fence) VkErr
var submit_infos = try SubmitInfo.initBlob(allocator, infos);
defer SubmitInfo.deinitBlob(allocator, &submit_infos);
if (submit_infos.items.len == 0) {
if (p_fence) |fence| {
try fence.signal();
}
return;
}
try self.dispatch_table.submit(self, submit_infos.items, p_fence);
}
pub fn presentKHR(_: *Self, info: *const vk.PresentInfoKHR) VkError!void {
if (info.p_wait_semaphores) |p_wait_semaphores| {
for (p_wait_semaphores[0..], 0..info.wait_semaphore_count) |p_semaphore, _| {
for (p_wait_semaphores[0..info.wait_semaphore_count]) |p_semaphore| {
const semaphore = try NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore);
// TODO: handle semaphores
_ = semaphore;
try semaphore.wait();
}
}
+4 -12
View File
@@ -52,7 +52,7 @@ pub const ShaderModule = @import("ShaderModule.zig");
pub const SurfaceKHR = @import("wsi/SurfaceKHR.zig");
pub const SwapchainKHR = @import("wsi/SwapchainKHR.zig");
pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1;
pub const VULKAN_VENDOR_ID = 0x10008;
/// Default driver name
pub const DRIVER_NAME = "Unnamed Ape Driver";
@@ -60,10 +60,10 @@ pub const DRIVER_NAME = "Unnamed Ape Driver";
pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0);
/// Maximum number of descriptor sets per pipeline
pub const VULKAN_MAX_DESCRIPTOR_SETS = 4;
pub const VULKAN_MAX_DESCRIPTOR_SETS = 8;
/// The number of push constant ranges is effectively bounded
/// by the number of possible shader stages. Not the number of stages that can
/// by the number of possible shader stages. Not the number of stages that can
/// be compiled together (a pipeline layout can be used in multiple pipelnes
/// wth different sets of shaders) but the total number of stage bits supported
/// by the implementation. Currently, those are
@@ -73,15 +73,7 @@ pub const VULKAN_MAX_DESCRIPTOR_SETS = 4;
/// - VK_SHADER_STAGE_GEOMETRY_BIT
/// - VK_SHADER_STAGE_FRAGMENT_BIT
/// - VK_SHADER_STAGE_COMPUTE_BIT
/// - VK_SHADER_STAGE_RAYGEN_BIT_KHR
/// - VK_SHADER_STAGE_ANY_HIT_BIT_KHR
/// - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
/// - VK_SHADER_STAGE_MISS_BIT_KHR
/// - VK_SHADER_STAGE_INTERSECTION_BIT_KHR
/// - VK_SHADER_STAGE_CALLABLE_BIT_KHR
/// - VK_SHADER_STAGE_TASK_BIT_EXT
/// - VK_SHADER_STAGE_MESH_BIT_EXT
pub const VULKAN_MAX_PUSH_CONSTANT_RANGES = 14;
pub const VULKAN_MAX_PUSH_CONSTANT_RANGES = 6;
pub const std_options: std.Options = .{
.log_level = .debug,
+3 -9
View File
@@ -2069,15 +2069,9 @@ pub export fn apeCmdUpdateBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, o
defer entryPointEndLogTrace();
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
const buffer = Dispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
notImplementedWarning();
_ = cmd;
_ = buffer;
_ = offset;
_ = size;
_ = data;
const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
const data_bytes: [*]const u8 = @ptrCast(data);
cmd.updateBuffer(buffer, offset, data_bytes[0..size]) catch |err| return errorLogger(err);
}
pub export fn apeCmdWaitEvents(