diff --git a/build.zig b/build.zig index e9d76542..f36f665a 100644 --- a/build.zig +++ b/build.zig @@ -71,6 +71,7 @@ pub fn build(b: *std.build.Builder) void { inline for ([_]ExampleDefinition{ .{ .name = "triangle" }, + .{ .name = "triangle-msaa" }, .{ .name = "boids" }, .{ .name = "rotating-cube", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "two-cubes", .packages = &[_]Pkg{Packages.zmath} }, diff --git a/examples/triangle-msaa/frag.wgsl b/examples/triangle-msaa/frag.wgsl new file mode 100644 index 00000000..285632d5 --- /dev/null +++ b/examples/triangle-msaa/frag.wgsl @@ -0,0 +1,3 @@ +@fragment fn main() -> @location(0) vec4 { + return vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/examples/triangle-msaa/main.zig b/examples/triangle-msaa/main.zig new file mode 100644 index 00000000..de728b41 --- /dev/null +++ b/examples/triangle-msaa/main.zig @@ -0,0 +1,114 @@ +const std = @import("std"); +const mach = @import("mach"); +const gpu = @import("gpu"); + +pub const App = @This(); + +pipeline: *gpu.RenderPipeline, +queue: *gpu.Queue, +texture: *gpu.Texture, +texture_view: *gpu.TextureView, +window_title_timer: mach.Timer, + +const sample_count = 4; + +pub fn init(app: *App, core: *mach.Core) !void { + const vs_module = core.device.createShaderModuleWGSL("vert.wgsl", @embedFile("vert.wgsl")); + const fs_module = core.device.createShaderModuleWGSL("frag.wgsl", @embedFile("frag.wgsl")); + + // Fragment state + const blend = gpu.BlendState{}; + const color_target = gpu.ColorTargetState{ + .format = core.swap_chain_format, + .blend = &blend, + .write_mask = gpu.ColorWriteMaskFlags.all, + }; + const fragment = gpu.FragmentState.init(.{ + .module = fs_module, + .entry_point = "main", + .targets = &.{color_target}, + }); + const pipeline_descriptor = gpu.RenderPipeline.Descriptor{ + .fragment = &fragment, + .vertex = gpu.VertexState{ + .module = vs_module, + .entry_point = "main", + }, + .multisample = gpu.MultisampleState{ + .count = sample_count, + }, + }; + + app.pipeline = core.device.createRenderPipeline(&pipeline_descriptor); + app.queue = core.device.getQueue(); + + app.texture = core.device.createTexture(&gpu.Texture.Descriptor{ + .size = gpu.Extent3D{ + .width = core.current_desc.width, + .height = core.current_desc.height, + }, + .sample_count = sample_count, + .format = core.swap_chain_format, + .usage = .{ .render_attachment = true }, + }); + app.texture_view = app.texture.createView(null); + + vs_module.release(); + fs_module.release(); +} + +pub fn deinit(app: *App, _: *mach.Core) void { + app.texture.release(); + app.texture_view.release(); +} + +pub fn update(app: *App, core: *mach.Core) !void { + const back_buffer_view = core.swap_chain.?.getCurrentTextureView(); + const color_attachment = gpu.RenderPassColorAttachment{ + .view = app.texture_view, + .resolve_target = back_buffer_view, + .clear_value = std.mem.zeroes(gpu.Color), + .load_op = .clear, + .store_op = .discard, + }; + + const encoder = core.device.createCommandEncoder(null); + const render_pass_info = gpu.RenderPassDescriptor.init(.{ + .color_attachments = &.{color_attachment}, + }); + const pass = encoder.beginRenderPass(&render_pass_info); + pass.setPipeline(app.pipeline); + pass.draw(3, 1, 0, 0); + pass.end(); + pass.release(); + + var command = encoder.finish(null); + encoder.release(); + + app.queue.submit(&.{command}); + command.release(); + core.swap_chain.?.present(); + back_buffer_view.release(); + + if (app.window_title_timer.read() >= 1.0) { + const window_title = try std.fmt.allocPrintZ(core.allocator, "FPS: {d}", .{@floatToInt(u32, 1 / core.delta_time)}); + defer core.allocator.free(window_title); + try core.internal.window.setTitle(window_title); + app.window_title_timer.reset(); + } +} + +pub fn resize(app: *App, core: *mach.Core, width: u32, height: u32) !void { + app.texture.release(); + app.texture = core.device.createTexture(&gpu.Texture.Descriptor{ + .size = gpu.Extent3D{ + .width = width, + .height = height, + }, + .sample_count = sample_count, + .format = core.swap_chain_format, + .usage = .{ .render_attachment = true }, + }); + app.texture_view.release(); + app.texture_view = app.texture.createView(null); +} diff --git a/examples/triangle-msaa/vert.wgsl b/examples/triangle-msaa/vert.wgsl new file mode 100644 index 00000000..183333b1 --- /dev/null +++ b/examples/triangle-msaa/vert.wgsl @@ -0,0 +1,10 @@ +@vertex fn main( + @builtin(vertex_index) VertexIndex : u32 +) -> @builtin(position) vec4 { + var pos = array, 3>( + vec2( 0.0, 0.5), + vec2(-0.5, -0.5), + vec2( 0.5, -0.5) + ); + return vec4(pos[VertexIndex], 0.0, 1.0); +}