Files
VulkanDriver/src/soft/SoftBuffer.zig
Kbz-8 b13d9cb4c9
Some checks failed
Build / build (push) Successful in 1m11s
Test / build_and_test (push) Failing after 3h3m41s
working compute pipelines
2026-02-26 03:12:47 +01:00

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();
}