Use staging buffer with the vertex buffer

This commit is contained in:
Timothy Warren 2023-04-12 13:48:07 -04:00
parent f7ada5471d
commit c1b448433a
2 changed files with 73 additions and 7 deletions

View File

@ -6,3 +6,16 @@ default:
compile-shaders: compile-shaders:
glslc shaders/shader.vert -o shaders/vert.spv glslc shaders/shader.vert -o shaders/vert.spv
glslc shaders/shader.frag -o shaders/frag.spv glslc shaders/shader.frag -o shaders/frag.spv
# Cargo fmt
fmt:
cargo fmt
# Checks
check:
cargo check
cargo clippy
# Cargo fix
fix:
cargo fix

View File

@ -542,7 +542,7 @@ impl AppData {
// Buffers // Buffers
//================================================ //================================================
pub(super) unsafe fn create_buffer( unsafe fn create_buffer(
&self, &self,
instance: &Instance, instance: &Instance,
device: &Device, device: &Device,
@ -570,28 +570,81 @@ impl AppData {
Ok((buffer, buffer_memory)) Ok((buffer, buffer_memory))
} }
unsafe fn copy_buffer(
&self,
device: &Device,
source: vk::Buffer,
destination: vk::Buffer,
size: vk::DeviceSize,
) -> Result<()> {
// Create the command buffer
let info = vk::CommandBufferAllocateInfo::builder()
.level(vk::CommandBufferLevel::PRIMARY)
.command_pool(self.command_pool)
.command_buffer_count(1);
let command_buffer = device.allocate_command_buffers(&info)?[0];
let info = vk::CommandBufferBeginInfo::builder()
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT);
device.begin_command_buffer(command_buffer, &info)?;
let regions = vk::BufferCopy::builder().size(size);
device.cmd_copy_buffer(command_buffer, source, destination, &[regions]);
device.end_command_buffer(command_buffer)?;
// Execute command buffer
let command_buffers = &[command_buffer];
let info = vk::SubmitInfo::builder().command_buffers(command_buffers);
device.queue_submit(self.graphics_queue, &[info], vk::Fence::null())?;
device.queue_wait_idle(self.graphics_queue)?;
device.free_command_buffers(self.command_pool, &[command_buffer]);
Ok(())
}
pub(super) unsafe fn create_vertex_buffer( pub(super) unsafe fn create_vertex_buffer(
&mut self, &mut self,
instance: &Instance, instance: &Instance,
device: &Device, device: &Device,
) -> Result<()> { ) -> Result<()> {
// Create staging buffer
let size = (size_of::<Vertex>() * VERTICES.len()) as u64; let size = (size_of::<Vertex>() * VERTICES.len()) as u64;
let (staging_buffer, staging_buffer_memory) = self.create_buffer(
instance,
device,
size,
vk::BufferUsageFlags::TRANSFER_SRC,
vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE,
)?;
let memory =
device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?;
memcpy(VERTICES.as_ptr(), memory.cast(), VERTICES.len());
device.unmap_memory(staging_buffer_memory);
// Create vertex buffer
let (vertex_buffer, vertex_buffer_memory) = self.create_buffer( let (vertex_buffer, vertex_buffer_memory) = self.create_buffer(
instance, instance,
device, device,
size, size,
vk::BufferUsageFlags::VERTEX_BUFFER, vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::VERTEX_BUFFER,
vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, vk::MemoryPropertyFlags::DEVICE_LOCAL,
)?; )?;
self.vertex_buffer = vertex_buffer; self.vertex_buffer = vertex_buffer;
self.vertex_buffer_memory = vertex_buffer_memory; self.vertex_buffer_memory = vertex_buffer_memory;
let memory = // Copy to the vertex buffer
device.map_memory(vertex_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?; self.copy_buffer(device, staging_buffer, vertex_buffer, size)?;
memcpy(VERTICES.as_ptr(), memory.cast(), VERTICES.len()); // cleanup
device.unmap_memory(vertex_buffer_memory); device.destroy_buffer(staging_buffer, None);
device.free_memory(staging_buffer_memory, None);
Ok(()) Ok(())
} }