diff --git a/build.zig b/build.zig index f6eb36e..556b8f2 100644 --- a/build.zig +++ b/build.zig @@ -13,62 +13,49 @@ const implementations = [_]ImplementationDesc{ }, }; -pub fn build(b: *std.Build) !void { +pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const libvulkan_mod = b.createModule(.{ + const common_mod = b.createModule(.{ .root_source_file = b.path("src/vulkan/lib.zig"), .target = target, .optimize = optimize, }); + const vulkan_headers = b.dependency("vulkan_headers", .{}); + const vulkan = b.dependency("vulkan_zig", .{ - .registry = b.dependency("vulkan_headers", .{}).path("registry/vk.xml"), + .registry = vulkan_headers.path("registry/vk.xml"), }).module("vulkan-zig"); - libvulkan_mod.addImport("vulkan", vulkan); - - const libvulkan = b.addLibrary(.{ - .name = "vulkan", - .root_module = libvulkan_mod, - .linkage = .dynamic, - }); - - b.installArtifact(libvulkan); + common_mod.addImport("vulkan", vulkan); + common_mod.addSystemIncludePath(vulkan_headers.path("include")); for (implementations) |impl| { - b.installArtifact(try buildImplementation(b, target, optimize, &impl, vulkan)); + const lib_mod = b.createModule(.{ + .root_source_file = b.path(impl.root_source_file), + .target = target, + .optimize = optimize, + .imports = &.{ + .{ .name = "common", .module = common_mod }, + .{ .name = "vulkan", .module = vulkan }, + }, + }); + + lib_mod.addSystemIncludePath(vulkan_headers.path("include")); + + const lib = b.addLibrary(.{ + .name = b.fmt("vulkan_{s}", .{impl.name}), + .root_module = lib_mod, + .linkage = .dynamic, + }); + b.installArtifact(lib); + + const lib_tests = b.addTest(.{ .root_module = lib_mod }); + + 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 libvulkan_tests = b.addTest(.{ - .root_module = libvulkan_mod, - }); - - const run_libvulkan_tests = b.addRunArtifact(libvulkan_tests); - - const test_step = b.step("test", "Run tests"); - test_step.dependOn(&run_libvulkan_tests.step); -} - -fn buildImplementation( - b: *std.Build, - target: std.Build.ResolvedTarget, - optimize: std.builtin.OptimizeMode, - desc: *const ImplementationDesc, - vulkan_bindings: *std.Build.Module, -) !*Step.Compile { - const lib_mod = b.createModule(.{ - .root_source_file = b.path(desc.root_source_file), - .target = target, - .optimize = optimize, - }); - - lib_mod.addImport("vulkan", vulkan_bindings); - - return b.addLibrary(.{ - .name = try std.fmt.allocPrint(b.allocator, "vulkan_{s}", .{desc.name}), - .root_module = lib_mod, - .linkage = .dynamic, - }); } diff --git a/src/soft/lib.zig b/src/soft/lib.zig index e69de29..c9b7231 100644 --- a/src/soft/lib.zig +++ b/src/soft/lib.zig @@ -0,0 +1,7 @@ +const std = @import("std"); + +const common = @import("common"); + +test { + std.testing.refAllDeclsRecursive(@This()); +} diff --git a/src/vulkan/Instance.zig b/src/vulkan/Instance.zig new file mode 100644 index 0000000..6677dbc --- /dev/null +++ b/src/vulkan/Instance.zig @@ -0,0 +1,9 @@ +const vk = @import("vulkan"); +const Object = @import("object.zig").Object; + +pub const Instance = extern struct { + const Self = @This(); + const ObjectType: vk.ObjectType = .instance; + + object: Object, +}; diff --git a/src/vulkan/Object.zig b/src/vulkan/Object.zig deleted file mode 100644 index e69de29..0000000 diff --git a/src/vulkan/PhysicalDevice.zig b/src/vulkan/PhysicalDevice.zig new file mode 100644 index 0000000..2e8e945 --- /dev/null +++ b/src/vulkan/PhysicalDevice.zig @@ -0,0 +1,14 @@ +const vk = @import("vulkan"); +const Instance = @import("Instance.zig").Instance; +const Object = @import("object.zig").Object; + +pub const PhysicalDevice = extern struct { + const Self = @This(); + const ObjectType: vk.ObjectType = .physical_device; + + object: Object, + + instance: *Instance, + props: vk.PhysicalDeviceProperties, + queue_families: [3]vk.QueueFamilyProperties, +}; diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index e69de29..03c0b2e 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -0,0 +1,8 @@ +const std = @import("std"); + +pub const Instance = @import("Instance.zig"); +pub const PhysicalDevice = @import("PhysicalDevice.zig"); + +test { + std.testing.refAllDeclsRecursive(@This()); +} diff --git a/src/vulkan/object.zig b/src/vulkan/object.zig new file mode 100644 index 0000000..b12cb48 --- /dev/null +++ b/src/vulkan/object.zig @@ -0,0 +1,42 @@ +const vk = @import("vulkan"); +const c = @cImport({ + @cInclude("vulkan/vk_icd.h"); +}); + +pub const Object = extern struct { + const Self = @This(); + + loader_data: c.VK_LOADER_DATA, + kind: vk.ObjectType, + owner: ?*anyopaque, + // VK_EXT_debug_utils + name: ?[]const u8, + + pub fn init(owner: ?*anyopaque, kind: vk.ObjectType) Self { + return .{ + .loader_data = c.ICD_LOADER_MAGIC, + .kind = kind, + .owner = owner, + .name = null, + }; + } +}; + +pub inline fn fromHandle(comptime T: type, comptime VkT: type, handle: VkT) !*T { + if (handle == .null_handle) { + return error.NullHandle; + } + + if (!@hasDecl(T, "object")) { + return error.NotAnObject; + } + if (!@hasDecl(T, "ObjectType") || @TypeOf(T.ObjectType) != vk.ObjectType) { + @panic("Object type \"" ++ @typeName(T) ++ "\" is malformed."); + } + + const dispatchable: *T = @ptrFromInt(@intFromEnum(handle)); + if (dispatchable.object.kind != T.ObjectType) { + return error.InvalidObjectType; + } + return dispatchable; +}