adding bounded arena allocator to renderer
Build / build (push) Successful in 1m6s
Test / build_and_test (push) Failing after 8h9m28s

This commit is contained in:
2026-05-10 12:28:53 +02:00
parent 7f812bcf39
commit e9454ddd9a
9 changed files with 107 additions and 32 deletions
+73
View File
@@ -0,0 +1,73 @@
const std = @import("std");
const base = @import("base");
const Self = @This();
const Allocator = std.mem.Allocator;
const Alignment = std.mem.Alignment;
mutex: base.SpinMutex,
arena: std.heap.ArenaAllocator,
bound: usize,
pub fn init(child_allocator: Allocator, bound: usize) Self {
return .{
.mutex = .{},
.arena = .init(child_allocator),
.bound = bound,
};
}
pub fn deinit(self: *Self) void {
self.arena.deinit();
}
pub fn allocator(self: *const Self) Allocator {
return .{
.ptr = @ptrCast(@constCast(self)), // Ugly const cast for convenience
.vtable = &.{
.alloc = alloc,
.resize = resize,
.remap = remap,
.free = free,
},
};
}
pub inline fn queryCapacity(self: *Self) usize {
return self.arena.queryCapacity();
}
fn alloc(context: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context));
self.mutex.lock();
defer self.mutex.unlock();
if (self.arena.queryCapacity() >= self.bound)
return null;
return self.arena.allocator().rawAlloc(len, alignment, ret_addr);
}
fn resize(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool {
const self: *Self = @ptrCast(@alignCast(context));
self.mutex.lock();
defer self.mutex.unlock();
if (self.arena.queryCapacity() >= self.bound)
return false;
return self.arena.allocator().rawResize(ptr, alignment, new_len, ret_addr);
}
fn remap(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context));
self.mutex.lock();
defer self.mutex.unlock();
if (self.arena.queryCapacity() >= self.bound)
return null;
return self.arena.allocator().rawRemap(ptr, alignment, new_len, ret_addr);
}
fn free(context: *anyopaque, ptr: []u8, alignment: Alignment, ret_addr: usize) void {
const self: *Self = @ptrCast(@alignCast(context));
self.mutex.lock();
defer self.mutex.unlock();
return self.arena.allocator().rawFree(ptr, alignment, ret_addr);
}
+5 -2
View File
@@ -8,6 +8,7 @@ const spv = @import("spv");
pub const F32x4 = zm.F32x4;
const PipelineState = @import("Device.zig").PipelineState;
const BoundedArenaAllocator = @import("BoundedArenaAllocator.zig");
const SoftBuffer = @import("../SoftBuffer.zig");
const SoftDescriptorSet = @import("../SoftDescriptorSet.zig");
@@ -26,6 +27,8 @@ const VkError = base.VkError;
const Self = @This();
const @"1GiB" = 1_073_741_824;
pub const VertexBuffer = struct {
buffer: *const SoftBuffer,
offset: usize,
@@ -100,7 +103,7 @@ pub fn init(device: *SoftDevice, state: *PipelineState) Self {
pub fn draw(self: *Self, vertex_count: usize, instance_count: usize, first_vertex: usize, first_instance: usize) VkError!void {
const io = self.device.interface.io();
var arena: std.heap.ArenaAllocator = .init(self.device.device_allocator.allocator());
var arena: BoundedArenaAllocator = .init(self.device.device_allocator.allocator(), @"1GiB");
defer arena.deinit();
const allocator = arena.allocator();
@@ -131,7 +134,7 @@ pub fn draw(self: *Self, vertex_count: usize, instance_count: usize, first_verte
pub fn drawIndexed(self: *Self, index_count: usize, instance_count: usize, first_index: usize, first_instance: usize, vertex_offset: i32) VkError!void {
const io = self.device.interface.io();
var arena: std.heap.ArenaAllocator = .init(self.device.device_allocator.allocator());
var arena: BoundedArenaAllocator = .init(self.device.device_allocator.allocator(), @"1GiB");
defer arena.deinit();
const allocator = arena.allocator();
+4 -4
View File
@@ -583,7 +583,7 @@ pub fn readFloat4(map: []const u8, src_format: vk.Format) F32x4 {
.s8_uint => c[0] = @floatFromInt(map[0]),
else => {}, //base.unsupported("Blitter: read float from source format {any}", .{src_format}),
else => base.unsupported("Blitter: read float from source format {any}", .{src_format}),
}
return c;
@@ -637,7 +637,7 @@ pub fn writeFloat4(color: F32x4, map: []u8, dst_format: vk.Format) void {
.r32g32b32a32_sfloat => std.mem.bytesAsValue(F32x4, map).* = color,
else => {}, //base.unsupported("Blitter: write float to destination format {any}", .{dst_format}),
else => base.unsupported("Blitter: write float to destination format {any}", .{dst_format}),
}
}
@@ -678,7 +678,7 @@ pub fn readInt4(map: []const u8, src_format: vk.Format) U32x4 {
.r32g32b32a32_uint,
=> c = std.mem.bytesToValue(U32x4, map),
else => {}, //base.unsupported("Blitter: read int from source format {any}", .{src_format}),
else => base.unsupported("Blitter: read int from source format {any}", .{src_format}),
}
return c;
@@ -720,6 +720,6 @@ pub fn writeInt4(color: U32x4, map: []u8, dst_format: vk.Format) void {
.r32g32b32a32_uint,
=> std.mem.bytesAsValue(U32x4, map).* = color,
else => {}, //base.unsupported("Blitter: write int to destination format {any}", .{dst_format}),
else => base.unsupported("Blitter: write int to destination format {any}", .{dst_format}),
}
}
-2
View File
@@ -167,8 +167,6 @@ pub fn drawTriangleFilled(allocator: std.mem.Allocator, fragments: *std.ArrayLis
.color = zm.f32x4(1.0, 1.0, 1.0, 1.0),
.inputs = try interpolateVertexOutputs(allocator, v0, v1, v2, b0, b1, b2),
}) catch return VkError.OutOfDeviceMemory;
if (fragments.items.len > 64_000)
return VkError.MemoryFootprintTooBigDrv;
}
}
}