zig-wgpu/src/GpuAllocator.zig
2026-05-18 00:10:09 +02:00

59 lines
1.6 KiB
Zig

const std = @import("std");
const GpuDevice = @import("GpuDevice.zig");
const GpuBuffer = @import("GpuBuffer.zig");
const c = @import("utils.zig").c;
device: GpuDevice,
tracked_buffers: std.AutoHashMap(c.WGPUBuffer, void),
allocated_vram_bytes: u64 = 0,
pub fn init(cpu_allocator: std.mem.Allocator, device: GpuDevice) !@This() {
return .{
.device = device,
.tracked_buffers = .init(cpu_allocator),
};
}
pub fn deinit(self: *@This()) void {
var it = self.tracked_buffers.keyIterator();
while (it.next()) |buf_ptr| {
const buf = buf_ptr.*;
c.wgpuBufferDestroy(buf);
c.wgpuBufferRelease(buf);
}
self.tracked_buffers.deinit();
}
pub fn registerBuffer(
self: *@This(),
bytes: u64,
usage: c.WGPUBufferUsage,
) !c.WGPUBuffer {
if (bytes > self.device.limits.maxBufferSize)
return error.SingleBufferExceedsLimit;
if (bytes + self.allocated_vram_bytes > self.device.config.vram_bytes_limit)
return error.ExceedsVramBudget;
const buf = c.wgpuDeviceCreateBuffer(self.device.device, &.{
.usage = usage,
.size = bytes,
}) orelse return error.BufferAlloc;
errdefer {
c.wgpuBufferDestroy(buf);
c.wgpuBufferRelease(buf);
}
try self.tracked_buffers.put(buf, {});
self.allocated_vram_bytes += bytes;
return buf;
}
pub fn unregisterAndDestroyBuffer(self: *@This(), buf: GpuBuffer) void {
if (self.tracked_buffers.remove(buf.raw)) {
c.wgpuBufferDestroy(buf.raw);
c.wgpuBufferRelease(buf.raw);
self.allocated_vram_bytes -= buf.size;
}
}