86 lines
2.8 KiB
Zig
86 lines
2.8 KiB
Zig
const IndexBuffer = @This();
|
|
const std = @import("std");
|
|
|
|
const vk = @import("vulkan");
|
|
|
|
const Engine = @import("Engine.zig");
|
|
const StagingBuffer = @import("StagingBuffer.zig");
|
|
const QSM = @import("QueueSharingMode.zig");
|
|
|
|
buffer: vk.Buffer,
|
|
memory: vk.DeviceMemory,
|
|
index_count: usize,
|
|
|
|
pub fn init(engine: *Engine, index_count: usize) !IndexBuffer {
|
|
const size = std.math.mul(usize, index_count, @sizeOf(u16)) catch return error.OutOfMemory;
|
|
|
|
const qsm = QSM.resolve(engine.graphics_queue.allocation.family, engine.transfer_queue.allocation.family);
|
|
const buffer = try engine.device.createBuffer(&.{
|
|
.size = size,
|
|
.usage = .{
|
|
.transfer_dst_bit = true,
|
|
.index_buffer_bit = true,
|
|
},
|
|
.sharing_mode = qsm.sharing_mode,
|
|
.queue_family_index_count = qsm.queue_family_index_count,
|
|
.p_queue_family_indices = qsm.p_queue_family_indices,
|
|
}, &engine.vk_allocator.interface);
|
|
errdefer engine.device.destroyBuffer(buffer);
|
|
|
|
const memory_requirements = engine.device.getBufferMemoryRequirements(buffer);
|
|
const memory = try engine.allocate(memory_requirements, .{ .device_local_bit = true });
|
|
errdefer engine.device.freeMemory(memory, &engine.vk_allocator.interface);
|
|
|
|
try engine.device.bindBufferMemory(buffer, memory, 0);
|
|
|
|
return .{
|
|
.buffer = buffer,
|
|
.memory = memory,
|
|
.index_count = index_count,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *IndexBuffer, engine: *Engine) void {
|
|
engine.device.freeMemory(self.memory, &engine.vk_allocator.interface);
|
|
engine.device.destroyBuffer(self.buffer);
|
|
|
|
self.* = undefined;
|
|
}
|
|
|
|
pub fn write(self: IndexBuffer, engine: *Engine, indices: []const u16) !void {
|
|
std.debug.assert(indices.len == self.index_count);
|
|
|
|
const fence = try engine.device.createFence(.{}, &engine.vk_allocator.interface);
|
|
defer engine.device.destroyFence(fence, &engine.vk_allocator.interface);
|
|
|
|
const size = std.mem.sliceAsBytes(indices).len;
|
|
|
|
const staging_buffer: StagingBuffer = .init(engine, std.mem.sliceAsBytes(indices), engine.graphics_queue.allocation.family);
|
|
defer staging_buffer.deinit(engine);
|
|
|
|
const command_buffer = try engine.allocateTransferCommandBuffer();
|
|
defer engine.freeTransferCommandBuffer(command_buffer);
|
|
|
|
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
|
|
|
const regions = [_]vk.BufferCopy{
|
|
.{
|
|
.src_offset = 0,
|
|
.dst_offset = 0,
|
|
.size = size,
|
|
},
|
|
};
|
|
|
|
command_buffer.copyBuffer(
|
|
staging_buffer.buffer,
|
|
self.buffer,
|
|
regions.len,
|
|
®ions,
|
|
);
|
|
|
|
try command_buffer.endCommandBuffer();
|
|
try engine.submitTransferCommandBuffer(command_buffer, fence);
|
|
|
|
_ = try engine.device.waitForFences(1, @ptrCast(&fence), .true, std.math.maxInt(u64));
|
|
}
|