diff --git a/build.zig b/build.zig index bded306..0317b85 100644 --- a/build.zig +++ b/build.zig @@ -73,9 +73,34 @@ pub fn build(b: *std.Build) void { .use_pkg_config = .force, }); exe_unit_tests.linkLibC(); - const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); + const dsa_unit_tests = b.addTest(.{ + .name = "dsa.zig tests", + .root_source_file = .{ .path = "src/dsa.zig" }, + .target = target, + .optimize = optimize, + }); + const run_dsa_unit_tests = b.addRunArtifact(dsa_unit_tests); + const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&run_exe_unit_tests.step); + test_step.dependOn(&run_dsa_unit_tests.step); + + const inspect = b.addExecutable(.{ + .name = "vkinspect", + .root_source_file = .{ .path = "src/inspect.zig" }, + .target = target, + .optimize = optimize, + }); + inspect.linkSystemLibrary2("vulkan", .{ + .needed = true, + .preferred_link_mode = .dynamic, + }); + exe_unit_tests.linkLibC(); + inspect.root_module.addImport("vk", vkmod); + inspect.linkLibC(); + const run_inspect = b.addRunArtifact(inspect); + const inspect_step = b.step("vki", "Vulkan Inspect"); + inspect_step.dependOn(&run_inspect.step); } diff --git a/src/dsa.zig b/src/dsa.zig new file mode 100644 index 0000000..83153af --- /dev/null +++ b/src/dsa.zig @@ -0,0 +1,59 @@ +const std = @import("std"); + +/// Slices must be sorted. Checks if `a` includes all elements of `b`. +pub fn includes(comptime T: type, a: []const T, b: []const T) bool { + var ia: usize = 0; + var ib: usize = 0; + + while (ib != b.len) { + if (ia == a.len) return false; + if (b[ib] < a[ia]) return false; + if (!(a[ia] < b[ib])) ib += 1; + ia += 1; + } + return true; +} + +test includes { + try std.testing.expect(includes( + usize, + &.{}, + &.{}, + )); + try std.testing.expect(includes( + usize, + &.{ 1, 2, 3, 4, 5 }, + &.{}, + )); + try std.testing.expect(includes( + usize, + &.{ 1, 2, 3, 4, 5 }, + &.{ 1, 2, 3, 4, 5 }, + )); + try std.testing.expect(!includes( + usize, + &.{}, + &.{ 1, 2, 3, 4, 5 }, + )); + + try std.testing.expect(includes( + usize, + &.{ 1, 2, 2, 4 }, + &.{ 2, 2 }, + )); + try std.testing.expect(includes( + usize, + &.{ 1, 2, 2, 4 }, + &.{ 1, 2, 2, 4 }, + )); + try std.testing.expect(!includes( + usize, + &.{ 1, 2, 2, 4 }, + &.{ 2, 2, 2 }, + )); + try std.testing.expect(!includes( + usize, + &.{ 1, 2, 2, 4 }, + &.{ 2, 2, 3 }, + )); +} diff --git a/src/inspect.zig b/src/inspect.zig new file mode 100644 index 0000000..7f936d2 --- /dev/null +++ b/src/inspect.zig @@ -0,0 +1,63 @@ +const std = @import("std"); +const vk = @import("vk"); + +const BaseWrapper = vk.BaseWrapper(.{ + .getInstanceProcAddr = true, + .createInstance = true, +}); + +const InstanceWrapper = vk.InstanceWrapper(.{ + .destroyInstance = true, + .enumeratePhysicalDevices = true, + .getPhysicalDeviceProperties = true, + .getPhysicalDeviceQueueFamilyProperties = true, +}); + +extern fn vkGetInstanceProcAddr(instance: vk.Instance, procname: [*:0]const u8) vk.PfnVoidFunction; +extern fn vkGetDeviceProcAddr(device: vk.Device, procname: [*:0]const u8) vk.PfnVoidFunction; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const ally = gpa.allocator(); + + const vkb = try BaseWrapper.load(vkGetInstanceProcAddr); + + const instance = try vkb.createInstance(&.{ + .p_application_info = &.{ + .p_application_name = "vkinspect", + .application_version = 0, + .p_engine_name = "vkinspect", + .engine_version = 0, + .api_version = vk.API_VERSION_1_3, + }, + .enabled_extension_count = 0, + .enabled_layer_count = 0, + }, null); + const vki = try InstanceWrapper.load(instance, vkGetInstanceProcAddr); + defer vki.destroyInstance(instance, null); + + var pdev_count: u32 = undefined; + _ = try vki.enumeratePhysicalDevices(instance, &pdev_count, null); + const pdevs = try ally.alloc(vk.PhysicalDevice, pdev_count); + defer ally.free(pdevs); + _ = try vki.enumeratePhysicalDevices(instance, &pdev_count, pdevs.ptr); + + std.debug.print("{d} physical devices:\n", .{pdev_count}); + for (pdevs) |pdev| { + const props = vki.getPhysicalDeviceProperties(pdev); + const name = std.mem.sliceTo(&props.device_name, 0); + std.debug.print("- {s}\n", .{name}); + + var family_count: u32 = undefined; + vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null); + const families = try ally.alloc(vk.QueueFamilyProperties, family_count); + defer ally.free(families); + vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, families.ptr); + + std.debug.print(" {d} queue families:\n", .{family_count}); + for (families) |family| { + std.debug.print(" - {any}\n", .{family.queue_flags}); + std.debug.print(" (max {d})\n", .{family.queue_count}); + } + } +}