Staging buffer

This commit is contained in:
Robin Voetter
2020-07-06 02:35:56 +02:00
parent d3413cbac8
commit 3f63c476b5
2 changed files with 74 additions and 17 deletions

View File

@@ -79,6 +79,7 @@ const DeviceDispatch = struct {
vkCmdSetViewport: vk.PfnCmdSetViewport, vkCmdSetViewport: vk.PfnCmdSetViewport,
vkCmdSetScissor: vk.PfnCmdSetScissor, vkCmdSetScissor: vk.PfnCmdSetScissor,
vkCmdBindVertexBuffers: vk.PfnCmdBindVertexBuffers, vkCmdBindVertexBuffers: vk.PfnCmdBindVertexBuffers,
vkCmdCopyBuffer: vk.PfnCmdCopyBuffer,
usingnamespace vk.DeviceWrapper(@This()); usingnamespace vk.DeviceWrapper(@This());
}; };

View File

@@ -84,35 +84,27 @@ pub fn main() !void {
var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain); var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
defer destroyFramebuffers(&gc, allocator, framebuffers); defer destroyFramebuffers(&gc, allocator, framebuffers);
const pool = try gc.vkd.createCommandPool(gc.dev, .{
.flags = .{},
.queue_family_index = gc.graphics_queue.family,
}, null);
defer gc.vkd.destroyCommandPool(gc.dev, pool, null);
const buffer = try gc.vkd.createBuffer(gc.dev, .{ const buffer = try gc.vkd.createBuffer(gc.dev, .{
.flags = .{}, .flags = .{},
.size = @sizeOf(@TypeOf(vertices)), .size = @sizeOf(@TypeOf(vertices)),
.usage = .{.vertex_buffer_bit = true}, .usage = .{.transfer_dst_bit = true, .vertex_buffer_bit = true},
.sharing_mode = .exclusive, .sharing_mode = .exclusive,
.queue_family_index_count = 0, .queue_family_index_count = 0,
.p_queue_family_indices = undefined, .p_queue_family_indices = undefined,
}, null); }, null);
defer gc.vkd.destroyBuffer(gc.dev, buffer, null); defer gc.vkd.destroyBuffer(gc.dev, buffer, null);
const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, buffer); const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, buffer);
const memory = try gc.allocate(mem_reqs, .{.host_visible_bit = true, .host_coherent_bit = true}); const memory = try gc.allocate(mem_reqs, .{.device_local_bit = true});
defer gc.vkd.freeMemory(gc.dev, memory, null); defer gc.vkd.freeMemory(gc.dev, memory, null);
try gc.vkd.bindBufferMemory(gc.dev, buffer, memory, 0); try gc.vkd.bindBufferMemory(gc.dev, buffer, memory, 0);
{ try uploadVertices(&gc, pool, buffer, memory);
const data = try gc.vkd.mapMemory(gc.dev, memory, 0, vk.WHOLE_SIZE, .{});
defer gc.vkd.unmapMemory(gc.dev, memory);
const gpu_vertices = @ptrCast([*]Vertex, @alignCast(@alignOf(Vertex), data));
for (vertices) |vertex, i| {
gpu_vertices[i] = vertex;
}
}
const pool = try gc.vkd.createCommandPool(gc.dev, .{
.flags = .{},
.queue_family_index = gc.graphics_queue.family,
}, null);
defer gc.vkd.destroyCommandPool(gc.dev, pool, null);
var cmdbufs = try createCommandBuffers( var cmdbufs = try createCommandBuffers(
&gc, &gc,
@@ -165,6 +157,70 @@ pub fn main() !void {
} }
} }
fn uploadVertices(gc: *const GraphicsContext, pool: vk.CommandPool, buffer: vk.Buffer, memory: vk.DeviceMemory) !void {
const staging_buffer = try gc.vkd.createBuffer(gc.dev, .{
.flags = .{},
.size = @sizeOf(@TypeOf(vertices)),
.usage = .{.transfer_src_bit = true},
.sharing_mode = .exclusive,
.queue_family_index_count = 0,
.p_queue_family_indices = undefined,
}, null);
defer gc.vkd.destroyBuffer(gc.dev, staging_buffer, null);
const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, staging_buffer);
const staging_memory = try gc.allocate(mem_reqs, .{.host_visible_bit = true, .host_coherent_bit = true});
defer gc.vkd.freeMemory(gc.dev, staging_memory, null);
try gc.vkd.bindBufferMemory(gc.dev, staging_buffer, staging_memory, 0);
{
const data = try gc.vkd.mapMemory(gc.dev, staging_memory, 0, vk.WHOLE_SIZE, .{});
defer gc.vkd.unmapMemory(gc.dev, staging_memory);
const gpu_vertices = @ptrCast([*]Vertex, @alignCast(@alignOf(Vertex), data));
for (vertices) |vertex, i| {
gpu_vertices[i] = vertex;
}
}
try copyBuffer(gc, pool, buffer, staging_buffer, @sizeOf(@TypeOf(vertices)));
}
fn copyBuffer(gc: *const GraphicsContext, pool: vk.CommandPool, dst: vk.Buffer, src: vk.Buffer, size: vk.DeviceSize) !void {
var cmdbuf: vk.CommandBuffer = undefined;
try gc.vkd.allocateCommandBuffers(gc.dev, .{
.command_pool = pool,
.level = .primary,
.command_buffer_count = 1,
}, @ptrCast([*]vk.CommandBuffer, &cmdbuf));
defer gc.vkd.freeCommandBuffers(gc.dev, pool, 1, @ptrCast([*]const vk.CommandBuffer, &cmdbuf));
try gc.vkd.beginCommandBuffer(cmdbuf, .{
.flags = .{.one_time_submit_bit = true},
.p_inheritance_info = null,
});
const region = vk.BufferCopy{
.src_offset = 0,
.dst_offset = 0,
.size = size,
};
gc.vkd.cmdCopyBuffer(cmdbuf, src, dst, 1, @ptrCast([*]const vk.BufferCopy, &region));
try gc.vkd.endCommandBuffer(cmdbuf);
const si = vk.SubmitInfo{
.wait_semaphore_count = 0,
.p_wait_semaphores = undefined,
.p_wait_dst_stage_mask = undefined,
.command_buffer_count = 1,
.p_command_buffers = @ptrCast([*]const vk.CommandBuffer, &cmdbuf),
.signal_semaphore_count = 0,
.p_signal_semaphores = undefined,
};
try gc.vkd.queueSubmit(gc.graphics_queue.handle, 1, @ptrCast([*]const vk.SubmitInfo, &si), .null_handle);
try gc.vkd.queueWaitIdle(gc.graphics_queue.handle);
}
fn createCommandBuffers( fn createCommandBuffers(
gc: *const GraphicsContext, gc: *const GraphicsContext,
pool: vk.CommandPool, pool: vk.CommandPool,