From 2a6233390d34de0465327e704ed4eb8f345feb43 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sat, 15 Nov 2025 00:52:28 +0100 Subject: [PATCH] adding doc generation --- build.zig | 14 ++++++++++++ src/soft/SoftCommandPool.zig | 7 ++++++ src/soft/SoftDevice.zig | 7 ++++++ src/vulkan/CommandPool.zig | 6 +++--- src/vulkan/Device.zig | 6 ++++-- src/vulkan/Instance.zig | 7 ++++++ src/vulkan/VulkanAllocator.zig | 39 +++++++++++++++++++--------------- src/vulkan/lib.zig | 3 +++ src/vulkan/lib_vulkan.zig | 12 ++++++++--- 9 files changed, 76 insertions(+), 25 deletions(-) diff --git a/build.zig b/build.zig index 48ef167..3e04dad 100644 --- a/build.zig +++ b/build.zig @@ -107,6 +107,20 @@ pub fn build(b: *std.Build) !void { const test_c_step = b.step(b.fmt("test-c-{s}", .{impl.name}), b.fmt("Run lib{s} C test", .{impl.name})); test_c_step.dependOn(&run_c_test.step); } + + const doc_lib = b.addLibrary(.{ + .name = "doc", + .root_module = base_mod, + }); + + const install_docs = b.addInstallDirectory(.{ + .source_dir = doc_lib.getEmittedDocs(), + .install_dir = .prefix, + .install_subdir = "docs", + }); + + const docs_step = b.step("docs", "Build and install the documentation"); + docs_step.dependOn(&install_docs.step); } fn customSoft(b: *std.Build, mod: *std.Build.Module) !void { diff --git a/src/soft/SoftCommandPool.zig b/src/soft/SoftCommandPool.zig index 90d20f7..8868c82 100644 --- a/src/soft/SoftCommandPool.zig +++ b/src/soft/SoftCommandPool.zig @@ -17,6 +17,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v var interface = try Interface.init(device, allocator, info); interface.vtable = &.{ + .allocateCommandBuffers = allocateCommandBuffers, .destroy = destroy, .reset = reset, }; @@ -27,6 +28,12 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v return self; } +pub fn allocateCommandBuffers(interface: *Interface, info: *const vk.CommandBufferAllocateInfo) VkError![]*base.CommandBuffer { + _ = interface; + _ = info; + return VkError.FeatureNotPresent; +} + pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); allocator.destroy(self); diff --git a/src/soft/SoftDevice.zig b/src/soft/SoftDevice.zig index 62156ae..9bc5bde 100644 --- a/src/soft/SoftDevice.zig +++ b/src/soft/SoftDevice.zig @@ -12,6 +12,7 @@ const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); const SoftFence = @import("SoftFence.zig"); const VkError = base.VkError; +const NonDispatchable = base.NonDispatchable; const Self = @This(); pub const Interface = base.Device; @@ -34,6 +35,7 @@ pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocato }; interface.dispatch_table = &.{ + .allocateCommandBuffers = allocateCommandBuffers, .allocateMemory = allocateMemory, .createCommandPool = createCommandPool, .createFence = createFence, @@ -105,6 +107,11 @@ pub fn waitForFences(_: *Interface, fences: []*base.Fence, waitForAll: bool, tim // Command Pool functions ============================================================================================================================ +pub fn allocateCommandBuffers(_: *Interface, info: *const vk.CommandBufferAllocateInfo) VkError![]*base.CommandBuffer { + const pool = try NonDispatchable(base.CommandPool).fromHandleObject(info.command_pool); + return pool.allocateCommandBuffers(info); +} + pub fn createCommandPool(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.CommandPoolCreateInfo) VkError!*base.CommandPool { const pool = try SoftCommandPool.create(interface, allocator, info); return &pool.interface; diff --git a/src/vulkan/CommandPool.zig b/src/vulkan/CommandPool.zig index 4615354..7bd014b 100644 --- a/src/vulkan/CommandPool.zig +++ b/src/vulkan/CommandPool.zig @@ -21,7 +21,7 @@ host_allocator: VulkanAllocator, vtable: *const VTable, pub const VTable = struct { - allocateCommandBuffers: *const fn (*Self, vk.CommandBufferAllocateInfo) VkError!*CommandBuffer, + allocateCommandBuffers: *const fn (*Self, *const vk.CommandBufferAllocateInfo) VkError![]*CommandBuffer, destroy: *const fn (*Self, std.mem.Allocator) void, reset: *const fn (*Self, vk.CommandPoolResetFlags) VkError!void, }; @@ -31,14 +31,14 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Comma .owner = device, .flags = info.flags, .queue_family_index = info.queue_family_index, - .buffers = .initCapacity(allocator, BUFFER_POOL_BASE_CAPACITY) catch return VkError.OutOfHostMemory, + .buffers = std.ArrayList(*CommandBuffer).initCapacity(allocator, BUFFER_POOL_BASE_CAPACITY) catch return VkError.OutOfHostMemory, .host_allocator = VulkanAllocator.from(allocator).clone(), .first_free_buffer_index = 0, .vtable = undefined, }; } -pub inline fn allocateCommandBuffers(self: *Self, info: vk.CommandBufferAllocateInfo) VkError!*CommandBuffer { +pub inline fn allocateCommandBuffers(self: *Self, info: *const vk.CommandBufferAllocateInfo) VkError![]*CommandBuffer { return self.vtable.allocateCommandBuffers(self, info); } diff --git a/src/vulkan/Device.zig b/src/vulkan/Device.zig index 2012ede..78bde2e 100644 --- a/src/vulkan/Device.zig +++ b/src/vulkan/Device.zig @@ -8,6 +8,7 @@ const VkError = @import("error_set.zig").VkError; const PhysicalDevice = @import("PhysicalDevice.zig"); const Queue = @import("Queue.zig"); +const CommandBuffer = @import("CommandBuffer.zig"); const CommandPool = @import("CommandPool.zig"); const DeviceMemory = @import("DeviceMemory.zig"); const Fence = @import("Fence.zig"); @@ -28,6 +29,7 @@ pub const VTable = struct { }; pub const DispatchTable = struct { + allocateCommandBuffers: *const fn (*Self, *const vk.CommandBufferAllocateInfo) VkError![]*CommandBuffer, allocateMemory: *const fn (*Self, std.mem.Allocator, *const vk.MemoryAllocateInfo) VkError!*DeviceMemory, createCommandPool: *const fn (*Self, std.mem.Allocator, *const vk.CommandPoolCreateInfo) VkError!*CommandPool, createFence: *const fn (*Self, std.mem.Allocator, *const vk.FenceCreateInfo) VkError!*Fence, @@ -110,8 +112,8 @@ pub inline fn waitForFences(self: *Self, fences: []*Fence, waitForAll: bool, tim // Command Pool functions ============================================================================================================================ -pub inline fn allocateCommandBuffers(self: *Self, info: *const vk.CommandPoolCreateInfo) VkError![]*CommandBuffer { - return self.dispatch_table.createCommandPool(self, allocator, info); +pub inline fn allocateCommandBuffers(self: *Self, info: *const vk.CommandBufferAllocateInfo) VkError![]*CommandBuffer { + return self.dispatch_table.allocateCommandBuffers(self, info); } pub inline fn createCommandPool(self: *Self, allocator: std.mem.Allocator, info: *const vk.CommandPoolCreateInfo) VkError!*CommandPool { diff --git a/src/vulkan/Instance.zig b/src/vulkan/Instance.zig index b0a11e0..45b0eea 100644 --- a/src/vulkan/Instance.zig +++ b/src/vulkan/Instance.zig @@ -41,6 +41,13 @@ pub fn init(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) V }; } +// Dummy for docs creation and stuff +pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Self { + _ = allocator; + _ = infos; + return VkError.IncompatibleDriver; +} + pub fn deinit(self: *Self, allocator: std.mem.Allocator) VkError!void { try self.releasePhysicalDevices(allocator); try self.dispatch_table.destroyInstance(self, allocator); diff --git a/src/vulkan/VulkanAllocator.zig b/src/vulkan/VulkanAllocator.zig index ca5c016..05a0890 100644 --- a/src/vulkan/VulkanAllocator.zig +++ b/src/vulkan/VulkanAllocator.zig @@ -55,38 +55,43 @@ pub fn cloneWithScope(self: *Self, scope: vk.SystemAllocationScope) Self { fn alloc(context: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8 { const self: *Self = @ptrCast(@alignCast(context)); - if (self.callbacks.?.pfn_allocation) |pfn_allocation| { - return @ptrCast(pfn_allocation(self.callbacks.?.p_user_data, len, alignment.toByteUnits(), self.scope)); - } else { - return getFallbackAllocator().rawAlloc(len, alignment, ret_addr); + + if (self.callbacks) |callbacks| { + if (callbacks.pfn_allocation) |pfn_allocation| { + return @ptrCast(pfn_allocation(self.callbacks.?.p_user_data, len, alignment.toByteUnits(), self.scope)); + } } + + return getFallbackAllocator().rawAlloc(len, alignment, ret_addr); } fn resize(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool { const self: *Self = @ptrCast(@alignCast(context)); - if (self.callbacks != null) { - return new_len <= ptr.len; - } else { - return getFallbackAllocator().rawResize(ptr, alignment, new_len, ret_addr); - } + return if (self.callbacks != null) + new_len <= ptr.len + else + getFallbackAllocator().rawResize(ptr, alignment, new_len, ret_addr); } fn remap(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8 { const self: *Self = @ptrCast(@alignCast(context)); - if (self.callbacks.?.pfn_reallocation) |pfn_reallocation| { - return @ptrCast(pfn_reallocation(self.callbacks.?.p_user_data, ptr.ptr, new_len, alignment.toByteUnits(), self.scope)); - } else { - return getFallbackAllocator().rawRemap(ptr, alignment, new_len, ret_addr); + if (self.callbacks) |callbacks| { + if (callbacks.pfn_reallocation) |pfn_reallocation| { + return @ptrCast(pfn_reallocation(self.callbacks.?.p_user_data, ptr.ptr, new_len, alignment.toByteUnits(), self.scope)); + } } + return getFallbackAllocator().rawRemap(ptr, alignment, new_len, ret_addr); } fn free(context: *anyopaque, ptr: []u8, alignment: Alignment, ret_addr: usize) void { const self: *Self = @ptrCast(@alignCast(context)); - if (self.callbacks.?.pfn_free) |pfn_free| { - return pfn_free(self.callbacks.?.p_user_data, ptr.ptr); - } else { - return getFallbackAllocator().rawFree(ptr, alignment, ret_addr); + if (self.callbacks) |callbacks| { + if (callbacks.pfn_free) |pfn_free| { + pfn_free(self.callbacks.?.p_user_data, ptr.ptr); + } } + + getFallbackAllocator().rawFree(ptr, alignment, ret_addr); } inline fn getFallbackAllocator() std.mem.Allocator { diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index 1375ca8..316e405 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -21,6 +21,9 @@ pub const Fence = @import("Fence.zig"); pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1; +pub const DRIVER_NAME = "VulkanBase"; +pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0); + pub const DRIVER_LOGS_ENV_NAME = "STROLL_LOGS_LEVEL"; pub const DRIVER_DEBUG_ALLOCATOR_ENV_NAME = "STROLL_DEBUG_ALLOCATOR"; diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index 8537db8..bcf98a4 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -1,3 +1,5 @@ +//! This file contains all exported Vulkan entrypoints. + const std = @import("std"); const vk = @import("vulkan"); const root = @import("root"); @@ -19,12 +21,11 @@ const Device = @import("Device.zig"); const PhysicalDevice = @import("PhysicalDevice.zig"); const Queue = @import("Queue.zig"); +const CommandBuffer = @import("CommandBuffer.zig"); const CommandPool = @import("CommandPool.zig"); const DeviceMemory = @import("DeviceMemory.zig"); const Fence = @import("Fence.zig"); -// This file contains all exported Vulkan entrypoints. - fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []const u8) void { if (lib.getLogVerboseLevel() != .High) return; std.log.scoped(scope).err("Could not find function {s}", .{name}); @@ -289,8 +290,13 @@ pub export fn strollAllocateCommandBuffers(p_device: vk.Device, p_info: ?*const return .error_validation_failed; } const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); + const pool = NonDispatchable(CommandPool).fromHandleObject(info.command_pool) catch |err| return toVkResult(err); + const allocator = pool.host_allocator.allocator(); + const cmds = device.allocateCommandBuffers(info) catch |err| return toVkResult(err); - @memcpy(p_cmds[0..info.command_buffer_count], cmds[0..info.command_buffer_count]); + for (cmds[0..info.command_buffer_count], 0..) |cmd, i| { + p_cmds[i] = (NonDispatchable(CommandBuffer).wrap(allocator, cmd) catch |err| return toVkResult(err)).toVkHandle(vk.CommandBuffer); + } return .success; }