adding bounded arena allocator to renderer
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user