diff --git a/build.zig b/build.zig index 89502345..52851eac 100644 --- a/build.zig +++ b/build.zig @@ -31,28 +31,25 @@ pub fn build(b: *std.build.Builder) void { inline for ([_]ExampleDefinition{ .{ .name = "triangle" }, - //.{ .name = "boids" }, - //.{ .name = "rotating-cube", .packages = &[_]Pkg{Packages.zmath} }, - //.{ .name = "two-cubes", .packages = &[_]Pkg{Packages.zmath} }, - //.{ .name = "instanced-cube", .packages = &[_]Pkg{Packages.zmath} }, - //.{ .name = "advanced-gen-texture-light", .packages = &[_]Pkg{Packages.zmath} }, - //.{ .name = "textured-cube", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg } }, - //.{ .name = "fractal-cube", .packages = &[_]Pkg{Packages.zmath} }, + .{ .name = "boids" }, + .{ .name = "rotating-cube", .packages = &[_]Pkg{Packages.zmath} }, + .{ .name = "two-cubes", .packages = &[_]Pkg{Packages.zmath} }, + .{ .name = "instanced-cube", .packages = &[_]Pkg{Packages.zmath} }, + .{ .name = "advanced-gen-texture-light", .packages = &[_]Pkg{Packages.zmath} }, + .{ .name = "textured-cube", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg } }, + .{ .name = "fractal-cube", .packages = &[_]Pkg{Packages.zmath} }, }) |example| { const example_app = App.init( b, .{ .name = "example-" ++ example.name, .src = "examples/" ++ example.name ++ "/main.zig", - .deps = &.{ glfw.pkg, gpu.pkg, pkg }, + .deps = comptime example.packages ++ &[_]Pkg{ glfw.pkg, gpu.pkg, pkg }, }, ); const example_exe = example_app.step; example_exe.setTarget(target); example_exe.setBuildMode(mode); - inline for (example.packages) |additional_package| { - example_exe.addPackage(additional_package); - } example_app.link(options); example_exe.install(); diff --git a/examples/advanced-gen-texture-light/main.zig b/examples/advanced-gen-texture-light/main.zig index 718dc99f..c16d1ddb 100755 --- a/examples/advanced-gen-texture-light/main.zig +++ b/examples/advanced-gen-texture-light/main.zig @@ -16,52 +16,12 @@ const Vec = zm.Vec; const Mat = zm.Mat; const Quat = zm.Quat; -const App = mach.App(*FrameParams, .{}); +const App = @This(); + +ctx: FrameParams = .{}, var global_params: *FrameParams = undefined; -pub fn main() !void { - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - - const ctx = try allocator.create(FrameParams); - global_params = ctx; // TODO ugly hack to use ctx from glfw callbacks - var app = try App.init(allocator, ctx, .{}); - - app.window.setKeyCallback(keyCallback); - // todo - // app.window.setKeyCallback(struct { - // fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { - // _ = scancode; - // _ = mods; - // if (action == .press) { - // switch (key) { - // .space => window.setShouldClose(true), - // else => {}, - // } - // } - // } - // }.callback); - try app.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); - - const eye = vec3(5.0, 7.0, 5.0); - const target = vec3(0.0, 0.0, 0.0); - - const size = try app.window.getFramebufferSize(); - const aspect_ratio = @intToFloat(f32, size.width) / @intToFloat(f32, size.height); - - ctx.* = FrameParams{ - .queue = app.device.getQueue(), - .cube = Cube.init(app), - .light = Light.init(app), - .depth = Texture.depth(app.device, size.width, size.height), - .depth_size = size, - .camera = Camera.init(app.device, eye, target, vec3(0.0, 1.0, 0.0), aspect_ratio, 45.0, 0.1, 100.0), - }; - - try app.run(.{ .frame = frame }); -} - const FrameParams = struct { queue: gpu.Queue, cube: Cube, @@ -77,37 +37,74 @@ const FrameParams = struct { const right: u8 = 0b1000; }; -fn frame(app: *App, params: *FrameParams) !void { +pub fn init(app: *App, engine: *mach.Engine) !void { + engine.core.internal.window.setKeyCallback(keyCallback); + // todo + // engine.core.internal.window.setKeyCallback(struct { + // fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { + // _ = scancode; + // _ = mods; + // if (action == .press) { + // switch (key) { + // .space => window.setShouldClose(true), + // else => {}, + // } + // } + // } + // }.callback); + try engine.core.internal.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); + + const eye = vec3(5.0, 7.0, 5.0); + const target = vec3(0.0, 0.0, 0.0); + + const size = try engine.core.internal.window.getFramebufferSize(); + const aspect_ratio = @intToFloat(f32, size.width) / @intToFloat(f32, size.height); + + app.ctx = FrameParams{ + .queue = engine.gpu_driver.device.getQueue(), + .cube = Cube.init(engine), + .light = Light.init(engine), + .depth = Texture.depth(engine.gpu_driver.device, size.width, size.height), + .depth_size = size, + .camera = Camera.init(engine.gpu_driver.device, eye, target, vec3(0.0, 1.0, 0.0), aspect_ratio, 45.0, 0.1, 100.0), + }; + + global_params = &app.ctx; // TODO ugly hack to use ctx from glfw callbacks +} + +pub fn deinit(_: *App, _: *mach.Engine) void {} + +pub fn update(app: *App, engine: *mach.Engine) !bool { // If window is resized, recreate depth buffer otherwise we cannot use it. - const size = app.window.getFramebufferSize() catch unreachable; // TODO: return type inference can't handle this - if (size.width != params.depth_size.width or size.height != params.depth_size.height) { - params.depth = Texture.depth(app.device, size.width, size.height); - params.depth_size = size; + const size = engine.core.internal.window.getFramebufferSize() catch unreachable; // TODO: return type inference can't handle this + if (size.width != app.ctx.depth_size.width or size.height != app.ctx.depth_size.height) { + app.ctx.depth = Texture.depth(engine.gpu_driver.device, size.width, size.height); + app.ctx.depth_size = size; } // move camera - const speed = zm.f32x4s(@floatCast(f32, app.delta_time * 5)); - const fwd = zm.normalize3(params.camera.target - params.camera.eye); - const right = zm.normalize3(zm.cross3(fwd, params.camera.up)); + const speed = zm.f32x4s(@floatCast(f32, engine.delta_time * 5)); + const fwd = zm.normalize3(app.ctx.camera.target - app.ctx.camera.eye); + const right = zm.normalize3(zm.cross3(fwd, app.ctx.camera.up)); - if (params.keys & FrameParams.up != 0) - params.camera.eye += fwd * speed; + if (app.ctx.keys & FrameParams.up != 0) + app.ctx.camera.eye += fwd * speed; - if (params.keys & FrameParams.down != 0) - params.camera.eye -= fwd * speed; + if (app.ctx.keys & FrameParams.down != 0) + app.ctx.camera.eye -= fwd * speed; - if (params.keys & FrameParams.right != 0) params.camera.eye += right * speed else if (params.keys & FrameParams.left != 0) params.camera.eye -= right * speed else params.camera.eye += right * (speed * @Vector(4, f32){ 0.5, 0.5, 0.5, 0.5 }); + if (app.ctx.keys & FrameParams.right != 0) app.ctx.camera.eye += right * speed else if (app.ctx.keys & FrameParams.left != 0) app.ctx.camera.eye -= right * speed else app.ctx.camera.eye += right * (speed * @Vector(4, f32){ 0.5, 0.5, 0.5, 0.5 }); - params.camera.update(params.queue); + app.ctx.camera.update(app.ctx.queue); // move light - const light_speed = @floatCast(f32, app.delta_time * 2.5); - params.light.update(params.queue, light_speed); + const light_speed = @floatCast(f32, engine.delta_time * 2.5); + app.ctx.light.update(app.ctx.queue, light_speed); - const back_buffer_view = app.swap_chain.?.getCurrentTextureView(); + const back_buffer_view = engine.gpu_driver.swap_chain.?.getCurrentTextureView(); defer back_buffer_view.release(); - const encoder = app.device.createCommandEncoder(null); + const encoder = engine.gpu_driver.device.createCommandEncoder(null); defer encoder.release(); const color_attachment = gpu.RenderPassColorAttachment{ @@ -120,7 +117,7 @@ fn frame(app: *App, params: *FrameParams) !void { const render_pass_descriptor = gpu.RenderPassEncoder.Descriptor{ .color_attachments = &.{color_attachment}, .depth_stencil_attachment = &.{ - .view = params.depth.view, + .view = app.ctx.depth.view, .depth_load_op = .clear, .depth_store_op = .store, .stencil_load_op = .none, @@ -133,24 +130,24 @@ fn frame(app: *App, params: *FrameParams) !void { defer pass.release(); // brick cubes - pass.setPipeline(params.cube.pipeline); - pass.setBindGroup(0, params.camera.bind_group, &.{}); - pass.setBindGroup(1, params.cube.texture.bind_group, &.{}); - pass.setBindGroup(2, params.light.bind_group, &.{}); - pass.setVertexBuffer(0, params.cube.mesh.buffer, 0, params.cube.mesh.size); - pass.setVertexBuffer(1, params.cube.instance.buffer, 0, params.cube.instance.size); - pass.draw(4, params.cube.instance.len, 0, 0); - pass.draw(4, params.cube.instance.len, 4, 0); - pass.draw(4, params.cube.instance.len, 8, 0); - pass.draw(4, params.cube.instance.len, 12, 0); - pass.draw(4, params.cube.instance.len, 16, 0); - pass.draw(4, params.cube.instance.len, 20, 0); + pass.setPipeline(app.ctx.cube.pipeline); + pass.setBindGroup(0, app.ctx.camera.bind_group, &.{}); + pass.setBindGroup(1, app.ctx.cube.texture.bind_group, &.{}); + pass.setBindGroup(2, app.ctx.light.bind_group, &.{}); + pass.setVertexBuffer(0, app.ctx.cube.mesh.buffer, 0, app.ctx.cube.mesh.size); + pass.setVertexBuffer(1, app.ctx.cube.instance.buffer, 0, app.ctx.cube.instance.size); + pass.draw(4, app.ctx.cube.instance.len, 0, 0); + pass.draw(4, app.ctx.cube.instance.len, 4, 0); + pass.draw(4, app.ctx.cube.instance.len, 8, 0); + pass.draw(4, app.ctx.cube.instance.len, 12, 0); + pass.draw(4, app.ctx.cube.instance.len, 16, 0); + pass.draw(4, app.ctx.cube.instance.len, 20, 0); // light source - pass.setPipeline(params.light.pipeline); - pass.setBindGroup(0, params.camera.bind_group, &.{}); - pass.setBindGroup(1, params.light.bind_group, &.{}); - pass.setVertexBuffer(0, params.cube.mesh.buffer, 0, params.cube.mesh.size); + pass.setPipeline(app.ctx.light.pipeline); + pass.setBindGroup(0, app.ctx.camera.bind_group, &.{}); + pass.setBindGroup(1, app.ctx.light.bind_group, &.{}); + pass.setVertexBuffer(0, app.ctx.cube.mesh.buffer, 0, app.ctx.cube.mesh.size); pass.draw(4, 1, 0, 0); pass.draw(4, 1, 4, 0); pass.draw(4, 1, 8, 0); @@ -163,8 +160,10 @@ fn frame(app: *App, params: *FrameParams) !void { var command = encoder.finish(null); defer command.release(); - params.queue.submit(&.{command}); - app.swap_chain.?.present(); + app.ctx.queue.submit(&.{command}); + engine.gpu_driver.swap_chain.?.present(); + + return true; } const Camera = struct { @@ -267,8 +266,8 @@ const Cube = struct { const SPACING = 2; // spacing between cubes const DISPLACEMENT = vec3u(IPR * SPACING / 2, 0, IPR * SPACING / 2); - fn init(app: App) Self { - const device = app.device; + fn init(engine: *mach.Engine) Self { + const device = engine.gpu_driver.device; const texture = Brick.texture(device); @@ -306,12 +305,12 @@ const Cube = struct { .mesh = mesh(device), .texture = texture, .instance = instance, - .pipeline = pipeline(app), + .pipeline = pipeline(engine), }; } - fn pipeline(app: App) gpu.RenderPipeline { - const device = app.device; + fn pipeline(engine: *mach.Engine) gpu.RenderPipeline { + const device = engine.gpu_driver.device; const layout_descriptor = gpu.PipelineLayout.Descriptor{ .bind_group_layouts = &.{ @@ -343,7 +342,7 @@ const Cube = struct { }; const color_target = gpu.ColorTargetState{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .write_mask = gpu.ColorWriteMask.all, .blend = &blend, }; @@ -715,8 +714,8 @@ const Light = struct { color: Vec, }; - fn init(app: App) Self { - const device = app.device; + fn init(engine: *mach.Engine) Self { + const device = engine.gpu_driver.device; const uniform = .{ .color = vec3u(1, 1, 1), .position = vec3u(3, 7, 2), @@ -738,7 +737,7 @@ const Light = struct { .buffer = buffer, .uniform = uniform, .bind_group = bind_group, - .pipeline = Self.pipeline(app), + .pipeline = Self.pipeline(engine), }; } @@ -762,8 +761,8 @@ const Light = struct { }); } - fn pipeline(app: App) gpu.RenderPipeline { - const device = app.device; + fn pipeline(engine: *mach.Engine) gpu.RenderPipeline { + const device = engine.gpu_driver.device; const layout_descriptor = gpu.PipelineLayout.Descriptor{ .bind_group_layouts = &.{ @@ -794,7 +793,7 @@ const Light = struct { }; const color_target = gpu.ColorTargetState{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .write_mask = gpu.ColorWriteMask.all, .blend = &blend, }; diff --git a/examples/boids/main.zig b/examples/boids/main.zig index 19d4fc23..3916e7e9 100644 --- a/examples/boids/main.zig +++ b/examples/boids/main.zig @@ -4,16 +4,15 @@ const std = @import("std"); const mach = @import("mach"); const gpu = @import("gpu"); -const FrameParams = struct { - compute_pipeline: gpu.ComputePipeline, - render_pipeline: gpu.RenderPipeline, - sprite_vertex_buffer: gpu.Buffer, - particle_buffers: [2]gpu.Buffer, - particle_bind_groups: [2]gpu.BindGroup, - sim_param_buffer: gpu.Buffer, - frame_counter: usize, -}; -const App = mach.App(*FrameParams, .{}); +compute_pipeline: gpu.ComputePipeline, +render_pipeline: gpu.RenderPipeline, +sprite_vertex_buffer: gpu.Buffer, +particle_buffers: [2]gpu.Buffer, +particle_bind_groups: [2]gpu.BindGroup, +sim_param_buffer: gpu.Buffer, +frame_counter: usize, + +const App = @This(); const num_particle = 1500; @@ -27,19 +26,13 @@ var sim_params = [_]f32{ 0.005, // .rule_3_scale }; -pub fn main() !void { - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - - const ctx = try allocator.create(FrameParams); - var app = try App.init(allocator, ctx, .{}); - - const sprite_shader_module = app.device.createShaderModule(&.{ +pub fn init(app: *App, engine: *mach.Engine) !void { + const sprite_shader_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "sprite shader module", .code = .{ .wgsl = @embedFile("sprite.wgsl") }, }); - const update_sprite_shader_module = app.device.createShaderModule(&.{ + const update_sprite_shader_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "update sprite shader module", .code = .{ .wgsl = @embedFile("updateSprites.wgsl") }, }); @@ -68,7 +61,7 @@ pub fn main() !void { }, }; - const render_pipeline = app.device.createRenderPipeline(&gpu.RenderPipeline.Descriptor{ + const render_pipeline = engine.gpu_driver.device.createRenderPipeline(&gpu.RenderPipeline.Descriptor{ .vertex = .{ .module = sprite_shader_module, .entry_point = "vert_main", @@ -91,12 +84,12 @@ pub fn main() !void { }, .fragment = &gpu.FragmentState{ .module = sprite_shader_module, .entry_point = "frag_main", .targets = &[_]gpu.ColorTargetState{ .{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, }, } }, }); - const compute_pipeline = app.device.createComputePipeline(&gpu.ComputePipeline.Descriptor{ .compute = gpu.ProgrammableStageDescriptor{ + const compute_pipeline = engine.gpu_driver.device.createComputePipeline(&gpu.ComputePipeline.Descriptor{ .compute = gpu.ProgrammableStageDescriptor{ .module = update_sprite_shader_module, .entry_point = "main", } }); @@ -106,17 +99,17 @@ pub fn main() !void { -0.02, 0.0, 0.02, }; - const sprite_vertex_buffer = app.device.createBuffer(&gpu.Buffer.Descriptor{ + const sprite_vertex_buffer = engine.gpu_driver.device.createBuffer(&gpu.Buffer.Descriptor{ .usage = .{ .vertex = true, .copy_dst = true }, .size = vert_buffer_data.len * @sizeOf(f32), }); - app.device.getQueue().writeBuffer(sprite_vertex_buffer, 0, f32, &vert_buffer_data); + engine.gpu_driver.device.getQueue().writeBuffer(sprite_vertex_buffer, 0, f32, &vert_buffer_data); - const sim_param_buffer = app.device.createBuffer(&gpu.Buffer.Descriptor{ + const sim_param_buffer = engine.gpu_driver.device.createBuffer(&gpu.Buffer.Descriptor{ .usage = .{ .uniform = true, .copy_dst = true }, .size = sim_params.len * @sizeOf(f32), }); - app.device.getQueue().writeBuffer(sim_param_buffer, 0, f32, &sim_params); + engine.gpu_driver.device.getQueue().writeBuffer(sim_param_buffer, 0, f32, &sim_params); var initial_particle_data: [num_particle * 4]f32 = undefined; var rng = std.rand.DefaultPrng.init(0); @@ -133,7 +126,7 @@ pub fn main() !void { var particle_bind_groups: [2]gpu.BindGroup = undefined; i = 0; while (i < 2) : (i += 1) { - particle_buffers[i] = app.device.createBuffer(&gpu.Buffer.Descriptor{ + particle_buffers[i] = engine.gpu_driver.device.createBuffer(&gpu.Buffer.Descriptor{ .usage = .{ .vertex = true, .copy_dst = true, @@ -141,33 +134,31 @@ pub fn main() !void { }, .size = initial_particle_data.len * @sizeOf(f32), }); - app.device.getQueue().writeBuffer(particle_buffers[i], 0, f32, &initial_particle_data); + engine.gpu_driver.device.getQueue().writeBuffer(particle_buffers[i], 0, f32, &initial_particle_data); } i = 0; while (i < 2) : (i += 1) { - particle_bind_groups[i] = app.device.createBindGroup(&gpu.BindGroup.Descriptor{ .layout = compute_pipeline.getBindGroupLayout(0), .entries = &[_]gpu.BindGroup.Entry{ + particle_bind_groups[i] = engine.gpu_driver.device.createBindGroup(&gpu.BindGroup.Descriptor{ .layout = compute_pipeline.getBindGroupLayout(0), .entries = &[_]gpu.BindGroup.Entry{ gpu.BindGroup.Entry.buffer(0, sim_param_buffer, 0, sim_params.len * @sizeOf(f32)), gpu.BindGroup.Entry.buffer(1, particle_buffers[i], 0, initial_particle_data.len * @sizeOf(f32)), gpu.BindGroup.Entry.buffer(2, particle_buffers[(i + 1) % 2], 0, initial_particle_data.len * @sizeOf(f32)), } }); } - ctx.* = FrameParams{ - .compute_pipeline = compute_pipeline, - .render_pipeline = render_pipeline, - .sprite_vertex_buffer = sprite_vertex_buffer, - .particle_buffers = particle_buffers, - .particle_bind_groups = particle_bind_groups, - .sim_param_buffer = sim_param_buffer, - .frame_counter = 0, - }; - - try app.run(.{ .frame = frame }); + app.compute_pipeline = compute_pipeline; + app.render_pipeline = render_pipeline; + app.sprite_vertex_buffer = sprite_vertex_buffer; + app.particle_buffers = particle_buffers; + app.particle_bind_groups = particle_bind_groups; + app.sim_param_buffer = sim_param_buffer; + app.frame_counter = 0; } -fn frame(app: *App, params: *FrameParams) !void { - const back_buffer_view = app.swap_chain.?.getCurrentTextureView(); +pub fn deinit(_: *App, _: *mach.Engine) void {} + +pub fn update(app: *App, engine: *mach.Engine) !bool { + const back_buffer_view = engine.gpu_driver.swap_chain.?.getCurrentTextureView(); const color_attachment = gpu.RenderPassColorAttachment{ .view = back_buffer_view, .resolve_target = null, @@ -180,38 +171,40 @@ fn frame(app: *App, params: *FrameParams) !void { color_attachment, } }; - sim_params[0] = @floatCast(f32, app.delta_time); - app.device.getQueue().writeBuffer(params.sim_param_buffer, 0, f32, &sim_params); + sim_params[0] = @floatCast(f32, engine.delta_time); + engine.gpu_driver.device.getQueue().writeBuffer(app.sim_param_buffer, 0, f32, &sim_params); - const command_encoder = app.device.createCommandEncoder(null); + const command_encoder = engine.gpu_driver.device.createCommandEncoder(null); { const pass_encoder = command_encoder.beginComputePass(null); - pass_encoder.setPipeline(params.compute_pipeline); - pass_encoder.setBindGroup(0, params.particle_bind_groups[params.frame_counter % 2], null); + pass_encoder.setPipeline(app.compute_pipeline); + pass_encoder.setBindGroup(0, app.particle_bind_groups[app.frame_counter % 2], null); pass_encoder.dispatch(@floatToInt(u32, std.math.ceil(@as(f32, num_particle) / 64)), 1, 1); pass_encoder.end(); pass_encoder.release(); } { const pass_encoder = command_encoder.beginRenderPass(&render_pass_descriptor); - pass_encoder.setPipeline(params.render_pipeline); - pass_encoder.setVertexBuffer(0, params.particle_buffers[(params.frame_counter + 1) % 2], 0, num_particle * 4 * @sizeOf(f32)); - pass_encoder.setVertexBuffer(1, params.sprite_vertex_buffer, 0, 6 * @sizeOf(f32)); + pass_encoder.setPipeline(app.render_pipeline); + pass_encoder.setVertexBuffer(0, app.particle_buffers[(app.frame_counter + 1) % 2], 0, num_particle * 4 * @sizeOf(f32)); + pass_encoder.setVertexBuffer(1, app.sprite_vertex_buffer, 0, 6 * @sizeOf(f32)); pass_encoder.draw(3, num_particle, 0, 0); pass_encoder.end(); pass_encoder.release(); } - params.frame_counter += 1; - if (params.frame_counter % 60 == 0) { - std.debug.print("Frame {}\n", .{params.frame_counter}); + app.frame_counter += 1; + if (app.frame_counter % 60 == 0) { + std.debug.print("Frame {}\n", .{app.frame_counter}); } var command = command_encoder.finish(null); command_encoder.release(); - app.device.getQueue().submit(&.{command}); + engine.gpu_driver.device.getQueue().submit(&.{command}); command.release(); - app.swap_chain.?.present(); + engine.gpu_driver.swap_chain.?.present(); back_buffer_view.release(); + + return true; } diff --git a/examples/fractal-cube/main.zig b/examples/fractal-cube/main.zig index 6e478910..ff3ef749 100755 --- a/examples/fractal-cube/main.zig +++ b/examples/fractal-cube/main.zig @@ -4,8 +4,8 @@ //! We also need a second texture to use on the cube, that after the render pass //! needs to copy the other texture. We can't use the same texture since //! it would interfere with the sincronization on the gpu during the render pass. -//! This demo currently does not work on opengl, because app.current_desc.width/height, -//! are set to 0 after app.init() and because webgpu does not implement copyTextureToTexture, +//! This demo currently does not work on opengl, because engine.gpu_driver.current_desc.width/height, +//! are set to 0 after engine.gpu_driver.init() and because webgpu does not implement copyTextureToTexture, //! for opengl const std = @import("std"); @@ -16,7 +16,7 @@ const zm = @import("zmath"); const Vertex = @import("cube_mesh.zig").Vertex; const vertices = @import("cube_mesh.zig").vertices; -const App = mach.App(*FrameParams, .{}); +const App = @This(); const UniformBufferObject = struct { mat: zm.Mat, @@ -24,15 +24,23 @@ const UniformBufferObject = struct { var timer: std.time.Timer = undefined; -pub fn main() !void { +pipeline: gpu.RenderPipeline, +queue: gpu.Queue, +vertex_buffer: gpu.Buffer, +uniform_buffer: gpu.Buffer, +bind_group: gpu.BindGroup, +depth_texture: ?gpu.Texture, +cube_texture: gpu.Texture, +cube_texture_view: gpu.TextureView, +cube_texture_render: gpu.Texture, +cube_texture_view_render: gpu.TextureView, +sampler: gpu.Sampler, +bgl: gpu.BindGroupLayout, + +pub fn init(app: *App, engine: *mach.Engine) !void { timer = try std.time.Timer.start(); - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - const ctx = try allocator.create(FrameParams); - var app = try App.init(allocator, ctx, .{}); - - app.window.setKeyCallback(struct { + engine.core.internal.window.setKeyCallback(struct { fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { _ = scancode; _ = mods; @@ -44,9 +52,9 @@ pub fn main() !void { } } }.callback); - try app.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); + try engine.core.internal.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); - const vs_module = app.device.createShaderModule(&.{ + const vs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my vertex shader", .code = .{ .wgsl = @embedFile("vert.wgsl") }, }); @@ -62,7 +70,7 @@ pub fn main() !void { .attributes = &vertex_attributes, }; - const fs_module = app.device.createShaderModule(&.{ + const fs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my fragment shader", .code = .{ .wgsl = @embedFile("frag.wgsl") }, }); @@ -80,7 +88,7 @@ pub fn main() !void { }, }; const color_target = gpu.ColorTargetState{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .blend = &blend, .write_mask = gpu.ColorWriteMask.all, }; @@ -94,15 +102,14 @@ pub fn main() !void { const bgle_buffer = gpu.BindGroupLayout.Entry.buffer(0, .{ .vertex = true }, .uniform, true, 0); const bgle_sampler = gpu.BindGroupLayout.Entry.sampler(1, .{ .fragment = true }, .filtering); const bgle_textureview = gpu.BindGroupLayout.Entry.texture(2, .{ .fragment = true }, .float, .dimension_2d, false); - const bgl = app.device.createBindGroupLayout( + const bgl = engine.gpu_driver.device.createBindGroupLayout( &gpu.BindGroupLayout.Descriptor{ .entries = &.{ bgle_buffer, bgle_sampler, bgle_textureview }, }, ); - defer bgl.release(); const bind_group_layouts = [_]gpu.BindGroupLayout{bgl}; - const pipeline_layout = app.device.createPipelineLayout(&.{ + const pipeline_layout = engine.gpu_driver.device.createPipelineLayout(&.{ .bind_group_layouts = &bind_group_layouts, }); @@ -132,7 +139,7 @@ pub fn main() !void { }, }; - const vertex_buffer = app.device.createBuffer(&.{ + const vertex_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .vertex = true }, .size = @sizeOf(Vertex) * vertices.len, .mapped_at_creation = true, @@ -140,52 +147,48 @@ pub fn main() !void { var vertex_mapped = vertex_buffer.getMappedRange(Vertex, 0, vertices.len); std.mem.copy(Vertex, vertex_mapped, vertices[0..]); vertex_buffer.unmap(); - defer vertex_buffer.release(); - const uniform_buffer = app.device.createBuffer(&.{ + const uniform_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .copy_dst = true, .uniform = true }, .size = @sizeOf(UniformBufferObject), .mapped_at_creation = false, }); - defer uniform_buffer.release(); // The texture to put on the cube - const cube_texture = app.device.createTexture(&gpu.Texture.Descriptor{ + const cube_texture = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .usage = .{ .texture_binding = true, .copy_dst = true }, - .size = .{ .width = app.current_desc.width, .height = app.current_desc.height }, - .format = app.swap_chain_format, + .size = .{ .width = engine.gpu_driver.current_desc.width, .height = engine.gpu_driver.current_desc.height }, + .format = engine.gpu_driver.swap_chain_format, }); defer cube_texture.release(); // The texture on which we render - const cube_texture_render = app.device.createTexture(&gpu.Texture.Descriptor{ + const cube_texture_render = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .usage = .{ .render_attachment = true, .copy_src = true }, - .size = .{ .width = app.current_desc.width, .height = app.current_desc.height }, - .format = app.swap_chain_format, + .size = .{ .width = engine.gpu_driver.current_desc.width, .height = engine.gpu_driver.current_desc.height }, + .format = engine.gpu_driver.swap_chain_format, }); defer cube_texture_render.release(); - const sampler = app.device.createSampler(&gpu.Sampler.Descriptor{ + const sampler = engine.gpu_driver.device.createSampler(&gpu.Sampler.Descriptor{ .mag_filter = .linear, .min_filter = .linear, }); - defer sampler.release(); const cube_texture_view = cube_texture.createView(&gpu.TextureView.Descriptor{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .dimension = .dimension_2d, .mip_level_count = 1, .array_layer_count = 1, }); - defer cube_texture_view.release(); const cube_texture_view_render = cube_texture_render.createView(&gpu.TextureView.Descriptor{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .dimension = .dimension_2d, .mip_level_count = 1, .array_layer_count = 1, }); defer cube_texture_view_render.release(); - const bind_group = app.device.createBindGroup( + const bind_group = engine.gpu_driver.device.createBindGroup( &gpu.BindGroup.Descriptor{ .layout = bgl, .entries = &.{ @@ -195,49 +198,40 @@ pub fn main() !void { }, }, ); - defer bind_group.release(); - ctx.* = FrameParams{ - .pipeline = app.device.createRenderPipeline(&pipeline_descriptor), - .queue = app.device.getQueue(), - .vertex_buffer = vertex_buffer, - .uniform_buffer = uniform_buffer, - .bind_group = bind_group, - .depth_texture = null, - .cube_texture = cube_texture, - .cube_texture_view = cube_texture_view, - .cube_texture_render = cube_texture_render, - .cube_texture_view_render = cube_texture_view_render, - .sampler = sampler, - .bgl = bgl, - }; + app.pipeline = engine.gpu_driver.device.createRenderPipeline(&pipeline_descriptor); + app.queue = engine.gpu_driver.device.getQueue(); + app.vertex_buffer = vertex_buffer; + app.uniform_buffer = uniform_buffer; + app.bind_group = bind_group; + app.depth_texture = null; + app.cube_texture = cube_texture; + app.cube_texture_view = cube_texture_view; + app.cube_texture_render = cube_texture_render; + app.cube_texture_view_render = cube_texture_view_render; + app.sampler = sampler; + app.bgl = bgl; vs_module.release(); fs_module.release(); pipeline_layout.release(); - - try app.run(.{ .frame = frame, .resize = resize }); - ctx.depth_texture.?.release(); } -const FrameParams = struct { - pipeline: gpu.RenderPipeline, - queue: gpu.Queue, - vertex_buffer: gpu.Buffer, - uniform_buffer: gpu.Buffer, - bind_group: gpu.BindGroup, - depth_texture: ?gpu.Texture, - cube_texture: gpu.Texture, - cube_texture_view: gpu.TextureView, - cube_texture_render: gpu.Texture, - cube_texture_view_render: gpu.TextureView, - sampler: gpu.Sampler, - bgl: gpu.BindGroupLayout, -}; +pub fn deinit(app: *App, _: *mach.Engine) void { + app.bgl.release(); + app.vertex_buffer.release(); + app.uniform_buffer.release(); + app.cube_texture.release(); + app.sampler.release(); + app.cube_texture_view.release(); + app.cube_texture_view.release(); + app.bind_group.release(); + app.depth_texture.?.release(); +} -fn frame(app: *App, params: *FrameParams) !void { - const cube_view = params.cube_texture_view_render; - const back_buffer_view = app.swap_chain.?.getCurrentTextureView(); +pub fn update(app: *App, engine: *mach.Engine) !bool { + const cube_view = app.cube_texture_view_render; + const back_buffer_view = engine.gpu_driver.swap_chain.?.getCurrentTextureView(); const cube_color_attachment = gpu.RenderPassColorAttachment{ .view = cube_view, @@ -255,7 +249,7 @@ fn frame(app: *App, params: *FrameParams) !void { }; const depth_stencil_attachment = gpu.RenderPassDepthStencilAttachment{ - .view = params.depth_texture.?.createView(&gpu.TextureView.Descriptor{ + .view = app.depth_texture.?.createView(&gpu.TextureView.Descriptor{ .format = .depth24_plus, .dimension = .dimension_2d, .array_layer_count = 1, @@ -268,7 +262,7 @@ fn frame(app: *App, params: *FrameParams) !void { .stencil_store_op = .none, }; - const encoder = app.device.createCommandEncoder(null); + const encoder = engine.gpu_driver.device.createCommandEncoder(null); const cube_render_pass_info = gpu.RenderPassEncoder.Descriptor{ .color_attachments = &.{cube_color_attachment}, .depth_stencil_attachment = &depth_stencil_attachment, @@ -288,38 +282,38 @@ fn frame(app: *App, params: *FrameParams) !void { ); const proj = zm.perspectiveFovRh( (std.math.pi * 2.0 / 5.0), - @intToFloat(f32, app.current_desc.width) / @intToFloat(f32, app.current_desc.height), + @intToFloat(f32, engine.gpu_driver.current_desc.width) / @intToFloat(f32, engine.gpu_driver.current_desc.height), 1, 100, ); const ubo = UniformBufferObject{ .mat = zm.transpose(zm.mul(zm.mul(model, view), proj)), }; - encoder.writeBuffer(params.uniform_buffer, 0, UniformBufferObject, &.{ubo}); + encoder.writeBuffer(app.uniform_buffer, 0, UniformBufferObject, &.{ubo}); } const pass = encoder.beginRenderPass(&render_pass_info); - pass.setPipeline(params.pipeline); - pass.setBindGroup(0, params.bind_group, &.{0}); - pass.setVertexBuffer(0, params.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); + pass.setPipeline(app.pipeline); + pass.setBindGroup(0, app.bind_group, &.{0}); + pass.setVertexBuffer(0, app.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); pass.draw(vertices.len, 1, 0, 0); pass.end(); pass.release(); encoder.copyTextureToTexture( &gpu.ImageCopyTexture{ - .texture = params.cube_texture_render, + .texture = app.cube_texture_render, }, &gpu.ImageCopyTexture{ - .texture = params.cube_texture, + .texture = app.cube_texture, }, - &.{ .width = app.current_desc.width, .height = app.current_desc.height }, + &.{ .width = engine.gpu_driver.current_desc.width, .height = engine.gpu_driver.current_desc.height }, ); const cube_pass = encoder.beginRenderPass(&cube_render_pass_info); - cube_pass.setPipeline(params.pipeline); - cube_pass.setBindGroup(0, params.bind_group, &.{0}); - cube_pass.setVertexBuffer(0, params.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); + cube_pass.setPipeline(app.pipeline); + cube_pass.setBindGroup(0, app.bind_group, &.{0}); + cube_pass.setVertexBuffer(0, app.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); cube_pass.draw(vertices.len, 1, 0, 0); cube_pass.end(); cube_pass.release(); @@ -327,65 +321,67 @@ fn frame(app: *App, params: *FrameParams) !void { var command = encoder.finish(null); encoder.release(); - params.queue.submit(&.{command}); + app.queue.submit(&.{command}); command.release(); - app.swap_chain.?.present(); + engine.gpu_driver.swap_chain.?.present(); back_buffer_view.release(); + + return true; } -fn resize(app: *App, params: *FrameParams, width: u32, height: u32) !void { - if (params.depth_texture != null) { - params.depth_texture.?.release(); - params.depth_texture = app.device.createTexture(&gpu.Texture.Descriptor{ +pub fn resize(app: *App, engine: *mach.Engine, width: u32, height: u32) !void { + if (app.depth_texture != null) { + app.depth_texture.?.release(); + app.depth_texture = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .usage = .{ .render_attachment = true }, .size = .{ .width = width, .height = height }, .format = .depth24_plus, }); - params.cube_texture.release(); - params.cube_texture = app.device.createTexture(&gpu.Texture.Descriptor{ + app.cube_texture.release(); + app.cube_texture = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .usage = .{ .texture_binding = true, .copy_dst = true }, .size = .{ .width = width, .height = height }, - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, }); - params.cube_texture_render.release(); - params.cube_texture_render = app.device.createTexture(&gpu.Texture.Descriptor{ + app.cube_texture_render.release(); + app.cube_texture_render = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .usage = .{ .render_attachment = true, .copy_src = true }, .size = .{ .width = width, .height = height }, - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, }); - params.cube_texture_view.release(); - params.cube_texture_view = params.cube_texture.createView(&gpu.TextureView.Descriptor{ - .format = app.swap_chain_format, + app.cube_texture_view.release(); + app.cube_texture_view = app.cube_texture.createView(&gpu.TextureView.Descriptor{ + .format = engine.gpu_driver.swap_chain_format, .dimension = .dimension_2d, .mip_level_count = 1, .array_layer_count = 1, }); - params.cube_texture_view_render.release(); - params.cube_texture_view_render = params.cube_texture_render.createView(&gpu.TextureView.Descriptor{ - .format = app.swap_chain_format, + app.cube_texture_view_render.release(); + app.cube_texture_view_render = app.cube_texture_render.createView(&gpu.TextureView.Descriptor{ + .format = engine.gpu_driver.swap_chain_format, .dimension = .dimension_2d, .mip_level_count = 1, .array_layer_count = 1, }); - params.bind_group.release(); - params.bind_group = app.device.createBindGroup( + app.bind_group.release(); + app.bind_group = engine.gpu_driver.device.createBindGroup( &gpu.BindGroup.Descriptor{ - .layout = params.bgl, + .layout = app.bgl, .entries = &.{ - gpu.BindGroup.Entry.buffer(0, params.uniform_buffer, 0, @sizeOf(UniformBufferObject)), - gpu.BindGroup.Entry.sampler(1, params.sampler), - gpu.BindGroup.Entry.textureView(2, params.cube_texture_view), + gpu.BindGroup.Entry.buffer(0, app.uniform_buffer, 0, @sizeOf(UniformBufferObject)), + gpu.BindGroup.Entry.sampler(1, app.sampler), + gpu.BindGroup.Entry.textureView(2, app.cube_texture_view), }, }, ); } else { // The first time resize is called, width and height are set to 0 - params.depth_texture = app.device.createTexture(&gpu.Texture.Descriptor{ + app.depth_texture = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .usage = .{ .render_attachment = true }, - .size = .{ .width = app.current_desc.width, .height = app.current_desc.height }, + .size = .{ .width = engine.gpu_driver.current_desc.width, .height = engine.gpu_driver.current_desc.height }, .format = .depth24_plus, }); } diff --git a/examples/instanced-cube/main.zig b/examples/instanced-cube/main.zig index ce325b83..7153a778 100755 --- a/examples/instanced-cube/main.zig +++ b/examples/instanced-cube/main.zig @@ -6,23 +6,24 @@ const zm = @import("zmath"); const Vertex = @import("cube_mesh.zig").Vertex; const vertices = @import("cube_mesh.zig").vertices; -const App = mach.App(*FrameParams, .{}); - const UniformBufferObject = struct { mat: zm.Mat, }; var timer: std.time.Timer = undefined; -pub fn main() !void { +pipeline: gpu.RenderPipeline, +queue: gpu.Queue, +vertex_buffer: gpu.Buffer, +uniform_buffer: gpu.Buffer, +bind_group: gpu.BindGroup, + +const App = @This(); + +pub fn init(app: *App, engine: *mach.Engine) !void { timer = try std.time.Timer.start(); - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - const ctx = try allocator.create(FrameParams); - var app = try App.init(allocator, ctx, .{}); - - app.window.setKeyCallback(struct { + engine.core.internal.window.setKeyCallback(struct { fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { _ = scancode; _ = mods; @@ -34,9 +35,9 @@ pub fn main() !void { } } }.callback); - try app.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); + try engine.core.internal.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); - const vs_module = app.device.createShaderModule(&.{ + const vs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my vertex shader", .code = .{ .wgsl = @embedFile("vert.wgsl") }, }); @@ -52,13 +53,13 @@ pub fn main() !void { .attributes = &vertex_attributes, }; - const fs_module = app.device.createShaderModule(&.{ + const fs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my fragment shader", .code = .{ .wgsl = @embedFile("frag.wgsl") }, }); const color_target = gpu.ColorTargetState{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .blend = null, .write_mask = gpu.ColorWriteMask.all, }; @@ -70,14 +71,14 @@ pub fn main() !void { }; const bgle = gpu.BindGroupLayout.Entry.buffer(0, .{ .vertex = true }, .uniform, true, 0); - const bgl = app.device.createBindGroupLayout( + const bgl = engine.gpu_driver.device.createBindGroupLayout( &gpu.BindGroupLayout.Descriptor{ .entries = &.{bgle}, }, ); const bind_group_layouts = [_]gpu.BindGroupLayout{bgl}; - const pipeline_layout = app.device.createPipelineLayout(&.{ + const pipeline_layout = engine.gpu_driver.device.createPipelineLayout(&.{ .bind_group_layouts = &bind_group_layouts, }); @@ -103,7 +104,7 @@ pub fn main() !void { }, }; - const vertex_buffer = app.device.createBuffer(&.{ + const vertex_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .vertex = true }, .size = @sizeOf(Vertex) * vertices.len, .mapped_at_creation = true, @@ -111,19 +112,18 @@ pub fn main() !void { var vertex_mapped = vertex_buffer.getMappedRange(Vertex, 0, vertices.len); std.mem.copy(Vertex, vertex_mapped, vertices[0..]); vertex_buffer.unmap(); - defer vertex_buffer.release(); const x_count = 4; const y_count = 4; const num_instances = x_count * y_count; - const uniform_buffer = app.device.createBuffer(&.{ + const uniform_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .copy_dst = true, .uniform = true }, .size = @sizeOf(UniformBufferObject) * num_instances, .mapped_at_creation = false, }); defer uniform_buffer.release(); - const bind_group = app.device.createBindGroup( + const bind_group = engine.gpu_driver.device.createBindGroup( &gpu.BindGroup.Descriptor{ .layout = bgl, .entries = &.{ @@ -131,38 +131,30 @@ pub fn main() !void { }, }, ); - defer bind_group.release(); - ctx.* = FrameParams{ - .pipeline = app.device.createRenderPipeline(&pipeline_descriptor), - .queue = app.device.getQueue(), - .vertex_buffer = vertex_buffer, - .uniform_buffer = uniform_buffer, - .bind_group = bind_group, - }; + app.pipeline = engine.gpu_driver.device.createRenderPipeline(&pipeline_descriptor); + app.queue = engine.gpu_driver.device.getQueue(); + app.vertex_buffer = vertex_buffer; + app.uniform_buffer = uniform_buffer; + app.bind_group = bind_group; vs_module.release(); fs_module.release(); pipeline_layout.release(); bgl.release(); - - try app.run(.{ .frame = frame }); } -const FrameParams = struct { - pipeline: gpu.RenderPipeline, - queue: gpu.Queue, - vertex_buffer: gpu.Buffer, - uniform_buffer: gpu.Buffer, - bind_group: gpu.BindGroup, -}; +pub fn deinit(app: *App, _: *mach.Engine) void { + app.vertex_buffer.release(); + app.bind_group.release(); +} var i: u32 = 0; -fn frame(app: *App, params: *FrameParams) !void { +pub fn update(app: *App, engine: *mach.Engine) !bool { i += 1; - const back_buffer_view = app.swap_chain.?.getCurrentTextureView(); + const back_buffer_view = engine.gpu_driver.swap_chain.?.getCurrentTextureView(); const color_attachment = gpu.RenderPassColorAttachment{ .view = back_buffer_view, .resolve_target = null, @@ -171,7 +163,7 @@ fn frame(app: *App, params: *FrameParams) !void { .store_op = .store, }; - const encoder = app.device.createCommandEncoder(null); + const encoder = engine.gpu_driver.device.createCommandEncoder(null); const render_pass_info = gpu.RenderPassEncoder.Descriptor{ .color_attachments = &.{color_attachment}, }; @@ -179,7 +171,7 @@ fn frame(app: *App, params: *FrameParams) !void { { const proj = zm.perspectiveFovRh( (std.math.pi / 3.0), - @intToFloat(f32, app.current_desc.width) / @intToFloat(f32, app.current_desc.height), + @intToFloat(f32, engine.gpu_driver.current_desc.width) / @intToFloat(f32, engine.gpu_driver.current_desc.height), 10, 30, ); @@ -203,13 +195,13 @@ fn frame(app: *App, params: *FrameParams) !void { m += 1; } } - encoder.writeBuffer(params.uniform_buffer, 0, UniformBufferObject, &ubos); + encoder.writeBuffer(app.uniform_buffer, 0, UniformBufferObject, &ubos); } const pass = encoder.beginRenderPass(&render_pass_info); - pass.setPipeline(params.pipeline); - pass.setVertexBuffer(0, params.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); - pass.setBindGroup(0, params.bind_group, &.{0}); + pass.setPipeline(app.pipeline); + pass.setVertexBuffer(0, app.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); + pass.setBindGroup(0, app.bind_group, &.{0}); pass.draw(vertices.len, 16, 0, 0); pass.end(); pass.release(); @@ -217,8 +209,10 @@ fn frame(app: *App, params: *FrameParams) !void { var command = encoder.finish(null); encoder.release(); - params.queue.submit(&.{command}); + app.queue.submit(&.{command}); command.release(); - app.swap_chain.?.present(); + engine.gpu_driver.swap_chain.?.present(); back_buffer_view.release(); + + return true; } diff --git a/examples/rotating-cube/main.zig b/examples/rotating-cube/main.zig index c4971d86..876e00c6 100755 --- a/examples/rotating-cube/main.zig +++ b/examples/rotating-cube/main.zig @@ -6,7 +6,7 @@ const zm = @import("zmath"); const Vertex = @import("cube_mesh.zig").Vertex; const vertices = @import("cube_mesh.zig").vertices; -const App = mach.App(*FrameParams, .{}); +const App = @This(); const UniformBufferObject = struct { mat: zm.Mat, @@ -14,15 +14,17 @@ const UniformBufferObject = struct { var timer: std.time.Timer = undefined; -pub fn main() !void { +pipeline: gpu.RenderPipeline, +queue: gpu.Queue, +vertex_buffer: gpu.Buffer, +uniform_buffer: gpu.Buffer, +bind_group: gpu.BindGroup, + +pub fn init(app: *App, engine: *mach.Engine) !void { timer = try std.time.Timer.start(); - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - const ctx = try allocator.create(FrameParams); - var app = try App.init(allocator, ctx, .{}); - - app.window.setKeyCallback(struct { + // TODO: higher level input handlers + engine.core.internal.window.setKeyCallback(struct { fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { _ = scancode; _ = mods; @@ -34,9 +36,9 @@ pub fn main() !void { } } }.callback); - try app.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); + try engine.core.internal.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); - const vs_module = app.device.createShaderModule(&.{ + const vs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my vertex shader", .code = .{ .wgsl = @embedFile("vert.wgsl") }, }); @@ -52,7 +54,7 @@ pub fn main() !void { .attributes = &vertex_attributes, }; - const fs_module = app.device.createShaderModule(&.{ + const fs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my fragment shader", .code = .{ .wgsl = @embedFile("frag.wgsl") }, }); @@ -70,7 +72,7 @@ pub fn main() !void { }, }; const color_target = gpu.ColorTargetState{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .blend = &blend, .write_mask = gpu.ColorWriteMask.all, }; @@ -82,14 +84,14 @@ pub fn main() !void { }; const bgle = gpu.BindGroupLayout.Entry.buffer(0, .{ .vertex = true }, .uniform, true, 0); - const bgl = app.device.createBindGroupLayout( + const bgl = engine.gpu_driver.device.createBindGroupLayout( &gpu.BindGroupLayout.Descriptor{ .entries = &.{bgle}, }, ); const bind_group_layouts = [_]gpu.BindGroupLayout{bgl}; - const pipeline_layout = app.device.createPipelineLayout(&.{ + const pipeline_layout = engine.gpu_driver.device.createPipelineLayout(&.{ .bind_group_layouts = &bind_group_layouts, }); @@ -115,7 +117,7 @@ pub fn main() !void { }, }; - const vertex_buffer = app.device.createBuffer(&.{ + const vertex_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .vertex = true }, .size = @sizeOf(Vertex) * vertices.len, .mapped_at_creation = true, @@ -123,15 +125,13 @@ pub fn main() !void { var vertex_mapped = vertex_buffer.getMappedRange(Vertex, 0, vertices.len); std.mem.copy(Vertex, vertex_mapped, vertices[0..]); vertex_buffer.unmap(); - defer vertex_buffer.release(); - const uniform_buffer = app.device.createBuffer(&.{ + const uniform_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .copy_dst = true, .uniform = true }, .size = @sizeOf(UniformBufferObject), .mapped_at_creation = false, }); - defer uniform_buffer.release(); - const bind_group = app.device.createBindGroup( + const bind_group = engine.gpu_driver.device.createBindGroup( &gpu.BindGroup.Descriptor{ .layout = bgl, .entries = &.{ @@ -139,34 +139,27 @@ pub fn main() !void { }, }, ); - defer bind_group.release(); - ctx.* = FrameParams{ - .pipeline = app.device.createRenderPipeline(&pipeline_descriptor), - .queue = app.device.getQueue(), - .vertex_buffer = vertex_buffer, - .uniform_buffer = uniform_buffer, - .bind_group = bind_group, - }; + app.pipeline = engine.gpu_driver.device.createRenderPipeline(&pipeline_descriptor); + app.queue = engine.gpu_driver.device.getQueue(); + app.vertex_buffer = vertex_buffer; + app.uniform_buffer = uniform_buffer; + app.bind_group = bind_group; vs_module.release(); fs_module.release(); pipeline_layout.release(); bgl.release(); - - try app.run(.{ .frame = frame }); } -const FrameParams = struct { - pipeline: gpu.RenderPipeline, - queue: gpu.Queue, - vertex_buffer: gpu.Buffer, - uniform_buffer: gpu.Buffer, - bind_group: gpu.BindGroup, -}; +pub fn deinit(app: *App, _: *mach.Engine) void { + app.vertex_buffer.release(); + app.uniform_buffer.release(); + app.bind_group.release(); +} -fn frame(app: *App, params: *FrameParams) !void { - const back_buffer_view = app.swap_chain.?.getCurrentTextureView(); +pub fn update(app: *App, engine: *mach.Engine) !bool { + const back_buffer_view = engine.gpu_driver.swap_chain.?.getCurrentTextureView(); const color_attachment = gpu.RenderPassColorAttachment{ .view = back_buffer_view, .resolve_target = null, @@ -175,7 +168,7 @@ fn frame(app: *App, params: *FrameParams) !void { .store_op = .store, }; - const encoder = app.device.createCommandEncoder(null); + const encoder = engine.gpu_driver.device.createCommandEncoder(null); const render_pass_info = gpu.RenderPassEncoder.Descriptor{ .color_attachments = &.{color_attachment}, .depth_stencil_attachment = null, @@ -191,7 +184,7 @@ fn frame(app: *App, params: *FrameParams) !void { ); const proj = zm.perspectiveFovRh( (std.math.pi / 4.0), - @intToFloat(f32, app.current_desc.width) / @intToFloat(f32, app.current_desc.height), + @intToFloat(f32, engine.gpu_driver.current_desc.width) / @intToFloat(f32, engine.gpu_driver.current_desc.height), 0.1, 10, ); @@ -199,13 +192,13 @@ fn frame(app: *App, params: *FrameParams) !void { const ubo = UniformBufferObject{ .mat = zm.transpose(mvp), }; - encoder.writeBuffer(params.uniform_buffer, 0, UniformBufferObject, &.{ubo}); + encoder.writeBuffer(app.uniform_buffer, 0, UniformBufferObject, &.{ubo}); } const pass = encoder.beginRenderPass(&render_pass_info); - pass.setPipeline(params.pipeline); - pass.setVertexBuffer(0, params.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); - pass.setBindGroup(0, params.bind_group, &.{0}); + pass.setPipeline(app.pipeline); + pass.setVertexBuffer(0, app.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); + pass.setBindGroup(0, app.bind_group, &.{0}); pass.draw(vertices.len, 1, 0, 0); pass.end(); pass.release(); @@ -213,8 +206,10 @@ fn frame(app: *App, params: *FrameParams) !void { var command = encoder.finish(null); encoder.release(); - params.queue.submit(&.{command}); + app.queue.submit(&.{command}); command.release(); - app.swap_chain.?.present(); + engine.gpu_driver.swap_chain.?.present(); back_buffer_view.release(); + + return true; } diff --git a/examples/textured-cube/main.zig b/examples/textured-cube/main.zig index bacc6ba9..b4c9ebbf 100644 --- a/examples/textured-cube/main.zig +++ b/examples/textured-cube/main.zig @@ -7,23 +7,26 @@ const zigimg = @import("zigimg"); const Vertex = @import("cube_mesh.zig").Vertex; const vertices = @import("cube_mesh.zig").vertices; -const App = mach.App(*FrameParams, .{}); - const UniformBufferObject = struct { mat: zm.Mat, }; var timer: std.time.Timer = undefined; -pub fn main() !void { +pipeline: gpu.RenderPipeline, +queue: gpu.Queue, +vertex_buffer: gpu.Buffer, +uniform_buffer: gpu.Buffer, +bind_group: gpu.BindGroup, +depth_texture: gpu.Texture, +depth_size: glfw.Window.Size, + +const App = @This(); + +pub fn init(app: *App, engine: *mach.Engine) !void { timer = try std.time.Timer.start(); - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - const ctx = try allocator.create(FrameParams); - var app = try App.init(allocator, ctx, .{}); - - app.window.setKeyCallback(struct { + engine.core.internal.window.setKeyCallback(struct { fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { _ = scancode; _ = mods; @@ -35,9 +38,9 @@ pub fn main() !void { } } }.callback); - try app.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); + try engine.core.internal.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); - const vs_module = app.device.createShaderModule(&.{ + const vs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my vertex shader", .code = .{ .wgsl = @embedFile("vert.wgsl") }, }); @@ -53,7 +56,7 @@ pub fn main() !void { .attributes = &vertex_attributes, }; - const fs_module = app.device.createShaderModule(&.{ + const fs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my fragment shader", .code = .{ .wgsl = @embedFile("frag.wgsl") }, }); @@ -71,7 +74,7 @@ pub fn main() !void { }, }; const color_target = gpu.ColorTargetState{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .blend = &blend, .write_mask = gpu.ColorWriteMask.all, }; @@ -105,9 +108,9 @@ pub fn main() !void { .cull_mode = .back, }, }; - const pipeline = app.device.createRenderPipeline(&pipeline_descriptor); + const pipeline = engine.gpu_driver.device.createRenderPipeline(&pipeline_descriptor); - const vertex_buffer = app.device.createBuffer(&.{ + const vertex_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .vertex = true }, .size = @sizeOf(Vertex) * vertices.len, .mapped_at_creation = true, @@ -115,17 +118,16 @@ pub fn main() !void { var vertex_mapped = vertex_buffer.getMappedRange(Vertex, 0, vertices.len); std.mem.copy(Vertex, vertex_mapped, vertices[0..]); vertex_buffer.unmap(); - defer vertex_buffer.release(); // Create a sampler with linear filtering for smooth interpolation. - const sampler = app.device.createSampler(&.{ + const sampler = engine.gpu_driver.device.createSampler(&.{ .mag_filter = .linear, .min_filter = .linear, }); - const queue = app.device.getQueue(); - const img = try zigimg.Image.fromFilePath(allocator, "examples/assets/gotta-go-fast.png"); + const queue = engine.gpu_driver.device.getQueue(); + const img = try zigimg.Image.fromFilePath(engine.allocator, "examples/assets/gotta-go-fast.png"); const img_size = gpu.Extent3D{ .width = @intCast(u32, img.width), .height = @intCast(u32, img.height) }; - const cube_texture = app.device.createTexture(&.{ + const cube_texture = engine.gpu_driver.device.createTexture(&.{ .size = img_size, .format = .rgba8_unorm, .usage = .{ @@ -141,20 +143,20 @@ pub fn main() !void { switch (img.pixels.?) { .Rgba32 => |pixels| queue.writeTexture(&.{ .texture = cube_texture }, pixels, &data_layout, &img_size), .Rgb24 => |pixels| { - const data = try rgb24ToRgba32(allocator, pixels); + const data = try rgb24ToRgba32(engine.allocator, pixels); //defer data.deinit(allocator); queue.writeTexture(&.{ .texture = cube_texture }, data.Rgba32, &data_layout, &img_size); }, else => @panic("unsupported image color format"), } - const uniform_buffer = app.device.createBuffer(&.{ + const uniform_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .copy_dst = true, .uniform = true }, .size = @sizeOf(UniformBufferObject), .mapped_at_creation = false, }); - defer uniform_buffer.release(); - const bind_group = app.device.createBindGroup( + + const bind_group = engine.gpu_driver.device.createBindGroup( &gpu.BindGroup.Descriptor{ .layout = pipeline.getBindGroupLayout(0), .entries = &.{ @@ -164,10 +166,9 @@ pub fn main() !void { }, }, ); - defer bind_group.release(); - const size = try app.window.getFramebufferSize(); - const depth_texture = app.device.createTexture(&gpu.Texture.Descriptor{ + const size = try engine.core.internal.window.getFramebufferSize(); + const depth_texture = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .size = gpu.Extent3D{ .width = size.width, .height = size.height, @@ -179,37 +180,29 @@ pub fn main() !void { }, }); - ctx.* = FrameParams{ - .pipeline = pipeline, - .queue = queue, - .vertex_buffer = vertex_buffer, - .uniform_buffer = uniform_buffer, - .bind_group = bind_group, - .depth_texture = depth_texture, - .depth_size = size, - }; + app.pipeline = pipeline; + app.queue = queue; + app.vertex_buffer = vertex_buffer; + app.uniform_buffer = uniform_buffer; + app.bind_group = bind_group; + app.depth_texture = depth_texture; + app.depth_size = size; vs_module.release(); fs_module.release(); - - try app.run(.{ .frame = frame }); } -const FrameParams = struct { - pipeline: gpu.RenderPipeline, - queue: gpu.Queue, - vertex_buffer: gpu.Buffer, - uniform_buffer: gpu.Buffer, - bind_group: gpu.BindGroup, - depth_texture: gpu.Texture, - depth_size: glfw.Window.Size, -}; +pub fn deinit(app: *App, _: *mach.Engine) void { + app.vertex_buffer.release(); + app.uniform_buffer.release(); + app.bind_group.release(); +} -fn frame(app: *App, params: *FrameParams) !void { +pub fn update(app: *App, engine: *mach.Engine) !bool { // If window is resized, recreate depth buffer otherwise we cannot use it. - const size = app.window.getFramebufferSize() catch unreachable; // TODO: return type inference can't handle this - if (size.width != params.depth_size.width or size.height != params.depth_size.height) { - params.depth_texture = app.device.createTexture(&gpu.Texture.Descriptor{ + const size = engine.core.internal.window.getFramebufferSize() catch unreachable; // TODO: return type inference can't handle this + if (size.width != app.depth_size.width or size.height != app.depth_size.height) { + app.depth_texture = engine.gpu_driver.device.createTexture(&gpu.Texture.Descriptor{ .size = gpu.Extent3D{ .width = size.width, .height = size.height, @@ -220,10 +213,10 @@ fn frame(app: *App, params: *FrameParams) !void { .texture_binding = true, }, }); - params.depth_size = size; + app.depth_size = size; } - const back_buffer_view = app.swap_chain.?.getCurrentTextureView(); + const back_buffer_view = engine.gpu_driver.swap_chain.?.getCurrentTextureView(); const color_attachment = gpu.RenderPassColorAttachment{ .view = back_buffer_view, .clear_value = .{ .r = 0.5, .g = 0.5, .b = 0.5, .a = 0.0 }, @@ -231,11 +224,11 @@ fn frame(app: *App, params: *FrameParams) !void { .store_op = .store, }; - const encoder = app.device.createCommandEncoder(null); + const encoder = engine.gpu_driver.device.createCommandEncoder(null); const render_pass_info = gpu.RenderPassEncoder.Descriptor{ .color_attachments = &.{color_attachment}, .depth_stencil_attachment = &.{ - .view = params.depth_texture.createView(&gpu.TextureView.Descriptor{ + .view = app.depth_texture.createView(&gpu.TextureView.Descriptor{ .format = .depth24_plus, .dimension = .dimension_2d, .array_layer_count = 1, @@ -257,7 +250,7 @@ fn frame(app: *App, params: *FrameParams) !void { ); const proj = zm.perspectiveFovRh( (std.math.pi / 4.0), - @intToFloat(f32, app.current_desc.width) / @intToFloat(f32, app.current_desc.height), + @intToFloat(f32, engine.gpu_driver.current_desc.width) / @intToFloat(f32, engine.gpu_driver.current_desc.height), 0.1, 10, ); @@ -265,13 +258,13 @@ fn frame(app: *App, params: *FrameParams) !void { const ubo = UniformBufferObject{ .mat = zm.transpose(mvp), }; - encoder.writeBuffer(params.uniform_buffer, 0, UniformBufferObject, &.{ubo}); + encoder.writeBuffer(app.uniform_buffer, 0, UniformBufferObject, &.{ubo}); } const pass = encoder.beginRenderPass(&render_pass_info); - pass.setPipeline(params.pipeline); - pass.setVertexBuffer(0, params.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); - pass.setBindGroup(0, params.bind_group, &.{}); + pass.setPipeline(app.pipeline); + pass.setVertexBuffer(0, app.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); + pass.setBindGroup(0, app.bind_group, &.{}); pass.draw(vertices.len, 1, 0, 0); pass.end(); pass.release(); @@ -279,10 +272,12 @@ fn frame(app: *App, params: *FrameParams) !void { var command = encoder.finish(null); encoder.release(); - params.queue.submit(&.{command}); + app.queue.submit(&.{command}); command.release(); - app.swap_chain.?.present(); + engine.gpu_driver.swap_chain.?.present(); back_buffer_view.release(); + + return true; } fn rgb24ToRgba32(allocator: std.mem.Allocator, in: []zigimg.color.Rgb24) !zigimg.color.ColorStorage { diff --git a/examples/two-cubes/main.zig b/examples/two-cubes/main.zig index 98a7f674..6baab680 100755 --- a/examples/two-cubes/main.zig +++ b/examples/two-cubes/main.zig @@ -6,23 +6,25 @@ const zm = @import("zmath"); const Vertex = @import("cube_mesh.zig").Vertex; const vertices = @import("cube_mesh.zig").vertices; -const App = mach.App(*FrameParams, .{}); - const UniformBufferObject = struct { mat: zm.Mat, }; var timer: std.time.Timer = undefined; -pub fn main() !void { +pipeline: gpu.RenderPipeline, +queue: gpu.Queue, +vertex_buffer: gpu.Buffer, +uniform_buffer: gpu.Buffer, +bind_group1: gpu.BindGroup, +bind_group2: gpu.BindGroup, + +const App = @This(); + +pub fn init(app: *App, engine: *mach.Engine) !void { timer = try std.time.Timer.start(); - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - const ctx = try allocator.create(FrameParams); - var app = try App.init(allocator, ctx, .{}); - - app.window.setKeyCallback(struct { + engine.core.internal.window.setKeyCallback(struct { fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { _ = scancode; _ = mods; @@ -34,9 +36,9 @@ pub fn main() !void { } } }.callback); - try app.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); + try engine.core.internal.window.setSizeLimits(.{ .width = 20, .height = 20 }, .{ .width = null, .height = null }); - const vs_module = app.device.createShaderModule(&.{ + const vs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my vertex shader", .code = .{ .wgsl = @embedFile("vert.wgsl") }, }); @@ -52,7 +54,7 @@ pub fn main() !void { .attributes = &vertex_attributes, }; - const fs_module = app.device.createShaderModule(&.{ + const fs_module = engine.gpu_driver.device.createShaderModule(&.{ .label = "my fragment shader", .code = .{ .wgsl = @embedFile("frag.wgsl") }, }); @@ -70,7 +72,7 @@ pub fn main() !void { }, }; const color_target = gpu.ColorTargetState{ - .format = app.swap_chain_format, + .format = engine.gpu_driver.swap_chain_format, .blend = &blend, .write_mask = gpu.ColorWriteMask.all, }; @@ -82,14 +84,14 @@ pub fn main() !void { }; const bgle = gpu.BindGroupLayout.Entry.buffer(0, .{ .vertex = true }, .uniform, true, 0); - const bgl = app.device.createBindGroupLayout( + const bgl = engine.gpu_driver.device.createBindGroupLayout( &gpu.BindGroupLayout.Descriptor{ .entries = &.{bgle}, }, ); const bind_group_layouts = [_]gpu.BindGroupLayout{bgl}; - const pipeline_layout = app.device.createPipelineLayout(&.{ + const pipeline_layout = engine.gpu_driver.device.createPipelineLayout(&.{ .bind_group_layouts = &bind_group_layouts, }); @@ -115,9 +117,9 @@ pub fn main() !void { }, }; - const queue = app.device.getQueue(); + const queue = engine.gpu_driver.device.getQueue(); - const vertex_buffer = app.device.createBuffer(&.{ + const vertex_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .vertex = true }, .size = @sizeOf(Vertex) * vertices.len, .mapped_at_creation = true, @@ -125,17 +127,16 @@ pub fn main() !void { var vertex_mapped = vertex_buffer.getMappedRange(Vertex, 0, vertices.len); std.mem.copy(Vertex, vertex_mapped, vertices[0..]); vertex_buffer.unmap(); - defer vertex_buffer.release(); // uniformBindGroup offset must be 256-byte aligned const uniform_offset = 256; - const uniform_buffer = app.device.createBuffer(&.{ + const uniform_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .uniform = true, .copy_dst = true }, .size = @sizeOf(UniformBufferObject) + uniform_offset, .mapped_at_creation = false, }); - defer uniform_buffer.release(); - const bind_group1 = app.device.createBindGroup( + + const bind_group1 = engine.gpu_driver.device.createBindGroup( &gpu.BindGroup.Descriptor{ .layout = bgl, .entries = &.{ @@ -143,8 +144,8 @@ pub fn main() !void { }, }, ); - defer bind_group1.release(); - const bind_group2 = app.device.createBindGroup( + + const bind_group2 = engine.gpu_driver.device.createBindGroup( &gpu.BindGroup.Descriptor{ .layout = bgl, .entries = &.{ @@ -152,36 +153,29 @@ pub fn main() !void { }, }, ); - defer bind_group2.release(); - ctx.* = FrameParams{ - .pipeline = app.device.createRenderPipeline(&pipeline_descriptor), - .queue = queue, - .vertex_buffer = vertex_buffer, - .uniform_buffer = uniform_buffer, - .bind_group1 = bind_group1, - .bind_group2 = bind_group2, - }; + app.pipeline = engine.gpu_driver.device.createRenderPipeline(&pipeline_descriptor); + app.queue = queue; + app.vertex_buffer = vertex_buffer; + app.uniform_buffer = uniform_buffer; + app.bind_group1 = bind_group1; + app.bind_group2 = bind_group2; vs_module.release(); fs_module.release(); pipeline_layout.release(); bgl.release(); - - try app.run(.{ .frame = frame }); } -const FrameParams = struct { - pipeline: gpu.RenderPipeline, - queue: gpu.Queue, - vertex_buffer: gpu.Buffer, - uniform_buffer: gpu.Buffer, - bind_group1: gpu.BindGroup, - bind_group2: gpu.BindGroup, -}; +pub fn deinit(app: *App, _: *mach.Engine) void { + app.vertex_buffer.release(); + app.uniform_buffer.release(); + app.bind_group1.release(); + app.bind_group2.release(); +} -fn frame(app: *App, params: *FrameParams) !void { - const back_buffer_view = app.swap_chain.?.getCurrentTextureView(); +pub fn update(app: *App, engine: *mach.Engine) !bool { + const back_buffer_view = engine.gpu_driver.swap_chain.?.getCurrentTextureView(); const color_attachment = gpu.RenderPassColorAttachment{ .view = back_buffer_view, .resolve_target = null, @@ -190,7 +184,7 @@ fn frame(app: *App, params: *FrameParams) !void { .store_op = .store, }; - const encoder = app.device.createCommandEncoder(null); + const encoder = engine.gpu_driver.device.createCommandEncoder(null); const render_pass_info = gpu.RenderPassEncoder.Descriptor{ .color_attachments = &.{color_attachment}, .depth_stencil_attachment = null, @@ -209,7 +203,7 @@ fn frame(app: *App, params: *FrameParams) !void { ); const proj = zm.perspectiveFovRh( (2.0 * std.math.pi / 5.0), - @intToFloat(f32, app.current_desc.width) / @intToFloat(f32, app.current_desc.height), + @intToFloat(f32, engine.gpu_driver.current_desc.width) / @intToFloat(f32, engine.gpu_driver.current_desc.height), 1, 100, ); @@ -222,19 +216,19 @@ fn frame(app: *App, params: *FrameParams) !void { .mat = zm.transpose(mvp2), }; - encoder.writeBuffer(params.uniform_buffer, 0, UniformBufferObject, &.{ubo1}); + encoder.writeBuffer(app.uniform_buffer, 0, UniformBufferObject, &.{ubo1}); // bind_group2 offset - encoder.writeBuffer(params.uniform_buffer, 256, UniformBufferObject, &.{ubo2}); + encoder.writeBuffer(app.uniform_buffer, 256, UniformBufferObject, &.{ubo2}); } const pass = encoder.beginRenderPass(&render_pass_info); - pass.setPipeline(params.pipeline); - pass.setVertexBuffer(0, params.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); + pass.setPipeline(app.pipeline); + pass.setVertexBuffer(0, app.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); - pass.setBindGroup(0, params.bind_group1, &.{0}); + pass.setBindGroup(0, app.bind_group1, &.{0}); pass.draw(vertices.len, 1, 0, 0); - pass.setBindGroup(0, params.bind_group2, &.{0}); + pass.setBindGroup(0, app.bind_group2, &.{0}); pass.draw(vertices.len, 1, 0, 0); pass.end(); @@ -243,8 +237,10 @@ fn frame(app: *App, params: *FrameParams) !void { var command = encoder.finish(null); encoder.release(); - params.queue.submit(&.{command}); + app.queue.submit(&.{command}); command.release(); - app.swap_chain.?.present(); + engine.gpu_driver.swap_chain.?.present(); back_buffer_view.release(); + + return true; }