81 lines
2.8 KiB
Zig
81 lines
2.8 KiB
Zig
const std = @import("std");
|
|
const vk = @import("vulkan");
|
|
const base = @import("base");
|
|
|
|
const lib = @import("lib.zig");
|
|
|
|
const VkError = base.VkError;
|
|
const Device = base.Device;
|
|
|
|
const Self = @This();
|
|
pub const Interface = base.Buffer;
|
|
|
|
interface: Interface,
|
|
|
|
pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.BufferCreateInfo) VkError!*Self {
|
|
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
|
errdefer allocator.destroy(self);
|
|
|
|
var interface = try Interface.init(device, allocator, info);
|
|
|
|
interface.vtable = &.{
|
|
.destroy = destroy,
|
|
.getMemoryRequirements = getMemoryRequirements,
|
|
};
|
|
|
|
self.* = .{
|
|
.interface = interface,
|
|
};
|
|
return self;
|
|
}
|
|
|
|
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
|
allocator.destroy(self);
|
|
}
|
|
|
|
pub fn getMemoryRequirements(interface: *Interface, requirements: *vk.MemoryRequirements) void {
|
|
requirements.alignment = lib.MEMORY_REQUIREMENTS_BUFFER_ALIGNMENT;
|
|
if (interface.usage.uniform_texel_buffer_bit or interface.usage.uniform_texel_buffer_bit) {
|
|
requirements.alignment = @max(requirements.alignment, lib.MIN_TEXEL_BUFFER_ALIGNMENT);
|
|
}
|
|
if (interface.usage.storage_buffer_bit) {
|
|
requirements.alignment = @max(requirements.alignment, lib.MIN_STORAGE_BUFFER_ALIGNMENT);
|
|
}
|
|
if (interface.usage.uniform_buffer_bit) {
|
|
requirements.alignment = @max(requirements.alignment, lib.MIN_UNIFORM_BUFFER_ALIGNMENT);
|
|
}
|
|
}
|
|
|
|
pub fn copyBuffer(self: *const Self, dst: *Self, regions: []const vk.BufferCopy) VkError!void {
|
|
for (regions) |region| {
|
|
const src_memory = if (self.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv;
|
|
const dst_memory = if (dst.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv;
|
|
|
|
const src_map: []u8 = @as([*]u8, @ptrCast(try src_memory.map(self.interface.offset + region.src_offset, region.size)))[0..region.size];
|
|
const dst_map: []u8 = @as([*]u8, @ptrCast(try dst_memory.map(dst.interface.offset + region.dst_offset, region.size)))[0..region.size];
|
|
|
|
@memcpy(dst_map, src_map);
|
|
|
|
src_memory.unmap();
|
|
dst_memory.unmap();
|
|
}
|
|
}
|
|
|
|
pub fn fillBuffer(self: *Self, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
|
const memory = if (self.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv;
|
|
var memory_map: []u32 = @as([*]u32, @ptrCast(@alignCast(try memory.map(offset, size))))[0..size];
|
|
|
|
var bytes = if (size == vk.WHOLE_SIZE) memory.size - offset else size;
|
|
|
|
var i: usize = 0;
|
|
while (bytes >= 4) : ({
|
|
bytes -= 4;
|
|
i += 1;
|
|
}) {
|
|
memory_map[i] = data;
|
|
}
|
|
|
|
memory.unmap();
|
|
}
|