diff --git a/build.zig b/build.zig index c23f4de..1fa459e 100644 --- a/build.zig +++ b/build.zig @@ -14,19 +14,11 @@ pub fn build(b: *std.Build) void { const cimgui = b.dependency("cimgui", .{}); - const nu = b.addModule("nu", .{ - .root_source_file = b.path("src/nu.zig"), - .target = target, - .optimize = optimize, - .link_libc = true, - }); - nu.addImport("cimgui", cimgui.module("cimgui")); - nu.addImport("vk", vkmod); - nu.linkSystemLibrary("glfw3", .{ - .needed = true, - .preferred_link_mode = .static, - .use_pkg_config = .force, - }); + // nu.linkSystemLibrary("glfw3", .{ + // .needed = true, + // .preferred_link_mode = .static, + // .use_pkg_config = .force, + // }); const exe = b.addExecutable(.{ .name = "scratchzig", @@ -34,9 +26,15 @@ pub fn build(b: *std.Build) void { .target = target, .optimize = optimize, }); - exe.root_module.addImport("nu", nu); + // exe.root_module.addImport("nu", nu); exe.root_module.addImport("vk", vkmod); exe.root_module.addImport("cimgui", cimgui.module("cimgui")); + exe.root_module.linkSystemLibrary("glfw3", .{ + .needed = true, + .preferred_link_mode = .static, + .use_pkg_config = .force, + }); + exe.linkLibC(); const shaders = vkgen.ShaderCompileStep.create( b, @@ -59,42 +57,6 @@ pub fn build(b: *std.Build) void { const run_step = b.step("run", "Run the app"); run_step.dependOn(&run_cmd.step); - const nu_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/nu.zig"), - .target = target, - .optimize = optimize, - }); - nu_unit_tests.root_module.addImport("cimgui", cimgui.module("cimgui")); - nu_unit_tests.root_module.addImport("vk", vkmod); - nu_unit_tests.root_module.linkSystemLibrary("glfw3", .{ - .needed = true, - .preferred_link_mode = .static, - .use_pkg_config = .force, - }); - nu_unit_tests.linkLibC(); - - const nu_test_runner = b.addInstallArtifact(nu_unit_tests, .{ - .dest_dir = .{ .override = .{ .custom = "dev" } }, - .dest_sub_path = "nu_test_runner", - }); - - const devel_step = b.step("dev", "Build development tools and test runners"); - devel_step.dependOn(&nu_test_runner.step); - - // const exe_unit_tests = b.addTest(.{ - // .root_source_file = b.path("src/main.zig"), - // .target = target, - // .optimize = optimize, - // }); - // exe_unit_tests.linkSystemLibrary2("glfw3", .{ - // .needed = true, - // .preferred_link_mode = .static, - // .use_pkg_config = .force, - // }); - // exe_unit_tests.linkLibC(); - // 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); - // test_step.dependOn(&run_nu_unit_tests.step); + // const devel_step = b.step("dev", "Build development tools and test runners"); + // devel_step.dependOn(&nu_test_runner.step); } diff --git a/src/Uber.zig b/src/Uber.zig index 702aa3c..efde228 100644 --- a/src/Uber.zig +++ b/src/Uber.zig @@ -2,8 +2,11 @@ const std = @import("std"); const vk = @import("vk"); const shaders = @import("shaders"); +const nu = @import("nu.zig"); const Self = @This(); +const ctx = nu.Render.ctx; + set_layout: vk.DescriptorSetLayout, layout: vk.PipelineLayout, pipeline: vk.Pipeline, @@ -50,34 +53,34 @@ pub const Vertex = extern struct { }; pub fn init(cache: vk.PipelineCache) !Self { - const vert = try au.D.createShaderModule(&.{ + const vert = try ctx.D.createShaderModule(&.{ .code_size = shaders.triangle_vert.len, .p_code = @ptrCast(&shaders.triangle_vert), }, null); - defer au.D.destroyShaderModule(vert, null); + defer ctx.D.destroyShaderModule(vert, null); - const frag = try au.D.createShaderModule(&.{ + const frag = try ctx.D.createShaderModule(&.{ .code_size = shaders.triangle_frag.len, .p_code = @ptrCast(&shaders.triangle_frag), }, null); - defer au.D.destroyShaderModule(frag, null); + defer ctx.D.destroyShaderModule(frag, null); - const set_layout = try au.D.createDescriptorSetLayout(&vk.DescriptorSetLayoutCreateInfo{ + const set_layout = try ctx.D.createDescriptorSetLayout(&vk.DescriptorSetLayoutCreateInfo{ .flags = .{}, .binding_count = @intCast(Uniform.Bindings.len), .p_bindings = &Uniform.Bindings, }, null); - errdefer au.D.destroyDescriptorSetLayout(set_layout, null); + errdefer ctx.D.destroyDescriptorSetLayout(set_layout, null); - const layout = try au.D.createPipelineLayout(&vk.PipelineLayoutCreateInfo{ + const layout = try ctx.D.createPipelineLayout(&vk.PipelineLayoutCreateInfo{ .push_constant_range_count = 0, .set_layout_count = 1, .p_set_layouts = &.{set_layout}, }, null); - errdefer au.D.destroyPipelineLayout(layout, null); + errdefer ctx.D.destroyPipelineLayout(layout, null); var pipeline: vk.Pipeline = .null_handle; - _ = try au.D.createGraphicsPipelines(cache, 1, &[1]vk.GraphicsPipelineCreateInfo{ + _ = try ctx.D.createGraphicsPipelines(cache, 1, &[1]vk.GraphicsPipelineCreateInfo{ vk.GraphicsPipelineCreateInfo{ .stage_count = 2, .p_stages = &.{ @@ -152,20 +155,20 @@ pub fn init(cache: vk.PipelineCache) !Self { }, .p_next = &vk.PipelineRenderingCreateInfo{ .color_attachment_count = 1, - .p_color_attachment_formats = &.{au.device_config.format.format}, + .p_color_attachment_formats = &.{nu.Render.sc.cinfo.image_format}, .depth_attachment_format = .undefined, .stencil_attachment_format = .undefined, .view_mask = 0, }, }, }, null, @ptrCast(&pipeline)); - errdefer au.D.destroyPipeline(pipeline, null); + errdefer ctx.D.destroyPipeline(pipeline, null); return .{ .pipeline = pipeline, .layout = layout, .set_layout = set_layout }; } pub fn deinit(self: Self) void { - au.D.destroyPipeline(self.pipeline, null); - au.D.destroyPipelineLayout(self.layout, null); - au.D.destroyDescriptorSetLayout(self.set_layout, null); + ctx.D.destroyPipeline(self.pipeline, null); + ctx.D.destroyPipelineLayout(self.layout, null); + ctx.D.destroyDescriptorSetLayout(self.set_layout, null); } diff --git a/src/main.zig b/src/main.zig index 17627fb..e61048f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,86 +1,219 @@ const std = @import("std"); const nu = @import("nu.zig"); +const Uber = @import("Uber.zig"); -pub const nu_modules = .{ - App, - // UI, -}; +pub const nu_modules = .{@This()}; pub const main = nu.main; -pub const nu_options: nu.Options = .{ - .window = .{ .title = "Hello World" }, +pub const nu_config: nu.Config = .{ + .window = nu.Window.Config{ + .title = "au", + }, .render = .{ - .app_name = "hello-world", - .frames_in_flight = 3, + .app_name = "au", + .frames_in_flight = 2, }, }; -// pub const UI = struct { -// const im = nu.ImGui; -// -// pub const depends = .{im}; -// -// var color: @Vector(4, f32) = @splat(1); -// -// pub fn setup(_: std.mem.Allocator) !void { -// const io: *nu.ImGui.ImGuiIO = @ptrCast(nu.ImGui.igGetIO()); -// io.ConfigFlags |= nu.ImGui.ImGuiConfigFlags_DockingEnable; -// } -// -// pub fn frame() !void { -// nu.ImGui.igShowMetricsWindow(null); -// -// { -// const viewport = im.igGetMainViewport(); -// im.igSetNextWindowPos(viewport.*.WorkPos, 0, .{ .x = 0, .y = 0 }); -// im.igSetNextWindowSize(viewport.*.WorkSize, 0); -// im.igSetNextWindowViewport(viewport.*.ID); -// im.igPushStyleVar_Float(im.ImGuiStyleVar_WindowRounding, 0); -// im.igPushStyleVar_Float(im.ImGuiStyleVar_WindowBorderSize, 0); -// im.igPushStyleVar_Vec2(im.ImGuiStyleVar_WindowPadding, .{ .x = 0, .y = 0 }); -// defer im.igPopStyleVar(3); -// -// const window_flags = -// im.ImGuiWindowFlags_MenuBar | -// im.ImGuiWindowFlags_NoDocking | -// im.ImGuiWindowFlags_NoTitleBar | -// im.ImGuiWindowFlags_NoCollapse | -// im.ImGuiWindowFlags_NoResize | -// im.ImGuiWindowFlags_NoMove | -// im.ImGuiWindowFlags_NoBringToFrontOnFocus | -// im.ImGuiWindowFlags_NoNavFocus | -// im.ImGuiWindowFlags_NoBackground; -// -// const dock_flags = -// im.ImGuiDockNodeFlags_PassthruCentralNode | -// im.ImGuiDockNodeFlags_NoDockingOverCentralNode; -// -// _ = im.igBegin("Main Dockspace", null, window_flags); -// const id = im.igGetID_Str("maindockspace"); -// _ = im.igDockSpace(id, .{ .x = 0, .y = 0 }, dock_flags, null); -// im.igEnd(); -// } -// -// if (nu.ImGui.igBegin("Color", null, nu.ImGui.ImGuiWindowFlags_None)) { -// if (nu.ImGui.igColorEdit4("color", @ptrCast(&color), nu.ImGui.ImGuiColorEditFlags_AlphaPreviewHalf)) {} -// } -// nu.ImGui.igEnd(); -// } -// }; +const im = nu.ImGui; +const ctx = nu.Render.ctx; +const vk = @import("vk"); -const App = struct { - const vk = @import("vk"); - // const au = @import("nu/Render/au.zig"); +pub const depends = .{nu.ImGui}; - pub const depends = .{nu.Render}; - - // todo timeline semaphore - - pub fn setup(_: std.mem.Allocator) !void {} - - pub fn teardown() void {} - - pub fn frame() !void {} - - // pub fn present(_: au.CommandBufferProxy) void {} +const vertices: []const Uber.Vertex = &.{ + .{ .pos = .{ 0.0, 0.0, 0.0, 1.0 }, .color = .{ 1.0, 1.0, 0.0 } }, + .{ .pos = .{ 1.0, 0.0, 0.0, 1.0 }, .color = .{ 1.0, 0.0, 1.0 } }, + .{ .pos = .{ 0.0, 1.0, 0.0, 1.0 }, .color = .{ 0.0, 1.0, 1.0 } }, + .{ .pos = .{ 1.0, 1.0, 0.0, 1.0 }, .color = .{ 1.0, 1.0, 1.0 } }, }; + +const Index = u16; +const indices: []const Index = &.{ + 1, 0, 2, + 2, 3, 1, +}; + +const uniform: Uber.Uniform = .{ + .mat = .{ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + }, +}; + +var mem: vk.DeviceMemory = .null_handle; +var vbo: vk.Buffer = .null_handle; +var ibo: vk.Buffer = .null_handle; +var ubo: vk.Buffer = .null_handle; + +var pool: vk.DescriptorPool = .null_handle; +var descriptor_set: vk.DescriptorSet = .null_handle; + +var cache: vk.PipelineCache = .null_handle; +var uber: Uber = undefined; + +pub fn setup(_: std.mem.Allocator) !void { + errdefer teardown(); + const props = ctx.I.getPhysicalDeviceMemoryProperties(ctx.pdevice.*); + const memory_type_index: u32 = for (0..props.memory_type_count) |idx| { + const t = props.memory_types[idx]; + if (t.property_flags.host_coherent_bit and t.property_flags.host_visible_bit) { + break @intCast(idx); + } + } else { + unreachable; + }; + + const SIZE = 0x10000; + mem = try ctx.D.allocateMemory(&vk.MemoryAllocateInfo{ + .allocation_size = SIZE, + .memory_type_index = memory_type_index, + }, null); + + const raw: [*]u8 = @ptrCast(try ctx.D.mapMemory(mem, 0, vk.WHOLE_SIZE, .{}) orelse unreachable); + errdefer ctx.D.unmapMemory(mem); + + // todo VMA. This doesn't work for some reason to do with alignment. + // var fba = std.heap.FixedBufferAllocator.init(raw[0..SIZE]); + // const aa = fba.allocator(); + + var bump: usize = 0; + + const vbytes = std.mem.sliceAsBytes(vertices); + vbo = try ctx.D.createBuffer(&vk.BufferCreateInfo{ + .queue_family_index_count = 1, + .p_queue_family_indices = &.{ctx.family.*}, + .sharing_mode = .exclusive, + .size = vbytes.len, + .usage = .{ .vertex_buffer_bit = true }, + }, null); + const vreq = ctx.D.getBufferMemoryRequirements(vbo); + bump = std.mem.alignForward(usize, bump, vreq.alignment); + @memcpy(raw + bump, vbytes); + try ctx.D.bindBufferMemory(vbo, mem, bump); + bump += vreq.size; + + const ibytes = std.mem.sliceAsBytes(indices); + ibo = try ctx.D.createBuffer(&vk.BufferCreateInfo{ + .queue_family_index_count = 1, + .p_queue_family_indices = &.{ctx.family.*}, + .sharing_mode = .exclusive, + .size = ibytes.len, + .usage = .{ .index_buffer_bit = true }, + }, null); + const ireq = ctx.D.getBufferMemoryRequirements(ibo); + bump = std.mem.alignForward(usize, bump, ireq.alignment); + @memcpy(raw + bump, ibytes); + try ctx.D.bindBufferMemory(ibo, mem, bump); + bump += ireq.size; + + const ubytes = std.mem.asBytes(&uniform); + ubo = try ctx.D.createBuffer(&vk.BufferCreateInfo{ + .queue_family_index_count = 1, + .p_queue_family_indices = &.{ctx.family.*}, + .sharing_mode = .exclusive, + .size = ubytes.len, + .usage = .{ .uniform_buffer_bit = true }, + }, null); + const ureq = ctx.D.getBufferMemoryRequirements(ubo); + bump = std.mem.alignForward(usize, bump, ureq.alignment); + @memcpy(raw + bump, ubytes); + try ctx.D.bindBufferMemory(ubo, mem, bump); + bump += ureq.size; + + cache = try ctx.D.createPipelineCache(&vk.PipelineCacheCreateInfo{}, null); + + uber = try Uber.init(cache); + + const pool_sizes: []const vk.DescriptorPoolSize = &.{vk.DescriptorPoolSize{ + .descriptor_count = 8, + .type = .uniform_buffer, + }}; + + pool = try ctx.D.createDescriptorPool(&vk.DescriptorPoolCreateInfo{ + .flags = .{ .free_descriptor_set_bit = true }, + .pool_size_count = @intCast(pool_sizes.len), + .p_pool_sizes = pool_sizes.ptr, + .max_sets = 32, + }, null); + + var sets: [1]vk.DescriptorSet = .{.null_handle}; + try ctx.D.allocateDescriptorSets(&vk.DescriptorSetAllocateInfo{ + .descriptor_pool = pool, + .descriptor_set_count = 1, + .p_set_layouts = &.{uber.set_layout}, + }, &sets); + descriptor_set = sets[0]; + + ctx.D.updateDescriptorSets( + 1, + &.{ + vk.WriteDescriptorSet{ + .dst_set = descriptor_set, + .dst_binding = 0, + .dst_array_element = 0, + .descriptor_count = 1, + .descriptor_type = .uniform_buffer, + .p_buffer_info = &.{ + vk.DescriptorBufferInfo{ + .buffer = ubo, + .offset = 0, + .range = vk.WHOLE_SIZE, + }, + }, + .p_image_info = undefined, + .p_texel_buffer_view = undefined, + }, + }, + 0, + null, + ); +} + +pub fn teardown() void { + ctx.Q.waitIdle() catch {}; + uber.deinit(); + ctx.D.destroyPipelineCache(cache, null); + ctx.D.destroyBuffer(ubo, null); + ctx.D.destroyBuffer(ibo, null); + ctx.D.destroyBuffer(vbo, null); + ctx.D.freeMemory(mem, null); + ctx.D.freeDescriptorSets(pool, 1, &.{descriptor_set}) catch unreachable; + ctx.D.destroyDescriptorPool(pool, null); +} + +pub fn frame() !void { + im.igShowMetricsWindow(null); +} + +pub fn present(cmd: ctx.CommandBufferProxy) void { + const w, const h = nu.Window.size(); + + cmd.bindPipeline(.graphics, uber.pipeline); + cmd.setScissor(0, 1, &.{vk.Rect2D{ + .offset = .{ .x = 0, .y = 0 }, + .extent = .{ .width = w, .height = h }, + }}); + cmd.setViewport(0, 1, &.{vk.Viewport{ + .x = 0, + .y = 0, + .width = @floatFromInt(w), + .height = @floatFromInt(h), + .min_depth = 0, + .max_depth = 1, + }}); + cmd.bindIndexBuffer(ibo, 0, .uint16); + cmd.bindVertexBuffers(0, 1, &.{vbo}, &.{0}); + cmd.bindDescriptorSets( + .graphics, + uber.layout, + 0, + 1, + &.{descriptor_set}, + 0, + null, + ); + cmd.drawIndexed(@intCast(indices.len), 1, 0, 0, 0); +} diff --git a/src/nu.zig b/src/nu.zig index 88c0a4b..27695a4 100644 --- a/src/nu.zig +++ b/src/nu.zig @@ -3,11 +3,12 @@ const root = @import("root"); pub const Window = @import("nu/Window.zig"); pub const Render = @import("nu/Render.zig"); -// pub const ImGui = @import("nu/ImGui.zig"); +pub const ImGui = @import("nu/ImGui.zig"); +pub const ctx = @import("nu/Render/ctx.zig"); -pub const Bus = @import("nu/Bus.zig"); +// pub const Bus = @import("nu/Bus.zig"); -const Config = struct { +pub const Config = struct { window: Window.Config = .{}, render: Render.Config = .{}, }; @@ -52,6 +53,7 @@ pub fn Engine(comptime D: type, comptime R: type, comptime M: anytype) type { return R.render(); } + // todo remove this pub fn try_invoke(comptime name: []const u8, args: anytype) !void { inline for (modules) |mod| { if (@hasDecl(mod, name)) { @@ -68,6 +70,7 @@ pub fn Engine(comptime D: type, comptime R: type, comptime M: anytype) type { } } + // todo remove this pub fn try_rinvoke(comptime name: []const u8, args: anytype) !void { comptime var it = std.mem.reverseIterator(modules); inline while (it.next()) |mod| { diff --git a/src/nu/ImGui.zig b/src/nu/ImGui.zig index 38e1caf..07a94a0 100644 --- a/src/nu/ImGui.zig +++ b/src/nu/ImGui.zig @@ -17,7 +17,7 @@ const config = nu.config.imgui; pub const depends = .{ Render, Window }; pub fn loader_wrapper(procname: [*c]const u8, _: ?*anyopaque) callconv(.C) vk.PfnVoidFunction { - return nu.glfwGetInstanceProcAddress(nu.I.handle, procname); + return Render.ctx.glfwGetInstanceProcAddress(Render.ctx.instance.*, procname); } var ctx: *im.ImGuiContext = undefined; @@ -38,8 +38,7 @@ pub fn setup(_: std.mem.Allocator) !void { } errdefer im.impl.ImGui_ImplGlfw_Shutdown(); - descriptor_pool = try Render.ctx.dw.createDescriptorPool( - Render.ctx.device, + descriptor_pool = try Render.ctx.D.createDescriptorPool( &vk.DescriptorPoolCreateInfo{ .flags = .{ .free_descriptor_set_bit = true }, .pool_size_count = 1, @@ -51,24 +50,24 @@ pub fn setup(_: std.mem.Allocator) !void { }, null, ); - errdefer Render.ctx.dw.destroyDescriptorPool(Render.ctx.device, descriptor_pool, null); + errdefer Render.ctx.D.destroyDescriptorPool(descriptor_pool, null); if (im.impl.ImGui_ImplVulkan_Init(@constCast(&im.impl.ImGui_ImplVulkan_InitInfo{ - .Instance = @ptrFromInt(@intFromEnum(Render.ctx.instance)), - .PhysicalDevice = @ptrFromInt(@intFromEnum(Render.ctx.pdevice)), - .Device = @ptrFromInt(@intFromEnum(Render.ctx.device)), - .QueueFamily = au.device_config.family, // todo - .Queue = @ptrFromInt(@intFromEnum(au.Q.handle)), // todo + .Instance = @ptrFromInt(@intFromEnum(Render.ctx.instance.*)), + .PhysicalDevice = @ptrFromInt(@intFromEnum(Render.ctx.pdevice.*)), + .Device = @ptrFromInt(@intFromEnum(Render.ctx.device.*)), + .QueueFamily = Render.ctx.family.*, // todo + .Queue = @ptrFromInt(@intFromEnum(Render.ctx.Q.handle)), // todo .DescriptorPool = @ptrFromInt(@intFromEnum(descriptor_pool)), .RenderPass = null, .MinImageCount = 2, - .ImageCount = @intCast(nu.config.render.frames_in_flight), + .ImageCount = @intCast(Render.sc.frames_in_flight), .PipelineRenderingCreateInfo = @bitCast(vk.PipelineRenderingCreateInfo{ .view_mask = 0, .depth_attachment_format = .undefined, .stencil_attachment_format = .undefined, .color_attachment_count = 1, - .p_color_attachment_formats = &.{au.device_config.format.format}, // todo + .p_color_attachment_formats = &.{Render.sc.cinfo.image_format}, // todo }), .MSAASamples = 0, .PipelineCache = null, @@ -86,9 +85,9 @@ pub fn setup(_: std.mem.Allocator) !void { } pub fn teardown() void { - Render.ctx.dw.deviceWaitIdle(Render.ctx.device) catch |err| std.debug.panic("Device wait failed: {!}", .{err}); + Render.ctx.D.deviceWaitIdle() catch |err| std.debug.panic("Device wait failed: {!}", .{err}); im.impl.ImGui_ImplVulkan_Shutdown(); - Render.ctx.dw.destroyDescriptorPool(Render.ctx.device, descriptor_pool, null); + Render.ctx.D.destroyDescriptorPool(descriptor_pool, null); im.impl.ImGui_ImplGlfw_Shutdown(); im.igDestroyContext(ctx); } @@ -99,7 +98,7 @@ pub fn frame() !void { im.igNewFrame(); } -pub fn present(cmd: au.CommandBufferProxy) void { // todo +pub fn rpresent(cmd: Render.ctx.CommandBufferProxy) void { // todo im.igEndFrame(); im.igRender(); diff --git a/src/nu/Render.zig b/src/nu/Render.zig index 5960530..fd868d2 100644 --- a/src/nu/Render.zig +++ b/src/nu/Render.zig @@ -8,7 +8,8 @@ const vk = @import("vk"); const nu = @import("../nu.zig"); -const ctx = @import("Render/ctx.zig"); +pub const ctx = @import("Render/ctx.zig"); + const SwapChain = @import("Render/SwapChain.zig"); pub const Config = struct { @@ -30,6 +31,7 @@ pub const Config = struct { .Debug, .ReleaseSafe => true, .ReleaseSmall, .ReleaseFast => false, }, + frames_in_flight: u8 = 2, }; const config = nu.config.render; @@ -70,17 +72,17 @@ const Flight = struct { } }; +pub const sc: *const SwapChain = &_sc; + var _sc: SwapChain = undefined; -var _flights: []Flight = undefined; +var _flights: [nu.config.render.frames_in_flight]Flight = undefined; pub fn setup(alloc: std.mem.Allocator) !void { try ctx.init(alloc); errdefer ctx.deinit(); - _flights = try alloc.alloc(Flight, 3); - errdefer alloc.free(_flights); errdefer for (_flights) |flight| flight.deinit(); - for (_flights) |*flight| flight.* = try Flight.init(); + for (&_flights) |*flight| flight.* = try Flight.init(); _sc = try SwapChain.init(alloc, _flights.len); errdefer _sc.deinit(); @@ -143,6 +145,9 @@ pub fn render() !void { }, }); + nu.engine.invoke("present", .{cmd}); + nu.engine.rinvoke("rpresent", .{cmd}); + cmd.endRendering(); cmd.pipelineBarrier( diff --git a/src/nu/Render/SwapChain.zig b/src/nu/Render/SwapChain.zig index 183eedb..01356e4 100644 --- a/src/nu/Render/SwapChain.zig +++ b/src/nu/Render/SwapChain.zig @@ -96,6 +96,7 @@ const View = struct { alloc: std.mem.Allocator, +frames_in_flight: u32, flight_index: usize = 0, flight_syncs: std.MultiArrayList(Sync) = .{}, @@ -104,13 +105,14 @@ handle: vk.SwapchainKHR = .null_handle, chain: std.MultiArrayList(View) = .{}, -pub fn init(alloc: std.mem.Allocator, flight_count: usize) !Self { +pub fn init(alloc: std.mem.Allocator, frames_in_flight: usize) !Self { var self: Self = .{ .alloc = alloc, + .frames_in_flight = @intCast(frames_in_flight), }; errdefer self.deinit(); - try self.flight_syncs.resize(alloc, flight_count); + try self.flight_syncs.resize(alloc, frames_in_flight); for (self.flight_syncs.items(.acquired)) |*sem| sem.* = try ctx.D.createSemaphore(&.{}, null); for (self.flight_syncs.items(.complete)) |*sem| @@ -275,11 +277,11 @@ pub fn present(self: *Self, target: Target) !void { .p_swapchains = &.{self.handle}, .p_image_indices = &.{target.image_index}, .p_results = null, - })) |res| switch(res) { + })) |res| switch (res) { .success => {}, .suboptimal_khr => self.handle = .null_handle, else => unreachable, - } else |err| switch(err) { + } else |err| switch (err) { error.OutOfDateKHR => self.handle = .null_handle, else => return err, } diff --git a/src/nu/Window.zig b/src/nu/Window.zig index 9ae74e5..0c749d6 100644 --- a/src/nu/Window.zig +++ b/src/nu/Window.zig @@ -93,3 +93,10 @@ pub fn add_resize_callback(cb: *const fn (u32, u32) void) void { pub fn set_title(title: [:0]const u8) void { c.glfwSetWindowTitle(handle, title); } + +pub fn size() std.meta.Tuple(&[_]type{ u32, u32 }) { + var w: c_int = undefined; + var h: c_int = undefined; + c.glfwGetFramebufferSize(handle, &w, &h); + return .{ @intCast(w), @intCast(h) }; +}