diff --git a/.gdb_history b/.gdb_history index f258323..ed32b5d 100644 --- a/.gdb_history +++ b/.gdb_history @@ -94,3 +94,6 @@ q run bt q +run +bt +q diff --git a/src/soft/Instance.zig b/src/soft/Instance.zig index cb124c5..f781807 100644 --- a/src/soft/Instance.zig +++ b/src/soft/Instance.zig @@ -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); } diff --git a/src/soft/PhysicalDevice.zig b/src/soft/PhysicalDevice.zig index 2fc617d..1ee2c2e 100644 --- a/src/soft/PhysicalDevice.zig +++ b/src/soft/PhysicalDevice.zig @@ -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; } diff --git a/src/vulkan/Instance.zig b/src/vulkan/Instance.zig index b2a66ef..e53045f 100644 --- a/src/vulkan/Instance.zig +++ b/src/vulkan/Instance.zig @@ -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, }; diff --git a/src/vulkan/PhysicalDevice.zig b/src/vulkan/PhysicalDevice.zig index 7259a74..7808061 100644 --- a/src/vulkan/PhysicalDevice.zig +++ b/src/vulkan/PhysicalDevice.zig @@ -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, diff --git a/src/vulkan/dispatchable.zig b/src/vulkan/dispatchable.zig index 385af50..64802bf 100644 --- a/src/vulkan/dispatchable.zig +++ b/src/vulkan/dispatchable.zig @@ -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; } diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index acb148c..ce8a699 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -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, diff --git a/test/c/main.c b/test/c/main.c index f44a847..a441d1b 100644 --- a/test/c/main.c +++ b/test/c/main.c @@ -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; }