minimal vulkan + glfw

This commit is contained in:
David Allemang
2024-03-20 17:09:27 -04:00
commit 90f3ecda90
6 changed files with 27068 additions and 0 deletions

44
.gitignore vendored Normal file
View File

@@ -0,0 +1,44 @@
*.d
*.slo
*.lo
*.o
*.obj
*.gch
*.pch
*.so
*.dylib
*.dll
*.mod
*.smod
*.lai
*.la
*.a
*.lib
*.exe
*.out
*.app
*.ko
*.elf
*.ilk
*.map
*.exp
*.so.*
*.i*86
*.x86_64
*.hex
*.dSYM/
*.su
*.idb
*.pdb
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
zig-cache/
zig-out/
build/
build-*/
docgen_tmp/

53
build.zig Normal file
View File

@@ -0,0 +1,53 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const vk = b.dependency("vulkan-zig", .{
.registry = @as([]const u8, b.pathFromRoot("reg/vk.xml")),
});
const vkmod = vk.module("vulkan-zig");
const exe = b.addExecutable(.{
.name = "scratchzig",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
// this requires PKG_CONFIG_PATH to be set. something like:
// ~/.local/lib/pkgconfig/
exe.linkSystemLibrary2("glfw3", .{
.needed = true,
.preferred_link_mode = .static,
.use_pkg_config = .force,
});
exe.linkLibC();
b.installArtifact(exe);
exe.root_module.addImport("vk", vkmod);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_exe_unit_tests.step);
}

15
build.zig.zon Normal file
View File

@@ -0,0 +1,15 @@
.{
.name = "scratchzig",
.version = "0.0.0",
.dependencies = .{
.@"vulkan-zig" = .{
.url = "https://github.com/Snektron/vulkan-zig/archive/ac4103a733c479b599aae8d42c08cabd7d5cf48a.tar.gz",
.hash = "122085abbcfa0328f5f6e0e702d25ee0a61bb92d0ce9ba415a2fea1d33f43129cb66",
},
},
.paths = .{
"",
},
}

26856
reg/vk.xml Normal file

File diff suppressed because it is too large Load Diff

25
src/c.zig Normal file
View File

@@ -0,0 +1,25 @@
pub usingnamespace @cImport({
@cDefine("GLFW_INCLUDE_NONE", {});
@cInclude("GLFW/glfw3.h");
});
const vk = @import("vk");
const c = @This();
pub extern fn glfwGetInstanceProcAddress(
instance: vk.Instance,
procname: [*:0]const u8,
) vk.PfnVoidFunction;
pub extern fn glfwGetPhysicalDevicePresentationSupport(
instance: vk.Instance,
pdev: vk.PhysicalDevice,
queuefamily: u32,
) c_int;
pub extern fn glfwCreateWindowSurface(
instance: vk.Instance,
window: *c.GLFWwindow,
allocation_callbacks: ?*const vk.AllocationCallbacks,
surface: *vk.SurfaceKHR,
) vk.Result;

75
src/main.zig Normal file
View File

@@ -0,0 +1,75 @@
const std = @import("std");
const c = @import("c.zig");
const vk = @import("vk");
const BaseDispatch = vk.BaseWrapper(.{
.createInstance = true,
.getInstanceProcAddr = true,
});
const InstanceDispatch = vk.InstanceWrapper(.{
.destroyInstance = true,
});
const Context = struct {
vkb: BaseDispatch,
vki: InstanceDispatch,
instance: vk.Instance,
pub fn init(allocator: std.mem.Allocator, app_name: [*:0]const u8, window: *c.GLFWwindow) !Context {
_ = allocator;
_ = window;
var self: Context = undefined;
self.vkb = try BaseDispatch.load(c.glfwGetInstanceProcAddress);
var glfw_exts_count: u32 = 0;
const glfw_exts = c.glfwGetRequiredInstanceExtensions(&glfw_exts_count);
const app_info = vk.ApplicationInfo{
.p_application_name = app_name,
.application_version = vk.makeApiVersion(0, 0, 0, 0),
.p_engine_name = app_name,
.engine_version = vk.makeApiVersion(0, 0, 0, 0),
.api_version = vk.API_VERSION_1_2,
};
self.instance = try self.vkb.createInstance(&.{
.p_application_info = &app_info,
.enabled_extension_count = glfw_exts_count,
.pp_enabled_extension_names = @as([*]const [*:0]const u8, @ptrCast(glfw_exts)),
}, null);
self.vki = try InstanceDispatch.load(self.instance, self.vkb.dispatch.vkGetInstanceProcAddr);
errdefer self.vki.destroyInstance(self.instance, null);
return self;
}
pub fn deinit(self: Context) void {
self.vki.destroyInstance(self.instance, null);
}
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
if (c.glfwInit() != c.GLFW_TRUE) {
return error.GlfwInitFailed;
}
defer c.glfwTerminate();
const window: *c.GLFWwindow = c.glfwCreateWindow(1280, 720, "Hello World!", null, null) orelse return error.GlfwWindowFailed;
defer c.glfwDestroyWindow(window);
const ctx = try Context.init(allocator, "content", window);
defer ctx.deinit();
while (c.glfwWindowShouldClose(window) == 0) : (c.glfwPollEvents()) {
c.glfwSwapBuffers(window);
}
}