wip initial testing

This commit is contained in:
David Allemang
2026-05-27 16:02:01 -04:00
commit f3cef55647
7 changed files with 277 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.idea/
.zig-cache/
zig-out/
zig-pkg/

74
build.zig Normal file
View File

@@ -0,0 +1,74 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const vk_dep = b.dependency("vk", .{});
const volk_dep = b.dependency("volk", .{});
// const volk_c = b.addTranslateC(.{
// .target = target,
// .optimize = optimize,
// .root_source_file = volk_dep.path("volk.c"),
// .link_libc = true,
// });
// volk_c.addIncludePath(vk_dep.path("include"));
const vk = b.addModule("vulkan", .{
.target = target,
.optimize = optimize,
.root_source_file = b.path("src/volk.zig"),
.link_libc = true,
});
vk.addIncludePath(vk_dep.path("include"));
vk.addIncludePath(volk_dep.path("."));
vk.addCSourceFile(.{ .file = volk_dep.path("volk.c"), .language = .c });
const mod = b.addModule("zig_vk_api_test", .{
.root_source_file = b.path("src/root.zig"),
.target = target,
});
const exe = b.addExecutable(.{
.name = "zig_vk_api_test",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "zig_vk_api_test", .module = mod },
.{ .name = "vk", .module = vk },
},
}),
});
b.installArtifact(exe);
const run_step = b.step("run", "Run the app");
const run_cmd = b.addRunArtifact(exe);
run_step.dependOn(&run_cmd.step);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const mod_tests = b.addTest(.{
.root_module = mod,
});
const run_mod_tests = b.addRunArtifact(mod_tests);
const exe_tests = b.addTest(.{
.root_module = exe.root_module,
});
const run_exe_tests = b.addRunArtifact(exe_tests);
const test_step = b.step("test", "Run tests");
test_step.dependOn(&run_mod_tests.step);
test_step.dependOn(&run_exe_tests.step);
}

21
build.zig.zon Normal file
View File

@@ -0,0 +1,21 @@
.{
.name = .zig_vk_api_test,
.version = "0.0.0",
.fingerprint = 0xa7b5f349ba365910,
.minimum_zig_version = "0.16.0",
.dependencies = .{
.vk = .{
.url = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/v1.4.352.tar.gz",
.hash = "N-V-__8AAHAZeALsJNAOsFHuMyyXDuoFVG48EQdnJGNAZ3Th",
},
.volk = .{
.url = "https://github.com/zeux/volk/archive/refs/tags/1.4.350.tar.gz",
.hash = "N-V-__8AAFGqCADosOofL302vYn3DZNlkeErvJevsqMt-Jpa",
},
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

3
mise.toml Normal file
View File

@@ -0,0 +1,3 @@
[tools]
zig = "latest"
zls = "latest"

132
src/main.zig Normal file
View File

@@ -0,0 +1,132 @@
const std = @import("std");
const Io = std.Io;
const vk = @import("vk");
pub fn main() !void {
if (vk.c.volkInitialize() != vk.c.VK_SUCCESS) @panic("Failed to initialize vk");
defer vk.c.volkFinalize();
const app_info = vk.c.VkApplicationInfo{
.sType = vk.c.VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = null,
.apiVersion = vk.c.VK_API_VERSION_1_4,
.pApplicationName = "WIP",
.applicationVersion = vk.c.VK_MAKE_VERSION(0, 0, 1),
.pEngineName = "WIP",
.engineVersion = vk.c.VK_MAKE_VERSION(0, 0, 1),
};
const ext_names: []const [*c]const u8 = &.{"VK_EXT_debug_utils"};
const lyr_names: []const [*c]const u8 = &.{"VK_LAYER_KHRONOS_validation"};
const ins_info = vk.c.VkInstanceCreateInfo{
.sType = vk.c.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = null,
.flags = 0,
.enabledExtensionCount = @intCast(ext_names.len),
.ppEnabledExtensionNames = ext_names.ptr,
.enabledLayerCount = @intCast(lyr_names.len),
.ppEnabledLayerNames = lyr_names.ptr,
.pApplicationInfo = &app_info,
};
const deb_info = vk.c.VkDebugUtilsMessengerCreateInfoEXT{
.sType = vk.c.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = null,
.flags = 0,
};
var ins: vk.c.VkInstance = undefined;
if (vk.c.vkCreateInstance.?(&ins_info, null, &ins) != vk.c.VK_SUCCESS) @panic("Failed to create VkInstance");
vk.c.volkLoadInstanceOnly(ins);
defer vk.c.vkDestroyInstance.?(ins, null);
var pdevs: [3]vk.c.VkPhysicalDevice = undefined;
var pdev_count: u32 = 3;
if (vk.c.vkEnumeratePhysicalDevices.?(
ins,
&pdev_count,
&pdevs,
) != vk.c.VK_SUCCESS) @panic("Failed to enumerate physical devices.");
// pub const PFN_vkEnumeratePhysicalDevices = ?*const fn (instance: VkInstance, pPhysicalDeviceCount: [*c]u32, pPhysicalDevices: [*c]VkPhysicalDevice) callconv(.c) VkResult;
// vk.c.vkEnumerateDeviceExtensionProperties();
// const info = vk.c.VkInstanceCreateInfo {
// .sType = vk.c.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
// .pNext = null,
// .
// };
// vk.c.vkCreateInstance(pCreateInfo: [*c]const VkInstanceCreateInfo, pAllocator: [*c]const VkAllocationCallbacks, pInstance: [*c]VkInstance);
}
// pub fn main(init: std.process.Init) !void {
// std.debug.print("{any}\n", .{vk});
//
// // Prints to stderr, unbuffered, ignoring potential errors.
// std.debug.print("All your {s} are belong to us.\n", .{"codebase"});
//
// // This is appropriate for anything that lives as long as the process.
// const arena: std.mem.Allocator = init.arena.allocator();
//
// // Accessing command line arguments:
// const args = try init.minimal.args.toSlice(arena);
// for (args) |arg| {
// std.log.info("arg: {s}", .{arg});
// }
//
// // In order to do I/O operations need an `Io` instance.
// const io = init.io;
//
// // Stdout is for the actual output of your application, for example if you
// // are implementing gzip, then only the compressed bytes should be sent to
// // stdout, not any debugging messages.
// var stdout_buffer: [1024]u8 = undefined;
// var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
// const stdout_writer = &stdout_file_writer.interface;
//
// try zig_vk_api_test.printAnotherMessage(stdout_writer);
//
// try stdout_writer.flush(); // Don't forget to flush!
// }
//
// test "simple test" {
// const gpa = std.testing.allocator;
// var list: std.ArrayList(i32) = .empty;
// defer list.deinit(gpa); // Try commenting this out and see if zig detects the memory leak!
// try list.append(gpa, 42);
// try std.testing.expectEqual(@as(i32, 42), list.pop());
// }
//
// test "fuzz example" {
// try std.testing.fuzz({}, testOne, .{});
// }
//
// fn testOne(context: void, smith: *std.testing.Smith) !void {
// _ = context;
// // Try passing `--fuzz` to `zig build test` and see if it manages to fail this test case!
//
// const gpa = std.testing.allocator;
// var list: std.ArrayList(u8) = .empty;
// defer list.deinit(gpa);
// while (!smith.eos()) switch (smith.value(enum { add_data, dup_data })) {
// .add_data => {
// const slice = try list.addManyAsSlice(gpa, smith.value(u4));
// smith.bytes(slice);
// },
// .dup_data => {
// if (list.items.len == 0) continue;
// if (list.items.len > std.math.maxInt(u32)) return error.SkipZigTest;
// const len = smith.valueRangeAtMost(u32, 1, @min(32, list.items.len));
// const off = smith.valueRangeAtMost(u32, 0, @intCast(list.items.len - len));
// try list.appendSlice(gpa, list.items[off..][0..len]);
// try std.testing.expectEqualSlices(
// u8,
// list.items[off..][0..len],
// list.items[list.items.len - len ..],
// );
// },
// };
// }

18
src/root.zig Normal file
View File

@@ -0,0 +1,18 @@
//! By convention, root.zig is the root source file when making a package.
const std = @import("std");
const Io = std.Io;
/// This is a documentation comment to explain the `printAnotherMessage` function below.
///
/// Accepting an `Io.Writer` instance is a handy way to write reusable code.
pub fn printAnotherMessage(writer: *Io.Writer) Io.Writer.Error!void {
try writer.print("Run `zig build test` to run the tests.\n", .{});
}
pub fn add(a: i32, b: i32) i32 {
return a + b;
}
test "basic add functionality" {
try std.testing.expect(add(3, 7) == 10);
}

25
src/volk.zig Normal file
View File

@@ -0,0 +1,25 @@
const std = @import("std");
pub const c = @cImport({
@cInclude("volk.h");
});
pub const InstanceTable = blk: {
const info = @typeInfo(c.VolkInstanceTable).@"struct";
var field_names: [info.fields.len][]const u8 = undefined;
var field_types: [info.fields.len]type = undefined;
var field_attrs: [info.fields.len]std.builtin.Type.StructField.Attributes = undefined;
for (info.fields, &field_names, &field_types, &field_attrs) |field, *field_name, *field_type, *field_attr| {
field_name.* = field.name;
field_type.* = std.meta.Child(field.type);
field_attr.* = .{};
}
break :blk @Struct(.auto, null, field_names, field_types, field_attrs);
};
// pub const InstanceTable: type = {
//
// };