From 6d559d719a9f39fd019c7d0504d2801fc98f9abe Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Wed, 29 Oct 2025 21:55:28 +0100 Subject: [PATCH] adding entry point to soft driver, adding C test --- build.zig | 21 ++++++++++++++++++++- src/soft/lib.zig | 7 ------- src/soft/libvulkan.zig | 11 +++++++++++ src/vulkan/Instance.zig | 17 ++++++++++++++--- src/vulkan/icd.zig | 24 ++++++++++++++++++++++++ src/vulkan/lib.zig | 2 ++ src/vulkan/object.zig | 4 ++-- test/c/main.c | 24 ++++++++++++++++++++++++ 8 files changed, 97 insertions(+), 13 deletions(-) delete mode 100644 src/soft/lib.zig create mode 100644 src/soft/libvulkan.zig create mode 100644 src/vulkan/icd.zig create mode 100644 test/c/main.c diff --git a/build.zig b/build.zig index 556b8f2..6dd5858 100644 --- a/build.zig +++ b/build.zig @@ -9,7 +9,7 @@ const ImplementationDesc = struct { const implementations = [_]ImplementationDesc{ .{ .name = "soft", - .root_source_file = "src/soft/lib.zig", + .root_source_file = "src/soft/libvulkan.zig", }, }; @@ -57,5 +57,24 @@ pub fn build(b: *std.Build) void { const run_tests = b.addRunArtifact(lib_tests); const test_step = b.step(b.fmt("test-{s}", .{impl.name}), b.fmt("Run lib{s} tests", .{impl.name})); test_step.dependOn(&run_tests.step); + + const c_test_exe = b.addExecutable(.{ + .name = b.fmt("c_test_vulkan_{s}", .{impl.name}), + .root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + }), + }); + + c_test_exe.root_module.addCSourceFile(.{ + .file = b.path("test/c/main.c"), + .flags = &.{b.fmt("-DLIBVK=\"{s}\"", .{lib.name})}, + }); + + const run_c_test = b.addRunArtifact(c_test_exe); + 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(b.getInstallStep()); + test_c_step.dependOn(&run_c_test.step); } } diff --git a/src/soft/lib.zig b/src/soft/lib.zig deleted file mode 100644 index c9b7231..0000000 --- a/src/soft/lib.zig +++ /dev/null @@ -1,7 +0,0 @@ -const std = @import("std"); - -const common = @import("common"); - -test { - std.testing.refAllDeclsRecursive(@This()); -} diff --git a/src/soft/libvulkan.zig b/src/soft/libvulkan.zig new file mode 100644 index 0000000..ba6e77c --- /dev/null +++ b/src/soft/libvulkan.zig @@ -0,0 +1,11 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const common = @import("common"); + +pub export fn vk_icdGetInstanceProcAddr(instance: vk.Instance, pName: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction { + if (pName == null) { + return null; + } + const name = std.mem.span(pName.?); + return common.icd.getInstanceProcAddr(instance, name); +} diff --git a/src/vulkan/Instance.zig b/src/vulkan/Instance.zig index b0d9b95..7ac810f 100644 --- a/src/vulkan/Instance.zig +++ b/src/vulkan/Instance.zig @@ -1,13 +1,24 @@ const std = @import("std"); const vk = @import("vulkan"); -const PhysicalDevice = @import("PhysicalDevice").PhysicalDevice; +const PhysicalDevice = @import("PhysicalDevice.zig").PhysicalDevice; const Object = @import("object.zig").Object; pub const Instance = extern struct { const Self = @This(); - const ObjectType: vk.ObjectType = .instance; + pub const ObjectType: vk.ObjectType = .instance; + pub const vtable: *const VTable = .{}; object: Object, - physical_devices: std.ArrayList(*PhysicalDevice), + //physical_devices: std.ArrayList(*PhysicalDevice), alloc_callbacks: vk.AllocationCallbacks, + + pub const VTable = struct { + createInstance: ?vk.PfnCreateInstance, + destroyInstance: ?vk.PfnDestroyInstance, + enumeratePhysicalDevices: ?vk.PfnEnumeratePhysicalDevices, + getInstanceProcAddr: ?vk.PfnGetInstanceProcAddr, + enumerateInstanceVersion: ?vk.PfnEnumerateInstanceVersion, + //enumerateInstanceLayerProperties: vk.PfnEnumerateInstanceProperties, + enumerateInstanceExtensionProperties: ?vk.PfnEnumerateInstanceExtensionProperties, + }; }; diff --git a/src/vulkan/icd.zig b/src/vulkan/icd.zig new file mode 100644 index 0000000..94540f1 --- /dev/null +++ b/src/vulkan/icd.zig @@ -0,0 +1,24 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const c = @cImport({ + @cInclude("vulkan/vk_icd.h"); +}); + +const Instance = @import("Instance.zig").Instance; +const fromHandle = @import("object.zig").fromHandle; + +pub fn getInstanceProcAddr(vk_instance: vk.Instance, name: []const u8) vk.PfnVoidFunction { + _ = fromHandle(Instance, vk.Instance, vk_instance) catch .{}; + + inline for (.{ + "vkCreateInstance", + "vkDestroyInstance", + "vkGetInstanceProcAddr", + }) |sym| { + if (std.mem.eql(u8, name, sym)) { + //const f = @field(Instance.vtable, sym); + return @ptrFromInt(12); + } + } + return null; +} diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index 03c0b2e..43728f7 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -1,5 +1,7 @@ const std = @import("std"); +pub const icd = @import("icd.zig"); + pub const Instance = @import("Instance.zig"); pub const PhysicalDevice = @import("PhysicalDevice.zig"); diff --git a/src/vulkan/object.zig b/src/vulkan/object.zig index e964c30..10cdc0e 100644 --- a/src/vulkan/object.zig +++ b/src/vulkan/object.zig @@ -10,7 +10,7 @@ pub const Object = extern struct { kind: vk.ObjectType, owner: ?*anyopaque, // VK_EXT_debug_utils - name: ?[]const u8, + name: ?[*]const u8, pub fn init(owner: ?*anyopaque, kind: vk.ObjectType) Self { return .{ @@ -24,7 +24,7 @@ pub const Object = extern struct { pub inline fn fromHandle(comptime T: type, comptime VkT: type, handle: VkT) !*T { comptime { - if (!@hasDecl(T, "object") or !@hasDecl(T, "ObjectType") or @TypeOf(T.ObjectType) != vk.ObjectType) { + if (!@hasField(T, "object") or !@hasDecl(T, "ObjectType") or @TypeOf(T.ObjectType) != vk.ObjectType) { @compileError("Object type \"" ++ @typeName(T) ++ "\" is malformed."); } } diff --git a/test/c/main.c b/test/c/main.c new file mode 100644 index 0000000..336f748 --- /dev/null +++ b/test/c/main.c @@ -0,0 +1,24 @@ +#include +#include + +#define VK_NO_PROTOTYPES +#include + +#include + +#ifndef LIBVK + #define LIBVK "vulkan" +#endif + +int main(void) +{ + printf("openning ./zig-out/lib/lib" LIBVK ".so\n"); + void* lib = dlopen("./zig-out/lib/lib" LIBVK ".so", RTLD_NOW | RTLD_LOCAL); + + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dlsym(lib, "vk_icdGetInstanceProcAddr"); + + printf("test %p\n", vkGetInstanceProcAddr(NULL, "vkCreateInstance")); + + dlclose(lib); + return 0; +}