diff --git a/README.md b/README.md index bebffc5..8991850 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ vkCmdExecuteCommands | ✅ Implemented vkCmdFillBuffer | ✅ Implemented vkCmdNextSubpass | ⚙️ WIP vkCmdPipelineBarrier | ✅ Implemented -vkCmdPushConstants | ⚙️ WIP +vkCmdPushConstants | ✅ Implemented vkCmdResetEvent | ✅ Implemented vkCmdResetQueryPool | ⚙️ WIP vkCmdResolveImage | ⚙️ WIP @@ -82,7 +82,7 @@ vkCmdSetDepthBias | ⚙️ WIP vkCmdSetDepthBounds | ⚙️ WIP vkCmdSetEvent | ✅ Implemented vkCmdSetLineWidth | ⚙️ WIP -vkCmdSetScissor | ⚙️ WIP +vkCmdSetScissor | ✅ Implemented vkCmdSetStencilCompareMask | ⚙️ WIP vkCmdSetStencilReference | ⚙️ WIP vkCmdSetStencilWriteMask | ⚙️ WIP diff --git a/build.zig.zon b/build.zig.zon index 0d5f865..2084a29 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -31,8 +31,8 @@ .lazy = true, }, .SPIRV_Interpreter = .{ - .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#c0825d53158cd5a5fc38f12d155d1158efc9b371", - .hash = "SPIRV_Interpreter-0.0.1-ajmpn0RFBQBe3oaZ5-aVNJQ7FMancJXlmCNt7mYUP5WP", + .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#dc80a6a3484667058194dc0540c2a15ba76ce2d9", + .hash = "SPIRV_Interpreter-0.0.1-ajmpnwNEBQA6scXu7V71PS-UV6wZtRut9vDh3PxrtW53", .lazy = true, }, //.SPIRV_Interpreter = .{ diff --git a/src/soft/device/BoundedAllocator.zig b/src/soft/device/BoundedAllocator.zig index 37d3257..56c9785 100644 --- a/src/soft/device/BoundedAllocator.zig +++ b/src/soft/device/BoundedAllocator.zig @@ -10,6 +10,7 @@ mutex: base.SpinMutex, child_allocator: std.mem.Allocator, bound: usize, total_bytes_allocated: std.atomic.Value(usize), +peak_concurrent_bytes_allocated: std.atomic.Value(usize), current_bytes_allocated: std.atomic.Value(usize), pub fn init(child_allocator: Allocator, bound: usize) Self { @@ -19,6 +20,7 @@ pub fn init(child_allocator: Allocator, bound: usize) Self { .bound = bound, .total_bytes_allocated = std.atomic.Value(usize).init(0), .current_bytes_allocated = std.atomic.Value(usize).init(0), + .peak_concurrent_bytes_allocated = std.atomic.Value(usize).init(0), }; } @@ -38,6 +40,10 @@ pub inline fn queryFootprint(self: *Self) usize { return self.total_bytes_allocated.load(.monotonic); } +pub inline fn queryPeakFootprint(self: *Self) usize { + return self.peak_concurrent_bytes_allocated.load(.monotonic); +} + fn alloc(context: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8 { const self: *Self = @ptrCast(@alignCast(context)); self.mutex.lock(); @@ -45,6 +51,8 @@ fn alloc(context: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) if (self.current_bytes_allocated.fetchAdd(len, .monotonic) >= self.bound) return null; _ = self.total_bytes_allocated.fetchAdd(len, .monotonic); + if (self.current_bytes_allocated.load(.monotonic) > self.peak_concurrent_bytes_allocated.load(.monotonic)) + self.peak_concurrent_bytes_allocated.store(self.current_bytes_allocated.load(.monotonic), .monotonic); return self.child_allocator.rawAlloc(len, alignment, ret_addr); } diff --git a/src/soft/device/Renderer.zig b/src/soft/device/Renderer.zig index fe2a215..d60b744 100644 --- a/src/soft/device/Renderer.zig +++ b/src/soft/device/Renderer.zig @@ -65,6 +65,10 @@ pub const DrawCall = struct { render_pass: *SoftRenderPass, framebuffer: *SoftFramebuffer, + stats: struct { + polygons_drawn: usize, + }, + fn init(allocator: std.mem.Allocator, vertex_count: usize, instance_count: usize, renderer: *Self) VkError!@This() { const framebuffer = renderer.framebuffer orelse return VkError.InvalidHandleDrv; const render_pass = renderer.render_pass orelse return VkError.InvalidHandleDrv; @@ -78,6 +82,9 @@ pub const DrawCall = struct { .depth_attachment = if (render_pass.interface.subpasses[0].depth_stencil_attachments) |desc| framebuffer.interface.attachments[desc.attachment] else null, .render_pass = render_pass, .framebuffer = framebuffer, + .stats = .{ + .polygons_drawn = 0, + }, }; for (self.vertices) |*vertex| { @@ -146,11 +153,27 @@ fn drawCall(self: *Self, bounded_allocator: *BoundedAllocator, vertex_count: usi const duration = timer.untilNow(io, .real); const ms: f32 = @floatFromInt(duration.toMicroseconds()); const memory_footprint = @divTrunc(bounded_allocator.queryFootprint(), 1000); + const peak_memory_footprint = @divTrunc(bounded_allocator.queryPeakFootprint(), 1000); + + const fmt = + \\Drawcall stats: + \\> Took {d:.3}ms + \\> Total allocation of {d} KB + \\> Peak concurrent allocation of {d} KB + \\> Total polygons drawn {d} + ; + const args = .{ + ms / 1000, + memory_footprint, + peak_memory_footprint, + draw_call.stats.polygons_drawn, + }; + const logger = std.log.scoped(.SoftwareRenderer); if (memory_footprint > 256_000) - logger.warn("Drawcall stats:\n> Took {d:.3}ms\n> Allocated {d} KB", .{ ms / 1000, memory_footprint }) + logger.warn(fmt, args) else - logger.debug("Drawcall stats:\n> Took {d:.3}ms\n> Allocated {d} KB", .{ ms / 1000, memory_footprint }); + logger.debug(fmt, args); }; self.vertexShaderStage(allocator, &draw_call, vertex_count, instance_count, first_vertex, first_instance, indices) catch |err| { diff --git a/src/soft/device/rasterizer.zig b/src/soft/device/rasterizer.zig index 5577edc..8a31751 100644 --- a/src/soft/device/rasterizer.zig +++ b/src/soft/device/rasterizer.zig @@ -74,6 +74,8 @@ fn rasterizeTriangle(renderer: *Renderer, allocator: std.mem.Allocator, draw_cal if (try triangleIsCulled(renderer, v0, v1, v2)) return; + draw_call.stats.polygons_drawn += 1; + const pipeline_data = (renderer.state.pipeline orelse return VkError.InvalidHandleDrv).interface.mode.graphics; switch (pipeline_data.rasterization.polygon_mode) { .fill => try edge_function.drawTriangle(allocator, draw_call, v0, v1, v2),