From 4e9fdac9b75ff7cbf9a263b4a76de0c0d098c323 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Mon, 3 Nov 2025 17:38:31 +0100 Subject: [PATCH] working on device --- src/soft/PhysicalDevice.zig | 14 +++++++++ src/soft/lib.zig | 2 ++ src/vulkan/Device.zig | 15 ++++++++++ src/vulkan/Instance.zig | 7 ++--- src/vulkan/PhysicalDevice.zig | 53 +++++++++++++++++++++++++++++++++-- src/vulkan/lib.zig | 7 +++-- test/c/main.c | 1 + 7 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 src/vulkan/Device.zig diff --git a/src/soft/PhysicalDevice.zig b/src/soft/PhysicalDevice.zig index 8e1870d..2dcd7fc 100644 --- a/src/soft/PhysicalDevice.zig +++ b/src/soft/PhysicalDevice.zig @@ -20,6 +20,20 @@ pub fn init(instance: *const base.Instance, allocator: std.mem.Allocator) !*disp base_physical_device.props.device_id = root.DEVICE_ID; base_physical_device.props.device_type = .cpu; + base_physical_device.mem_props.memory_type_count = 1; + base_physical_device.mem_props.memory_types[0] = .{ + .heap_index = 0, + .property_flags = .{ + .host_visible_bit = true, + .host_coherent_bit = true, + }, + }; + base_physical_device.mem_props.memory_heap_count = 1; + base_physical_device.mem_props.memory_heaps[0] = .{ + .size = std.process.totalSystemMemory() catch 0, + .flags = .{}, // Host memory + }; + const info = try cpuinfo.get(allocator); defer info.deinit(allocator); diff --git a/src/soft/lib.zig b/src/soft/lib.zig index 8a108c1..5fd34d1 100644 --- a/src/soft/lib.zig +++ b/src/soft/lib.zig @@ -3,6 +3,7 @@ const vk = @import("vulkan"); const base = @import("base"); const Instance = @import("Instance.zig"); +const PhysicalDevice = @import("PhysicalDevice.zig"); pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0); pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1); @@ -11,4 +12,5 @@ pub const DEVICE_ID = 0x600DCAFE; comptime { _ = base; _ = Instance; + _ = PhysicalDevice; } diff --git a/src/vulkan/Device.zig b/src/vulkan/Device.zig new file mode 100644 index 0000000..e31e516 --- /dev/null +++ b/src/vulkan/Device.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const Self = @This(); +pub const ObjectType: vk.ObjectType = .device; + +physical_device: *const PhysicalDevice, +dispatch_table: DispatchTable, +driver_data: ?*anyopaque, + +pub const DispatchTable = struct {}; + +pub fn createImplDevice(physical_device: *base.PhysicalDevice, infos: vk.DeviceCreateInfo, allocator: std.mem.Allocator) !*anyopaque { +} diff --git a/src/vulkan/Instance.zig b/src/vulkan/Instance.zig index 843b073..b82f2c7 100644 --- a/src/vulkan/Instance.zig +++ b/src/vulkan/Instance.zig @@ -4,6 +4,7 @@ const root = @import("lib.zig"); const dispatchable = @import("dispatchable.zig"); const VulkanAllocator = @import("VulkanAllocator.zig"); const PhysicalDevice = @import("PhysicalDevice.zig"); +const Dispatchable = dispatchable.Dispatchable; extern fn __vkImplInstanceInit(*Self, *const std.mem.Allocator) ?*anyopaque; @@ -17,9 +18,6 @@ driver_data: ?*anyopaque, pub const DispatchTable = struct { destroyInstance: ?*const fn (*const Self, std.mem.Allocator) anyerror!void = null, - enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion = null, - //enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties = null, - enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties = null, }; pub fn create(p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_instance: *vk.Instance) callconv(vk.vulkan_call_conv) vk.Result { @@ -32,7 +30,7 @@ pub fn create(p_infos: ?*const vk.InstanceCreateInfo, callbacks: ?*const vk.Allo const allocator = VulkanAllocator.init(deref_callbacks, .instance).allocator(); - const dispatchable_instance = dispatchable.Dispatchable(Self).create(allocator) catch return .error_out_of_host_memory; + const dispatchable_instance = Dispatchable(Self).create(allocator) catch return .error_out_of_host_memory; const self = dispatchable_instance.object; self.dispatch_table = .{}; @@ -76,7 +74,6 @@ pub fn getProcAddr(name: []const u8) vk.PfnVoidFunction { const pfn_map = std.StaticStringMap(vk.PfnVoidFunction).init([_]KV{ .{ "vkDestroyInstance", @ptrCast(&destroy) }, .{ "vkEnumeratePhysicalDevices", @ptrCast(&enumeratePhysicalDevices) }, - //.{ "vkGetPhysicalDeviceProperties", @ptrCast(self.dispatch_table.getPhysicalDeviceProperties) }, }, allocator) catch return null; defer pfn_map.deinit(allocator); diff --git a/src/vulkan/PhysicalDevice.zig b/src/vulkan/PhysicalDevice.zig index fcfb2f2..a85d992 100644 --- a/src/vulkan/PhysicalDevice.zig +++ b/src/vulkan/PhysicalDevice.zig @@ -2,20 +2,27 @@ const std = @import("std"); const vk = @import("vulkan"); const root = @import("lib.zig"); const Instance = @import("Instance.zig"); +const Device = @import("Device.zig"); const dispatchable = @import("dispatchable.zig"); +const VulkanAllocator = @import("VulkanAllocator.zig"); + +const Dispatchable = dispatchable.Dispatchable; const Self = @This(); pub const ObjectType: vk.ObjectType = .physical_device; props: vk.PhysicalDeviceProperties, +mem_props: vk.PhysicalDeviceMemoryProperties, instance: *const Instance, dispatch_table: DispatchTable, driver_data: ?*anyopaque, -pub const DispatchTable = struct {}; +pub const DispatchTable = struct { + createImplDevice: ?*const fn (*Self, vk.DeviceCreateInfo, std.mem.Allocator) anyerror!?*anyopaque, +}; -pub fn init(instance: *const Instance, allocator: std.mem.Allocator) !*dispatchable.Dispatchable(Self) { - const dispatchable_physical_device = try dispatchable.Dispatchable(Self).create(allocator); +pub fn init(instance: *const Instance, allocator: std.mem.Allocator) !*Dispatchable(Self) { + const dispatchable_physical_device = try Dispatchable(Self).create(allocator); errdefer dispatchable_physical_device.destroy(allocator); const self = dispatchable_physical_device.object; @@ -32,6 +39,13 @@ pub fn init(instance: *const Instance, allocator: std.mem.Allocator) !*dispatcha .sparse_properties = undefined, }; + self.mem_props = .{ + .memory_type_count = 0, + .memory_types = undefined, + .memory_heap_count = 0, + .memory_heaps = undefined, + }; + self.driver_data = null; self.instance = instance; self.dispatch_table = .{}; @@ -39,17 +53,50 @@ pub fn init(instance: *const Instance, allocator: std.mem.Allocator) !*dispatcha return dispatchable_physical_device; } +pub fn createDevice(p_physical_device: vk.PhysicalDevice, p_infos: ?*const vk.DeviceCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_device: *vk.Device) callconv(vk.vulkan_call_conv) vk.Result { + const infos = p_infos orelse return .error_initialization_failed; + if (infos.s_type != .device_create_info) { + return .error_initialization_failed; + } + + const self = dispatchable.fromHandleObject(Self, @intFromEnum(p_physical_device)) catch return .error_unknown; + + const deref_callbacks = if (callbacks) |c| c.* else null; + + const allocator = VulkanAllocator.init(deref_callbacks, .instance).allocator(); + + const dispatchable_device = Dispatchable(Device).create(allocator) catch return .error_out_of_host_memory; + const device = dispatchable_device.object; + device.dispatch_table = .{}; + + if (self.dispatch_table.createImplDevice) |pfnCreateImplDevice| { + device.driver_data = pfnCreateImplDevice(self, infos, allocator) catch return .error_initialization_failed; + } else if (std.process.hasEnvVar(allocator, root.DRIVER_LOGS_ENV_NAME) catch false) { + std.log.scoped(.vkCreateDevice).warn("Missing dispatch implementation", .{}); + } + + p_device.* = @enumFromInt(dispatchable_device.toHandle()); + return .success; +} + pub fn getProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void { const self = dispatchable.fromHandleObject(Self, @intFromEnum(p_physical_device)) catch return; properties.* = self.props; } +pub fn getMemoryProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceMemoryProperties) callconv(vk.vulkan_call_conv) void { + const self = dispatchable.fromHandleObject(Self, @intFromEnum(p_physical_device)) catch return; + properties.* = self.mem_props; +} + pub fn getProcAddr(name: []const u8) vk.PfnVoidFunction { const allocator = std.heap.c_allocator; const KV = struct { []const u8, vk.PfnVoidFunction }; const pfn_map = std.StaticStringMap(vk.PfnVoidFunction).init([_]KV{ + .{ "vkCreateDevice", @ptrCast(&createDevice) }, .{ "vkGetPhysicalDeviceProperties", @ptrCast(&getProperties) }, + .{ "vkGetPhysicalDeviceMemoryProperties", @ptrCast(&getMemoryProperties) }, }, allocator) catch return null; defer pfn_map.deinit(allocator); diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index 214cf90..6a4f63e 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -7,6 +7,7 @@ pub const dispatchable = @import("dispatchable.zig"); pub const Instance = @import("Instance.zig"); pub const PhysicalDevice = @import("PhysicalDevice.zig"); pub const VulkanAllocator = @import("VulkanAllocator.zig"); +pub const Device = @import("Device.zig"); pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1; pub const DRIVER_LOGS_ENV_NAME = "DRIVER_LOGS"; @@ -40,11 +41,11 @@ const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ .{ "vkCreateInstance", @as(vk.PfnVoidFunction, @ptrCast(&Instance.create)) }, }); -pub export fn vkGetInstanceProcAddr(p_instance: vk.Instance, pName: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction { - if (pName == null) { +pub export fn vkGetInstanceProcAddr(p_instance: vk.Instance, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction { + if (p_name == null) { return null; } - const name = std.mem.span(pName.?); + const name = std.mem.span(p_name.?); return icd.getInstanceProcAddr(global_pfn_map, p_instance, name); } diff --git a/test/c/main.c b/test/c/main.c index b1cb463..fb0d2ee 100644 --- a/test/c/main.c +++ b/test/c/main.c @@ -45,6 +45,7 @@ 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(vkGetPhysicalDeviceMemoryProperties) VULKAN_INSTANCE_FUNCTION(vkDestroyInstance) uint32_t count;