first steps towards porting to 0.16
This commit is contained in:
parent
e1b960da37
commit
e99779fcbc
9 changed files with 65 additions and 61 deletions
39
build.zig
39
build.zig
|
|
@ -25,6 +25,10 @@ pub fn build(b: *std.Build) void {
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
});
|
});
|
||||||
rendering.addIncludePath(b.path("ext"));
|
rendering.addIncludePath(b.path("ext"));
|
||||||
|
if (target.result.os.tag == .macos) {
|
||||||
|
rendering.addSystemIncludePath(.{ .cwd_relative = "/usr/local/include" });
|
||||||
|
rendering.addLibraryPath(.{ .cwd_relative = "/usr/local/lib" });
|
||||||
|
}
|
||||||
rendering.addCSourceFile(.{ .file = b.path("ext/stb_image.c") });
|
rendering.addCSourceFile(.{ .file = b.path("ext/stb_image.c") });
|
||||||
rendering.addImport("math", math);
|
rendering.addImport("math", math);
|
||||||
|
|
||||||
|
|
@ -45,8 +49,12 @@ pub fn build(b: *std.Build) void {
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
sideros.addIncludePath(b.path("ext"));
|
sideros.root_module.addIncludePath(b.path("ext"));
|
||||||
sideros.addIncludePath(b.path("src"));
|
sideros.root_module.addIncludePath(b.path("src"));
|
||||||
|
if (target.result.os.tag == .macos) {
|
||||||
|
sideros.root_module.addSystemIncludePath(.{ .cwd_relative = "/usr/local/include" });
|
||||||
|
sideros.root_module.addLibraryPath(.{ .cwd_relative = "/usr/local/lib" });
|
||||||
|
}
|
||||||
|
|
||||||
sideros.root_module.addImport("mods", mods);
|
sideros.root_module.addImport("mods", mods);
|
||||||
sideros.root_module.addImport("ecs", ecs);
|
sideros.root_module.addImport("ecs", ecs);
|
||||||
|
|
@ -71,18 +79,18 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
exe.root_module.addIncludePath(b.path("src"));
|
exe.root_module.addIncludePath(b.path("src"));
|
||||||
exe.linkLibrary(sideros);
|
exe.root_module.linkLibrary(sideros);
|
||||||
exe.linkLibC();
|
exe.root_module.link_libc = true;
|
||||||
exe.linkSystemLibrary("vulkan");
|
exe.root_module.linkSystemLibrary("vulkan", .{ .needed = true });
|
||||||
if (wayland) {
|
if (wayland) {
|
||||||
exe.root_module.addIncludePath(b.path("ext"));
|
exe.root_module.addIncludePath(b.path("ext"));
|
||||||
exe.linkSystemLibrary("wayland-client");
|
exe.root_module.linkSystemLibrary("wayland-client", .{});
|
||||||
exe.linkSystemLibrary("xkbcommon");
|
exe.root_module.linkSystemLibrary("xkbcommon", .{});
|
||||||
exe.root_module.addCSourceFile(.{ .file = b.path("ext/xdg-shell.c") });
|
exe.root_module.addCSourceFile(.{ .file = b.path("ext/xdg-shell.c") });
|
||||||
} else {
|
} else {
|
||||||
exe.linkSystemLibrary("xcb");
|
exe.root_module.linkSystemLibrary("xcb", .{});
|
||||||
exe.linkSystemLibrary("xcb-keysyms");
|
exe.root_module.linkSystemLibrary("xcb-keysyms", .{});
|
||||||
exe.linkSystemLibrary("xcb-icccm");
|
exe.root_module.linkSystemLibrary("xcb-icccm", .{});
|
||||||
}
|
}
|
||||||
b.installArtifact(exe);
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
|
@ -106,14 +114,14 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
exe.root_module.addIncludePath(b.path("src"));
|
exe.root_module.addIncludePath(b.path("src"));
|
||||||
exe.linkSystemLibrary("vulkan");
|
exe.root_module.linkSystemLibrary("vulkan", .{});
|
||||||
exe.root_module.addSystemIncludePath(.{ .cwd_relative = "/usr/local/include" });
|
exe.root_module.addSystemIncludePath(.{ .cwd_relative = "/usr/local/include" });
|
||||||
exe.root_module.addLibraryPath(.{ .cwd_relative = "/usr/local/lib" });
|
exe.root_module.addLibraryPath(.{ .cwd_relative = "/usr/local/lib" });
|
||||||
exe.root_module.addCSourceFile(.{.file = b.path("src/window.m")});
|
exe.root_module.addCSourceFile(.{.file = b.path("src/window.m")});
|
||||||
exe.root_module.linkFramework("Cocoa", .{});
|
exe.root_module.linkFramework("Cocoa", .{});
|
||||||
exe.root_module.linkFramework("Metal", .{});
|
exe.root_module.linkFramework("Metal", .{});
|
||||||
exe.root_module.linkFramework("QuartzCore", .{});
|
exe.root_module.linkFramework("QuartzCore", .{});
|
||||||
exe.linkLibrary(sideros);
|
exe.root_module.linkLibrary(sideros);
|
||||||
b.installArtifact(exe);
|
b.installArtifact(exe);
|
||||||
|
|
||||||
const run_cmd = b.addRunArtifact(exe);
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
|
|
@ -156,13 +164,10 @@ pub fn build(b: *std.Build) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compileAllShaders(b: *std.Build, module: *std.Build.Module) void {
|
fn compileAllShaders(b: *std.Build, module: *std.Build.Module) void {
|
||||||
const shaders_dir = if (@hasDecl(@TypeOf(b.build_root.handle), "openIterableDir"))
|
const shaders_dir = b.build_root.handle.openDir(b.graph.io, "assets/shaders", .{ .iterate = true }) catch @panic("Failed to open shaders directory");
|
||||||
b.build_root.handle.openIterableDir("assets/shaders", .{}) catch @panic("Failed to open shaders directory")
|
|
||||||
else
|
|
||||||
b.build_root.handle.openDir("assets/shaders", .{ .iterate = true }) catch @panic("Failed to open shaders directory");
|
|
||||||
|
|
||||||
var file_it = shaders_dir.iterate();
|
var file_it = shaders_dir.iterate();
|
||||||
while (file_it.next() catch @panic("Failed to iterate shader directory")) |entry| {
|
while (file_it.next(b.graph.io) catch @panic("Failed to iterate shader directory")) |entry| {
|
||||||
if (entry.kind == .file) {
|
if (entry.kind == .file) {
|
||||||
const ext = std.fs.path.extension(entry.name);
|
const ext = std.fs.path.extension(entry.name);
|
||||||
const basename = std.fs.path.basename(entry.name);
|
const basename = std.fs.path.basename(entry.name);
|
||||||
|
|
|
||||||
|
|
@ -33,27 +33,20 @@ pub const Pool = struct {
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
system_groups: std.ArrayList(SystemGroup),
|
system_groups: std.ArrayList(SystemGroup),
|
||||||
sync_groups: std.ArrayList(SyncGroup),
|
sync_groups: std.ArrayList(SyncGroup),
|
||||||
thread_pool: *std.Thread.Pool,
|
threaded_io: std.Io.Threaded,
|
||||||
wait_group: std.Thread.WaitGroup,
|
|
||||||
mutex: std.Thread.Mutex,
|
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, resources: *Resources) !@This() {
|
pub fn init(allocator: Allocator, resources: *Resources) !@This() {
|
||||||
var pool = @This(){
|
const pool = @This(){
|
||||||
.humans = .{},
|
.humans = .{},
|
||||||
.resources = resources,
|
.resources = resources,
|
||||||
.system_groups = std.ArrayList(SystemGroup).empty,
|
.system_groups = std.ArrayList(SystemGroup).empty,
|
||||||
.sync_groups = std.ArrayList(SystemGroup).empty,
|
.sync_groups = std.ArrayList(SystemGroup).empty,
|
||||||
.thread_pool = try allocator.create(std.Thread.Pool),
|
.threaded_io = .init(allocator, .{
|
||||||
.wait_group = .{},
|
.concurrent_limit = .limited(4),
|
||||||
.mutex = .{},
|
}),
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
try pool.thread_pool.init(.{
|
|
||||||
.allocator = allocator,
|
|
||||||
.n_jobs = 4,
|
|
||||||
});
|
|
||||||
|
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,28 +63,37 @@ pub const Pool = struct {
|
||||||
|
|
||||||
self.system_groups.deinit(self.allocator);
|
self.system_groups.deinit(self.allocator);
|
||||||
self.sync_groups.deinit(self.allocator);
|
self.sync_groups.deinit(self.allocator);
|
||||||
self.thread_pool.deinit();
|
self.threaded_io.deinit();
|
||||||
self.allocator.destroy(self.thread_pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(self: *@This()) void {
|
pub fn tick(self: *@This()) void {
|
||||||
|
const io = self.threaded_io.io();
|
||||||
|
var group: std.Io.Group = .init;
|
||||||
|
|
||||||
for (0..self.system_groups.items.len) |i| {
|
for (0..self.system_groups.items.len) |i| {
|
||||||
self.thread_pool.spawnWg(&self.wait_group, struct {
|
group.concurrent(io, struct {
|
||||||
fn run(pool: *Pool, index: usize) void {
|
fn run(pool: *Pool, index: usize) std.Io.Cancelable!void {
|
||||||
const group = pool.system_groups.items[index];
|
const system_group = pool.system_groups.items[index];
|
||||||
for (group) |system| {
|
for (system_group) |system| {
|
||||||
// TODO: system errors should be correctly handled
|
// TODO: system errors should be correctly handled
|
||||||
system(pool) catch unreachable;
|
system(pool) catch unreachable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.run, .{ self, i });
|
}.run, .{ self, i }) catch {
|
||||||
|
const system_group = self.system_groups.items[i];
|
||||||
|
for (system_group) |system| {
|
||||||
|
system(self) catch unreachable;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
for (0..self.sync_groups.items.len) |i| {
|
for (0..self.sync_groups.items.len) |i| {
|
||||||
const group = self.sync_groups.items[i];
|
const system_group = self.sync_groups.items[i];
|
||||||
for (group) |system| {
|
for (system_group) |system| {
|
||||||
system(self) catch unreachable;
|
system(self) catch unreachable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group.await(io) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getEntities(self: *@This(), T: type) *std.MultiArrayList(T) {
|
fn getEntities(self: *@This(), T: type) *std.MultiArrayList(T) {
|
||||||
|
|
|
||||||
|
|
@ -149,18 +149,18 @@ fn vulkan_cleanup(gameInit: sideros.GameInit) void {
|
||||||
//c.vkDestroyInstance(gameInit.instance, null);
|
//c.vkDestroyInstance(gameInit.instance, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main(init: std.process.Init) !void {
|
||||||
create_window();
|
create_window();
|
||||||
const layer = get_metal_layer();
|
const layer = get_metal_layer();
|
||||||
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa: std.heap.DebugAllocator(.{}) = .init;
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
defer if (gpa.deinit() != .ok) @panic("Memory leaked");
|
defer if (gpa.deinit() != .ok) @panic("Memory leaked");
|
||||||
|
|
||||||
const gameInit = try vulkan_init(allocator, layer);
|
const gameInit = try vulkan_init(allocator, layer);
|
||||||
defer vulkan_cleanup(gameInit);
|
defer vulkan_cleanup(gameInit);
|
||||||
|
|
||||||
sideros.sideros_init(gameInit);
|
sideros.sideros_init(init.io, gameInit);
|
||||||
|
|
||||||
while (!is_window_closed()) {
|
while (!is_window_closed()) {
|
||||||
poll_cocoa_events();
|
poll_cocoa_events();
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,9 @@ const DIndex = packed struct {
|
||||||
x: u32,
|
x: u32,
|
||||||
y: u32,
|
y: u32,
|
||||||
};
|
};
|
||||||
comptime {
|
|
||||||
// TODO: is this too big? we could do with 32 bits and a bit more indirection
|
/// This intentionally remains tagless; the opcode determines how to interpret it.
|
||||||
std.debug.assert(@sizeOf(Index) == 8);
|
const Index = union {
|
||||||
}
|
|
||||||
/// packed union has no tag
|
|
||||||
const Index = packed union {
|
|
||||||
u32: u32,
|
u32: u32,
|
||||||
i32: i32,
|
i32: i32,
|
||||||
u64: u64,
|
u64: u64,
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ pub const Builder = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addMesh(self: *Builder, path: []const u8) !Mesh {
|
pub fn addMesh(self: *Builder, io: std.Io, path: []const u8) !Mesh {
|
||||||
const gltf_data = try gltf.parseFile(self.allocator, path);
|
const gltf_data = try gltf.parseFile(self.allocator, io, path);
|
||||||
|
|
||||||
const vertex_buffer = try createVertexBuffer(self.allocator, self.device, gltf_data);
|
const vertex_buffer = try createVertexBuffer(self.allocator, self.device, gltf_data);
|
||||||
const index_buffer = try createIndexBuffer(self.allocator, self.device, gltf_data);
|
const index_buffer = try createIndexBuffer(self.allocator, self.device, gltf_data);
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ terrain_pipeline: vk.TerrainPipeline,
|
||||||
current_frame: u32,
|
current_frame: u32,
|
||||||
mesh: Mesh,
|
mesh: Mesh,
|
||||||
transforms: std.ArrayList(math.Transform),
|
transforms: std.ArrayList(math.Transform),
|
||||||
previous_time: std.time.Instant,
|
previous_time: std.Io.Timestamp,
|
||||||
current_image: usize,
|
current_image: usize,
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_handle: vk.c.VkSurfaceKHR) !Self {
|
pub fn init(allocator: Allocator, io: std.Io, instance_handle: vk.c.VkInstance, surface_handle: vk.c.VkSurfaceKHR) !Self {
|
||||||
const instance: vk.Instance = .{ .handle = instance_handle };
|
const instance: vk.Instance = .{ .handle = instance_handle };
|
||||||
const surface: vk.Surface = .{ .handle = surface_handle };
|
const surface: vk.Surface = .{ .handle = surface_handle };
|
||||||
var physical_device = try vk.PhysicalDevice.pick(allocator, instance);
|
var physical_device = try vk.PhysicalDevice.pick(allocator, instance);
|
||||||
|
|
@ -48,7 +48,7 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand
|
||||||
_ = try pipeline_builder.addTexture(texture, diffuse);
|
_ = try pipeline_builder.addTexture(texture, diffuse);
|
||||||
_ = try pipeline_builder.addTexture(texture, diffuse);
|
_ = try pipeline_builder.addTexture(texture, diffuse);
|
||||||
|
|
||||||
const mesh = try pipeline_builder.addMesh("assets/models/cube.glb");
|
const mesh = try pipeline_builder.addMesh(io, "assets/models/cube.glb");
|
||||||
var graphics_pipeline = try pipeline_builder.build(swapchain, render_pass, vertex_shader, fragment_shader);
|
var graphics_pipeline = try pipeline_builder.build(swapchain, render_pass, vertex_shader, fragment_shader);
|
||||||
|
|
||||||
const terrain_vertex_shader = try device.initShader("terrain_vert");
|
const terrain_vertex_shader = try device.initShader("terrain_vert");
|
||||||
|
|
@ -96,7 +96,7 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand
|
||||||
.terrain_pipeline = terrain_pipeline,
|
.terrain_pipeline = terrain_pipeline,
|
||||||
.current_frame = 0,
|
.current_frame = 0,
|
||||||
.transforms = transforms,
|
.transforms = transforms,
|
||||||
.previous_time = try std.time.Instant.now(),
|
.previous_time = std.Io.Timestamp.now(std.Io.Threaded.global_single_threaded.io(), .awake),
|
||||||
.mesh = mesh,
|
.mesh = mesh,
|
||||||
.current_image = undefined,
|
.current_image = undefined,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -161,8 +161,8 @@ pub const Model = struct {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parseFile(allocator: Allocator, name: []const u8) !struct { vertices: [][3]f32, normals: [][3]f32, uvs: [][2]f32, indices: []u16 } {
|
pub fn parseFile(allocator: Allocator, io: std.Io, name: []const u8) !struct { vertices: [][3]f32, normals: [][3]f32, uvs: [][2]f32, indices: []u16 } {
|
||||||
const file = try std.fs.cwd().openFile(name, .{});
|
const file = try std.Io.Dir.cwd().openFile(name, io, .{});
|
||||||
const all = try file.readToEndAlloc(allocator, 1_000_000);
|
const all = try file.readToEndAlloc(allocator, 1_000_000);
|
||||||
defer allocator.free(all);
|
defer allocator.free(all);
|
||||||
const json_chunk = std.mem.bytesAsValue(Model.Chunk, all[Model.Header.offset..]);
|
const json_chunk = std.mem.bytesAsValue(Model.Chunk, all[Model.Header.offset..]);
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const std = @import("std");
|
||||||
|
|
||||||
const systems = @import("systems.zig");
|
const systems = @import("systems.zig");
|
||||||
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa: std.heap.DebugAllocator(.{}) = .{};
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
var pool: ecs.Pool = undefined;
|
var pool: ecs.Pool = undefined;
|
||||||
var renderer: Renderer = undefined;
|
var renderer: Renderer = undefined;
|
||||||
|
|
@ -26,7 +26,7 @@ const ModInfo = struct {
|
||||||
runtime: *mods.Runtime,
|
runtime: *mods.Runtime,
|
||||||
modIdx: u32,
|
modIdx: u32,
|
||||||
};
|
};
|
||||||
var loadedMods: std.ArrayListUnmanaged(ModInfo) = .{};
|
var loadedMods: std.ArrayListUnmanaged(ModInfo) = .empty;
|
||||||
|
|
||||||
fn openOrCreateDir(fs: std.fs.Dir, path: []const u8) !std.fs.Dir {
|
fn openOrCreateDir(fs: std.fs.Dir, path: []const u8) !std.fs.Dir {
|
||||||
var dir: std.fs.Dir = undefined;
|
var dir: std.fs.Dir = undefined;
|
||||||
|
|
@ -133,7 +133,7 @@ fn init_mods() void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn sideros_init(init: api.GameInit) callconv(.c) void {
|
fn sideros_init(io: std.Io, init: api.GameInit) void {
|
||||||
resources = .{
|
resources = .{
|
||||||
.camera = &camera,
|
.camera = &camera,
|
||||||
.renderer = undefined,
|
.renderer = undefined,
|
||||||
|
|
@ -145,7 +145,7 @@ export fn sideros_init(init: api.GameInit) callconv(.c) void {
|
||||||
ecs.hooks.addHook(.scroll, systems.zoomCamera) catch @panic("TODO handle this");
|
ecs.hooks.addHook(.scroll, systems.zoomCamera) catch @panic("TODO handle this");
|
||||||
pool = ecs.Pool.init(allocator, &resources) catch @panic("TODO: Gracefully handle error");
|
pool = ecs.Pool.init(allocator, &resources) catch @panic("TODO: Gracefully handle error");
|
||||||
// TODO(ernesto): I think this @ptrCast are unavoidable but maybe not?
|
// TODO(ernesto): I think this @ptrCast are unavoidable but maybe not?
|
||||||
renderer = Renderer.init(allocator, @ptrCast(init.instance), @ptrCast(init.surface)) catch |err| std.debug.panic("TODO: Gracefully handle error: {}\n", .{err});
|
renderer = Renderer.init(allocator, io, @ptrCast(init.instance), @ptrCast(init.surface)) catch |err| std.debug.panic("TODO: Gracefully handle error: {}\n", .{err});
|
||||||
|
|
||||||
resources.terrain = rendering.Terrain.init(allocator, renderer.device, .{
|
resources.terrain = rendering.Terrain.init(allocator, renderer.device, .{
|
||||||
.octaves = 8,
|
.octaves = 8,
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ pub fn render(pool: *ecs.Pool) anyerror!void {
|
||||||
const camera = pool.resources.camera;
|
const camera = pool.resources.camera;
|
||||||
const terrain = pool.resources.terrain;
|
const terrain = pool.resources.terrain;
|
||||||
|
|
||||||
const now = try std.time.Instant.now();
|
const now = std.Io.Timestamp.now(pool.threaded_io.io(), .awake);
|
||||||
const delta_time: f32 = @as(f32, @floatFromInt(now.since(renderer.previous_time))) / @as(f32, 1_000_000_000.0);
|
const delta_time: f32 = @as(f32, @floatFromInt(renderer.previous_time.durationTo(now).toNanoseconds())) / @as(f32, 1_000_000_000.0);
|
||||||
pool.resources.delta_time = delta_time;
|
pool.resources.delta_time = delta_time;
|
||||||
renderer.previous_time = now;
|
renderer.previous_time = now;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue