adding doc generation

This commit is contained in:
2025-11-15 00:52:28 +01:00
parent 2928517451
commit 2a6233390d
9 changed files with 76 additions and 25 deletions

View File

@@ -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})); 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); 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 { fn customSoft(b: *std.Build, mod: *std.Build.Module) !void {

View File

@@ -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); var interface = try Interface.init(device, allocator, info);
interface.vtable = &.{ interface.vtable = &.{
.allocateCommandBuffers = allocateCommandBuffers,
.destroy = destroy, .destroy = destroy,
.reset = reset, .reset = reset,
}; };
@@ -27,6 +28,12 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
return self; 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 { pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
allocator.destroy(self); allocator.destroy(self);

View File

@@ -12,6 +12,7 @@ const SoftDeviceMemory = @import("SoftDeviceMemory.zig");
const SoftFence = @import("SoftFence.zig"); const SoftFence = @import("SoftFence.zig");
const VkError = base.VkError; const VkError = base.VkError;
const NonDispatchable = base.NonDispatchable;
const Self = @This(); const Self = @This();
pub const Interface = base.Device; pub const Interface = base.Device;
@@ -34,6 +35,7 @@ pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocato
}; };
interface.dispatch_table = &.{ interface.dispatch_table = &.{
.allocateCommandBuffers = allocateCommandBuffers,
.allocateMemory = allocateMemory, .allocateMemory = allocateMemory,
.createCommandPool = createCommandPool, .createCommandPool = createCommandPool,
.createFence = createFence, .createFence = createFence,
@@ -105,6 +107,11 @@ pub fn waitForFences(_: *Interface, fences: []*base.Fence, waitForAll: bool, tim
// Command Pool functions ============================================================================================================================ // 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 { pub fn createCommandPool(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.CommandPoolCreateInfo) VkError!*base.CommandPool {
const pool = try SoftCommandPool.create(interface, allocator, info); const pool = try SoftCommandPool.create(interface, allocator, info);
return &pool.interface; return &pool.interface;

View File

@@ -21,7 +21,7 @@ host_allocator: VulkanAllocator,
vtable: *const VTable, vtable: *const VTable,
pub const VTable = struct { 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, destroy: *const fn (*Self, std.mem.Allocator) void,
reset: *const fn (*Self, vk.CommandPoolResetFlags) VkError!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, .owner = device,
.flags = info.flags, .flags = info.flags,
.queue_family_index = info.queue_family_index, .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(), .host_allocator = VulkanAllocator.from(allocator).clone(),
.first_free_buffer_index = 0, .first_free_buffer_index = 0,
.vtable = undefined, .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); return self.vtable.allocateCommandBuffers(self, info);
} }

View File

@@ -8,6 +8,7 @@ const VkError = @import("error_set.zig").VkError;
const PhysicalDevice = @import("PhysicalDevice.zig"); const PhysicalDevice = @import("PhysicalDevice.zig");
const Queue = @import("Queue.zig"); const Queue = @import("Queue.zig");
const CommandBuffer = @import("CommandBuffer.zig");
const CommandPool = @import("CommandPool.zig"); const CommandPool = @import("CommandPool.zig");
const DeviceMemory = @import("DeviceMemory.zig"); const DeviceMemory = @import("DeviceMemory.zig");
const Fence = @import("Fence.zig"); const Fence = @import("Fence.zig");
@@ -28,6 +29,7 @@ pub const VTable = struct {
}; };
pub const DispatchTable = 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, allocateMemory: *const fn (*Self, std.mem.Allocator, *const vk.MemoryAllocateInfo) VkError!*DeviceMemory,
createCommandPool: *const fn (*Self, std.mem.Allocator, *const vk.CommandPoolCreateInfo) VkError!*CommandPool, createCommandPool: *const fn (*Self, std.mem.Allocator, *const vk.CommandPoolCreateInfo) VkError!*CommandPool,
createFence: *const fn (*Self, std.mem.Allocator, *const vk.FenceCreateInfo) VkError!*Fence, 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 ============================================================================================================================ // Command Pool functions ============================================================================================================================
pub inline fn allocateCommandBuffers(self: *Self, info: *const vk.CommandPoolCreateInfo) VkError![]*CommandBuffer { pub inline fn allocateCommandBuffers(self: *Self, info: *const vk.CommandBufferAllocateInfo) VkError![]*CommandBuffer {
return self.dispatch_table.createCommandPool(self, allocator, info); return self.dispatch_table.allocateCommandBuffers(self, info);
} }
pub inline fn createCommandPool(self: *Self, allocator: std.mem.Allocator, info: *const vk.CommandPoolCreateInfo) VkError!*CommandPool { pub inline fn createCommandPool(self: *Self, allocator: std.mem.Allocator, info: *const vk.CommandPoolCreateInfo) VkError!*CommandPool {

View File

@@ -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 { pub fn deinit(self: *Self, allocator: std.mem.Allocator) VkError!void {
try self.releasePhysicalDevices(allocator); try self.releasePhysicalDevices(allocator);
try self.dispatch_table.destroyInstance(self, allocator); try self.dispatch_table.destroyInstance(self, allocator);

View File

@@ -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 { fn alloc(context: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context)); 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)); if (self.callbacks) |callbacks| {
} else { if (callbacks.pfn_allocation) |pfn_allocation| {
return getFallbackAllocator().rawAlloc(len, alignment, ret_addr); 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 { fn resize(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool {
const self: *Self = @ptrCast(@alignCast(context)); const self: *Self = @ptrCast(@alignCast(context));
if (self.callbacks != null) { return if (self.callbacks != null)
return new_len <= ptr.len; new_len <= ptr.len
} else { else
return getFallbackAllocator().rawResize(ptr, alignment, new_len, ret_addr); getFallbackAllocator().rawResize(ptr, alignment, new_len, ret_addr);
}
} }
fn remap(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8 { fn remap(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context)); const self: *Self = @ptrCast(@alignCast(context));
if (self.callbacks.?.pfn_reallocation) |pfn_reallocation| { if (self.callbacks) |callbacks| {
return @ptrCast(pfn_reallocation(self.callbacks.?.p_user_data, ptr.ptr, new_len, alignment.toByteUnits(), self.scope)); if (callbacks.pfn_reallocation) |pfn_reallocation| {
} else { 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); }
} }
return getFallbackAllocator().rawRemap(ptr, alignment, new_len, ret_addr);
} }
fn free(context: *anyopaque, ptr: []u8, alignment: Alignment, ret_addr: usize) void { fn free(context: *anyopaque, ptr: []u8, alignment: Alignment, ret_addr: usize) void {
const self: *Self = @ptrCast(@alignCast(context)); const self: *Self = @ptrCast(@alignCast(context));
if (self.callbacks.?.pfn_free) |pfn_free| { if (self.callbacks) |callbacks| {
return pfn_free(self.callbacks.?.p_user_data, ptr.ptr); if (callbacks.pfn_free) |pfn_free| {
} else { pfn_free(self.callbacks.?.p_user_data, ptr.ptr);
return getFallbackAllocator().rawFree(ptr, alignment, ret_addr); }
} }
getFallbackAllocator().rawFree(ptr, alignment, ret_addr);
} }
inline fn getFallbackAllocator() std.mem.Allocator { inline fn getFallbackAllocator() std.mem.Allocator {

View File

@@ -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 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_LOGS_ENV_NAME = "STROLL_LOGS_LEVEL";
pub const DRIVER_DEBUG_ALLOCATOR_ENV_NAME = "STROLL_DEBUG_ALLOCATOR"; pub const DRIVER_DEBUG_ALLOCATOR_ENV_NAME = "STROLL_DEBUG_ALLOCATOR";

View File

@@ -1,3 +1,5 @@
//! This file contains all exported Vulkan entrypoints.
const std = @import("std"); const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const root = @import("root"); const root = @import("root");
@@ -19,12 +21,11 @@ const Device = @import("Device.zig");
const PhysicalDevice = @import("PhysicalDevice.zig"); const PhysicalDevice = @import("PhysicalDevice.zig");
const Queue = @import("Queue.zig"); const Queue = @import("Queue.zig");
const CommandBuffer = @import("CommandBuffer.zig");
const CommandPool = @import("CommandPool.zig"); const CommandPool = @import("CommandPool.zig");
const DeviceMemory = @import("DeviceMemory.zig"); const DeviceMemory = @import("DeviceMemory.zig");
const Fence = @import("Fence.zig"); const Fence = @import("Fence.zig");
// This file contains all exported Vulkan entrypoints.
fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []const u8) void { fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []const u8) void {
if (lib.getLogVerboseLevel() != .High) return; if (lib.getLogVerboseLevel() != .High) return;
std.log.scoped(scope).err("Could not find function {s}", .{name}); 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; return .error_validation_failed;
} }
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); 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); 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; return .success;
} }