cleaning dispatchable handle support

This commit is contained in:
2025-11-02 02:43:38 +01:00
parent 7639c40074
commit 697b67e07a
8 changed files with 74 additions and 41 deletions

View File

@@ -94,3 +94,6 @@ q
run
bt
q
run
bt
q

View File

@@ -9,33 +9,38 @@ const Self = @This();
pub const ObjectType: vk.ObjectType = .instance;
common_instance: common.Instance,
physical_device: dispatchable.Dispatchable(PhysicalDevice), // Software driver only has one physical device (CPU)
physical_device: vk.PhysicalDevice, // Software driver only has one physical device (CPU)
pub fn create(p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_instance: *vk.Instance) callconv(vk.vulkan_call_conv) vk.Result {
const allocator = std.heap.c_allocator;
const dispatchable_object = dispatchable.Dispatchable(Self).create(allocator, ObjectType) catch return .error_out_of_host_memory;
common.Instance.init(&dispatchable_object.object.common_instance, p_infos, callbacks) catch return .error_initialization_failed;
const dispatchable_instance = dispatchable.Dispatchable(Self).create(allocator) catch return .error_out_of_host_memory;
const instance = dispatchable_instance.object;
common.Instance.init(&instance.common_instance, p_infos, callbacks) catch return .error_initialization_failed;
dispatchable_object.object.common_instance.vtable = .{
instance.common_instance.vtable = .{
.destroyInstance = destroy,
.enumeratePhysicalDevices = enumeratePhysicalDevices,
.enumerateInstanceVersion = null,
//.enumerateInstanceLayerProperties = null,
.enumerateInstanceExtensionProperties = null,
.getPhysicalDeviceProperties = PhysicalDevice.getProperties,
};
dispatchable_object.object.physical_device.init() catch return .error_initialization_failed;
const dispatchable_physical_device = dispatchable.Dispatchable(PhysicalDevice).create(allocator) catch return .error_out_of_host_memory;
PhysicalDevice.init(dispatchable_physical_device.object) catch return .error_initialization_failed;
instance.physical_device = @enumFromInt(dispatchable_physical_device.toHandle());
p_instance.* = @enumFromInt(dispatchable.toHandle(Self, dispatchable_object));
p_instance.* = @enumFromInt(dispatchable_instance.toHandle());
return .success;
}
pub fn enumeratePhysicalDevices(p_instance: vk.Instance, count: *u32, devices: *vk.PhysicalDevice) callconv(vk.vulkan_call_conv) vk.Result {
const dispatchable_object = common.dispatchable.fromHandle(Self, @intFromEnum(p_instance)) catch return .error_initialization_failed;
_ = dispatchable_object;
_ = count;
_ = devices;
pub fn enumeratePhysicalDevices(p_instance: vk.Instance, count: *u32, p_devices: ?[*]vk.PhysicalDevice) callconv(vk.vulkan_call_conv) vk.Result {
const instance = dispatchable.fromHandleObject(Self, @intFromEnum(p_instance)) catch return .error_initialization_failed;
count.* = 1;
if (p_devices) |devices| {
devices[0] = instance.physical_device;
}
return .success;
}
@@ -43,6 +48,8 @@ pub fn destroy(p_instance: vk.Instance, callbacks: ?*const vk.AllocationCallback
const allocator = std.heap.c_allocator;
_ = callbacks;
const dispatchable_object = common.dispatchable.fromHandle(Self, @intFromEnum(p_instance)) catch return;
dispatchable_object.destroy(allocator);
const dispatchable_instance = dispatchable.fromHandle(Self, @intFromEnum(p_instance)) catch return;
const dispatchable_physical_device = dispatchable.fromHandle(PhysicalDevice, @intFromEnum(dispatchable_instance.object.physical_device)) catch return;
dispatchable_physical_device.destroy(allocator);
dispatchable_instance.destroy(allocator);
}

View File

@@ -6,21 +6,28 @@ const common = @import("common");
const dispatchable = common.dispatchable;
const Self = @This();
const ObjectType: vk.ObjectType = .physical_device;
pub const ObjectType: vk.ObjectType = .physical_device;
instance: *const Instance,
common_physical_device: common.PhysicalDevice,
pub fn init(self: *Self) !void {
self.common_physical_device.props = .{
.apiVersion = ,
.driverVersion = VKD_DRIVER_VERSION,
.vendorID = 0x0601,
.deviceID = 0x060103,
.deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU,
.deviceName = {},
.pipelineCacheUUID = {},
.limits = {},
.sparseProperties = {},
.api_version = @bitCast(common.DRIVER_VULKAN_VERSION),
.driver_version = @bitCast(common.DRIVER_VERSION),
.vendor_id = 0x0601,
.device_id = 0x060103,
.device_type = .cpu,
.device_name = [_]u8{0} ** vk.MAX_PHYSICAL_DEVICE_NAME_SIZE,
.pipeline_cache_uuid = undefined,
.limits = undefined,
.sparse_properties = undefined,
};
var writer = std.io.Writer.fixed(&self.common_physical_device.props.device_name);
try writer.print("Software Vulkan Driver", .{});
}
pub fn getProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void {
const physical_device = dispatchable.fromHandleObject(Self, @intFromEnum(p_physical_device)) catch return;
properties.* = physical_device.common_physical_device.props;
}

View File

@@ -15,13 +15,7 @@ pub fn init(self: *Self, p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*co
return error.InvalidCreateInfos;
}
self.vtable = .{
.destroyInstance = null,
.enumeratePhysicalDevices = null,
.enumerateInstanceVersion = null,
//.enumerateInstanceLayerProperties = null,
.enumerateInstanceExtensionProperties = null,
};
self.vtable = .{};
if (callbacks) |c| {
self.alloc_callbacks = c.*;
@@ -37,6 +31,7 @@ pub fn getProcAddr(self: *const Self, name: []const u8) vk.PfnVoidFunction {
.{ "vkEnumeratePhysicalDevices", @ptrCast(self.vtable.enumeratePhysicalDevices) },
.{ "vkEnumerateInstanceVersion", @ptrCast(self.vtable.enumerateInstanceVersion) },
.{ "vkEnumerateInstanceExtensionProperties", @ptrCast(self.vtable.enumerateInstanceExtensionProperties) },
.{ "vkGetPhysicalDeviceProperties", @ptrCast(self.vtable.getPhysicalDeviceProperties) },
}, allocator) catch return null;
defer pfn_map.deinit(allocator);
@@ -44,9 +39,10 @@ pub fn getProcAddr(self: *const Self, name: []const u8) vk.PfnVoidFunction {
}
pub const VTable = struct {
destroyInstance: ?vk.PfnDestroyInstance,
enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices,
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion,
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties,
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties,
destroyInstance: ?vk.PfnDestroyInstance = null,
enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices = null,
enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion = null,
//enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties = null,
enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties = null,
getPhysicalDeviceProperties: ?vk.PfnGetPhysicalDeviceProperties = null,
};

View File

@@ -2,7 +2,7 @@ const vk = @import("vulkan");
const Instance = @import("Instance.zig");
const Self = @This();
const ObjectType: vk.ObjectType = .physical_device;
pub const ObjectType: vk.ObjectType = .physical_device;
props: vk.PhysicalDeviceProperties,
queue_families: [3]vk.QueueFamilyProperties,

View File

@@ -12,11 +12,11 @@ pub fn Dispatchable(comptime T: type) type {
object_type: vk.ObjectType,
object: *T,
pub fn create(allocator: std.mem.Allocator, object_type: vk.ObjectType) !*Self {
pub fn create(allocator: std.mem.Allocator) !*Self {
const object = try allocator.create(Self);
object.* = .{
.loader_data = .{ .loaderMagic = c.ICD_LOADER_MAGIC },
.object_type = object_type,
.object_type = T.ObjectType,
.object = try allocator.create(T),
};
return object;
@@ -26,6 +26,10 @@ pub fn Dispatchable(comptime T: type) type {
allocator.destroy(self.object);
allocator.destroy(self);
}
pub inline fn toHandle(self: *Self) usize {
return @intFromPtr(self);
}
};
}
@@ -40,6 +44,7 @@ pub inline fn fromHandle(comptime T: type, handle: usize) !*Dispatchable(T) {
return dispatchable;
}
pub inline fn toHandle(comptime T: type, handle: *Dispatchable(T)) usize {
return @intFromPtr(handle);
pub inline fn fromHandleObject(comptime T: type, handle: usize) !*T {
const dispatchable_handle = try fromHandle(T, handle);
return dispatchable_handle.object;
}

View File

@@ -7,6 +7,9 @@ pub const dispatchable = @import("dispatchable.zig");
pub const Instance = @import("Instance.zig");
pub const PhysicalDevice = @import("PhysicalDevice.zig");
pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1);
pub const DRIVER_VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0);
pub const std_options: std.Options = .{
.log_level = .info,
.logFn = logFn,

View File

@@ -39,10 +39,22 @@ int main(void)
#define VULKAN_INSTANCE_FUNCTION(fn) PFN_##fn fn = (PFN_##fn)vkGetInstanceProcAddr(instance, #fn);
VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)
VULKAN_INSTANCE_FUNCTION(vkDestroyInstance)
uint32_t count;
vkEnumeratePhysicalDevices(instance, &count, NULL);
printf("VkPhysicalDevice count %d\n", count);
VkPhysicalDevice* physical_devices = (VkPhysicalDevice*)calloc(count, sizeof(VkPhysicalDevice));
vkEnumeratePhysicalDevices(instance, &count, physical_devices);
VkPhysicalDeviceProperties props;
vkGetPhysicalDeviceProperties(physical_devices[0], &props);
printf("VkPhysicalDevice name %s\n", props.deviceName);
vkDestroyInstance(instance, NULL);
free(physical_devices);
dlclose(lib);
return 0;
}