Moved read stuff to GpuBuffer directly
This commit is contained in:
parent
2673aef0fd
commit
d5e7f60926
@ -22,22 +22,16 @@ const BufferUsage = enum(u64) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Allocates the underlying WebGPU handle and registers it to the parent GpuAllocator
|
/// Allocates the underlying WebGPU handle and registers it to the parent GpuAllocator
|
||||||
pub fn init(gloc: GpuAllocator, T: type, len: usize, usage: std.EnumSet(BufferUsage)) !@This() {
|
pub fn init(gloc: GpuAllocator, size: u64, usage: std.EnumSet(BufferUsage)) !@This() {
|
||||||
switch (@typeInfo(T)) {
|
|
||||||
.int, .float => {},
|
|
||||||
else => @compileError("GpuBuffer can only use int and float type"),
|
|
||||||
}
|
|
||||||
|
|
||||||
var use: u64 = 0;
|
var use: u64 = 0;
|
||||||
var iter = usage.iterator();
|
var iter = usage.iterator();
|
||||||
while (iter.next()) |flag| use |= @intFromEnum(flag);
|
while (iter.next()) |flag| use |= @intFromEnum(flag);
|
||||||
|
|
||||||
const bytes = @sizeOf(T) * len;
|
const raw_handle = try gloc.allocBuffer(size, use);
|
||||||
const raw_handle = try gloc.allocBuffer(bytes, use);
|
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.raw = raw_handle,
|
.raw = raw_handle,
|
||||||
.size = bytes,
|
.size = size,
|
||||||
.usage = use,
|
.usage = use,
|
||||||
.gloc = gloc,
|
.gloc = gloc,
|
||||||
};
|
};
|
||||||
@ -48,6 +42,11 @@ pub fn deinit(self: @This()) void {
|
|||||||
self.gloc.freeBuffer(self.raw, self.size);
|
self.gloc.freeBuffer(self.raw, self.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Native getConstMappedRange wrapper
|
||||||
|
pub fn getConstMappedRange(self: @This(), offset: u64, size: u64) ?*const anyopaque {
|
||||||
|
return c.wgpuBufferGetConstMappedRange(self.raw, offset, size);
|
||||||
|
}
|
||||||
|
|
||||||
/// Native mapAsync wrapper
|
/// Native mapAsync wrapper
|
||||||
pub fn mapAsync(
|
pub fn mapAsync(
|
||||||
self: @This(),
|
self: @This(),
|
||||||
@ -59,11 +58,6 @@ pub fn mapAsync(
|
|||||||
_ = c.wgpuBufferMapAsync(self.raw, mode, offset, size, callback_info);
|
_ = c.wgpuBufferMapAsync(self.raw, mode, offset, size, callback_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Native getConstMappedRange wrapper
|
|
||||||
pub fn getConstMappedRange(self: @This(), offset: u64, size: u64) ?*const anyopaque {
|
|
||||||
return c.wgpuBufferGetConstMappedRange(self.raw, offset, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Native unmap wrapper
|
/// Native unmap wrapper
|
||||||
pub fn unmap(self: @This()) void {
|
pub fn unmap(self: @This()) void {
|
||||||
c.wgpuBufferUnmap(self.raw);
|
c.wgpuBufferUnmap(self.raw);
|
||||||
@ -76,3 +70,48 @@ pub fn load(
|
|||||||
) !void {
|
) !void {
|
||||||
c.wgpuQueueWriteBuffer(self.gloc.device.queue, self.raw, 0, data.ptr, self.size);
|
c.wgpuQueueWriteBuffer(self.gloc.device.queue, self.raw, 0, data.ptr, self.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read(self: @This(), alloc: std.mem.Allocator, T: type) ![]f16 {
|
||||||
|
const out = try alloc.alloc(T, @divExact(self.size, @sizeOf(T)));
|
||||||
|
|
||||||
|
const staging = try init(
|
||||||
|
self.gloc,
|
||||||
|
self.size,
|
||||||
|
.initMany(&.{ .MapRead, .CopyDst }),
|
||||||
|
);
|
||||||
|
defer staging.deinit();
|
||||||
|
|
||||||
|
const enc = c.wgpuDeviceCreateCommandEncoder(self.gloc.device.device, null) orelse return error.Encoder;
|
||||||
|
c.wgpuCommandEncoderCopyBufferToBuffer(enc, self.raw, 0, staging.raw, 0, self.size);
|
||||||
|
const cmd = c.wgpuCommandEncoderFinish(enc, null);
|
||||||
|
defer c.wgpuCommandEncoderRelease(enc);
|
||||||
|
defer c.wgpuCommandBufferRelease(cmd);
|
||||||
|
c.wgpuQueueSubmit(self.gloc.device.queue, 1, &cmd);
|
||||||
|
|
||||||
|
var mapped = false;
|
||||||
|
staging.mapAsync(
|
||||||
|
c.WGPUMapMode_Read,
|
||||||
|
0,
|
||||||
|
self.size,
|
||||||
|
.{ .callback = onMapped, .userdata1 = &mapped },
|
||||||
|
);
|
||||||
|
while (!mapped) self.gloc.device.poll();
|
||||||
|
|
||||||
|
const ptr: [*]const T = @ptrCast(@alignCast(
|
||||||
|
staging.getConstMappedRange(0, self.size),
|
||||||
|
));
|
||||||
|
@memcpy(out[0..out.len], ptr[0..out.len]);
|
||||||
|
staging.unmap();
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn onMapped(
|
||||||
|
status: c.WGPUMapAsyncStatus,
|
||||||
|
_: c.WGPUStringView,
|
||||||
|
userdata1: ?*anyopaque,
|
||||||
|
_: ?*anyopaque,
|
||||||
|
) callconv(.c) void {
|
||||||
|
const flag: *bool = @ptrCast(@alignCast(userdata1.?));
|
||||||
|
flag.* = (status == c.WGPUMapAsyncStatus_Success);
|
||||||
|
}
|
||||||
|
|||||||
43
src/Vec.zig
43
src/Vec.zig
@ -15,8 +15,7 @@ pub fn initZero(gloc: GpuAllocator, len: usize) !Vec {
|
|||||||
return .{
|
return .{
|
||||||
.buf = try GpuBuffer.init(
|
.buf = try GpuBuffer.init(
|
||||||
gloc,
|
gloc,
|
||||||
f16,
|
len * @sizeOf(f16),
|
||||||
len,
|
|
||||||
.initMany(&.{ .Storage, .CopyDst, .CopySrc }),
|
.initMany(&.{ .Storage, .CopyDst, .CopySrc }),
|
||||||
),
|
),
|
||||||
.len = len,
|
.len = len,
|
||||||
@ -59,41 +58,8 @@ pub fn run(self: Vec, gloc: GpuAllocator, other: Vec, pip: GpuPipeline) !Vec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Changed: gloc is passed by value instead of *GpuAllocator
|
// Changed: gloc is passed by value instead of *GpuAllocator
|
||||||
pub fn read(self: Vec, gloc: GpuAllocator, alloc: std.mem.Allocator) ![]f16 {
|
pub fn read(self: Vec, alloc: std.mem.Allocator) ![]f16 {
|
||||||
const out = try alloc.alloc(f16, self.len);
|
return self.buf.read(alloc, f16);
|
||||||
const bytes = self.byteSize();
|
|
||||||
|
|
||||||
const staging = try GpuBuffer.init(
|
|
||||||
gloc,
|
|
||||||
f16,
|
|
||||||
self.len,
|
|
||||||
.initMany(&.{ .MapRead, .CopyDst }),
|
|
||||||
);
|
|
||||||
defer staging.deinit();
|
|
||||||
|
|
||||||
const enc = c.wgpuDeviceCreateCommandEncoder(gloc.device.device, null) orelse return error.Encoder;
|
|
||||||
c.wgpuCommandEncoderCopyBufferToBuffer(enc, self.buf.raw, 0, staging.raw, 0, bytes);
|
|
||||||
const cmd = c.wgpuCommandEncoderFinish(enc, null);
|
|
||||||
defer c.wgpuCommandEncoderRelease(enc);
|
|
||||||
defer c.wgpuCommandBufferRelease(cmd);
|
|
||||||
c.wgpuQueueSubmit(gloc.device.queue, 1, &cmd);
|
|
||||||
|
|
||||||
var mapped = false;
|
|
||||||
staging.mapAsync(
|
|
||||||
c.WGPUMapMode_Read,
|
|
||||||
0,
|
|
||||||
bytes,
|
|
||||||
.{ .callback = onMapped, .userdata1 = &mapped },
|
|
||||||
);
|
|
||||||
while (!mapped) gloc.device.poll();
|
|
||||||
|
|
||||||
const ptr: [*]const f16 = @ptrCast(@alignCast(
|
|
||||||
staging.getConstMappedRange(0, bytes),
|
|
||||||
));
|
|
||||||
@memcpy(out[0..self.len], ptr[0..self.len]);
|
|
||||||
staging.unmap();
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn onMapped(
|
fn onMapped(
|
||||||
@ -124,8 +90,7 @@ fn dispatch2in1out(
|
|||||||
|
|
||||||
const info_buf = try GpuBuffer.init(
|
const info_buf = try GpuBuffer.init(
|
||||||
gloc,
|
gloc,
|
||||||
u32,
|
@sizeOf(u32),
|
||||||
1,
|
|
||||||
.initMany(&.{ .Uniform, .CopyDst }),
|
.initMany(&.{ .Uniform, .CopyDst }),
|
||||||
);
|
);
|
||||||
defer info_buf.deinit();
|
defer info_buf.deinit();
|
||||||
|
|||||||
@ -41,7 +41,7 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
|
|
||||||
std.debug.print("Bytes used: {d} (3 * {d})\n", .{ grena.allocated_vram_bytes, a.byteSize() });
|
std.debug.print("Bytes used: {d} (3 * {d})\n", .{ grena.allocated_vram_bytes, a.byteSize() });
|
||||||
|
|
||||||
const out = try sum.read(gloc, allocator);
|
const out = try sum.read(allocator);
|
||||||
defer allocator.free(out);
|
defer allocator.free(out);
|
||||||
|
|
||||||
std.debug.print("{any}\n", .{out});
|
std.debug.print("{any}\n", .{out});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user