Compare commits
2 commits
9b5a011afc
...
f7f428aa28
Author | SHA1 | Date | |
---|---|---|---|
f7f428aa28 | |||
3e12361e85 |
1 changed files with 167 additions and 59 deletions
222
src/main.rs
222
src/main.rs
|
@ -1609,84 +1609,61 @@ impl VulkanApp {
|
|||
}
|
||||
|
||||
fn create_vertex_buffer(&mut self) -> Result<(), String> {
|
||||
let mut buffer_info: ffi::VkBufferCreateInfo = unsafe { std::mem::zeroed() };
|
||||
let buffer_size: ffi::VkDeviceSize =
|
||||
(std::mem::size_of::<Vertex>() * VERTICES.len()) as u64;
|
||||
|
||||
buffer_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buffer_info.size = (std::mem::size_of::<Vertex>() * VERTICES.len()) as u64;
|
||||
buffer_info.usage = ffi::VkBufferUsageFlagBits_VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
buffer_info.sharingMode = ffi::VkSharingMode_VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
let result = unsafe {
|
||||
ffi::vkCreateBuffer(
|
||||
self.device,
|
||||
std::ptr::addr_of!(buffer_info),
|
||||
std::ptr::null(),
|
||||
std::ptr::addr_of_mut!(self.vertex_buffer),
|
||||
)
|
||||
};
|
||||
if result != ffi::VkResult_VK_SUCCESS {
|
||||
return Err(String::from("Failed to create vertex buffer!"));
|
||||
}
|
||||
|
||||
let mut mem_reqs: ffi::VkMemoryRequirements = unsafe { std::mem::zeroed() };
|
||||
unsafe {
|
||||
ffi::vkGetBufferMemoryRequirements(
|
||||
self.device,
|
||||
self.vertex_buffer,
|
||||
std::ptr::addr_of_mut!(mem_reqs),
|
||||
);
|
||||
}
|
||||
|
||||
let mut alloc_info: ffi::VkMemoryAllocateInfo = unsafe { std::mem::zeroed() };
|
||||
alloc_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = mem_reqs.size;
|
||||
alloc_info.memoryTypeIndex = self.find_memory_type(
|
||||
mem_reqs.memoryTypeBits,
|
||||
let (staging_buffer, staging_buffer_mem) = self.create_buffer(
|
||||
buffer_size,
|
||||
ffi::VkBufferUsageFlagBits_VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
ffi::VkMemoryPropertyFlagBits_VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||
| ffi::VkMemoryPropertyFlagBits_VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
)?;
|
||||
|
||||
let result = unsafe {
|
||||
ffi::vkAllocateMemory(
|
||||
self.device,
|
||||
std::ptr::addr_of!(alloc_info),
|
||||
std::ptr::null(),
|
||||
std::ptr::addr_of_mut!(self.vertex_buffer_memory),
|
||||
)
|
||||
};
|
||||
if result != ffi::VkResult_VK_SUCCESS {
|
||||
return Err(String::from("Failed to allocate vertex buffer memory!"));
|
||||
struct CleanupStaging {
|
||||
device: ffi::VkDevice,
|
||||
staging_buf: ffi::VkBuffer,
|
||||
staging_buf_mem: ffi::VkDeviceMemory,
|
||||
}
|
||||
|
||||
impl Drop for CleanupStaging {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::vkBindBufferMemory(
|
||||
self.device,
|
||||
self.vertex_buffer,
|
||||
self.vertex_buffer_memory,
|
||||
0,
|
||||
);
|
||||
ffi::vkDestroyBuffer(self.device, self.staging_buf, std::ptr::null());
|
||||
ffi::vkFreeMemory(self.device, self.staging_buf_mem, std::ptr::null());
|
||||
}
|
||||
}
|
||||
}
|
||||
let _cleanup_staging = CleanupStaging {
|
||||
device: self.device,
|
||||
staging_buf: staging_buffer,
|
||||
staging_buf_mem: staging_buffer_mem,
|
||||
};
|
||||
|
||||
let mut data_ptr: *mut c_void = unsafe { std::mem::zeroed() };
|
||||
unsafe {
|
||||
ffi::vkMapMemory(
|
||||
self.device,
|
||||
self.vertex_buffer_memory,
|
||||
staging_buffer_mem,
|
||||
0,
|
||||
buffer_info.size,
|
||||
buffer_size,
|
||||
0,
|
||||
std::ptr::addr_of_mut!(data_ptr),
|
||||
);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let data_ptr_vertices: *mut [Vertex; 3] = std::mem::transmute(data_ptr);
|
||||
*data_ptr_vertices = VERTICES;
|
||||
ffi::vkUnmapMemory(self.device, staging_buffer_mem);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ffi::vkUnmapMemory(self.device, self.vertex_buffer_memory);
|
||||
}
|
||||
let (buffer, buffer_mem) = self.create_buffer(
|
||||
buffer_size,
|
||||
ffi::VkBufferUsageFlagBits_VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| ffi::VkBufferUsageFlagBits_VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
ffi::VkMemoryPropertyFlagBits_VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
)?;
|
||||
|
||||
self.vertex_buffer = buffer;
|
||||
self.vertex_buffer_memory = buffer_mem;
|
||||
|
||||
self.copy_buffer(staging_buffer, self.vertex_buffer, buffer_size)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1746,6 +1723,137 @@ impl VulkanApp {
|
|||
|
||||
Ok((vertex_input_info, bind_desc, attr_descs))
|
||||
}
|
||||
|
||||
fn create_buffer(
|
||||
&mut self,
|
||||
size: ffi::VkDeviceSize,
|
||||
usage: ffi::VkBufferUsageFlags,
|
||||
properties: ffi::VkMemoryPropertyFlags,
|
||||
) -> Result<(ffi::VkBuffer, ffi::VkDeviceMemory), String> {
|
||||
let mut buffer_info: ffi::VkBufferCreateInfo = unsafe { std::mem::zeroed() };
|
||||
buffer_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buffer_info.size = size;
|
||||
buffer_info.usage = usage;
|
||||
buffer_info.sharingMode = ffi::VkSharingMode_VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
let mut buffer: ffi::VkBuffer = std::ptr::null_mut();
|
||||
let result = unsafe {
|
||||
ffi::vkCreateBuffer(
|
||||
self.device,
|
||||
std::ptr::addr_of!(buffer_info),
|
||||
std::ptr::null(),
|
||||
std::ptr::addr_of_mut!(buffer),
|
||||
)
|
||||
};
|
||||
if result != ffi::VkResult_VK_SUCCESS {
|
||||
return Err(String::from("Failed to create buffer!"));
|
||||
}
|
||||
|
||||
let mut mem_req: ffi::VkMemoryRequirements = unsafe { std::mem::zeroed() };
|
||||
unsafe {
|
||||
ffi::vkGetBufferMemoryRequirements(
|
||||
self.device,
|
||||
buffer,
|
||||
std::ptr::addr_of_mut!(mem_req),
|
||||
);
|
||||
}
|
||||
|
||||
let mut alloc_info: ffi::VkMemoryAllocateInfo = unsafe { std::mem::zeroed() };
|
||||
alloc_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = mem_req.size;
|
||||
alloc_info.memoryTypeIndex = self.find_memory_type(mem_req.memoryTypeBits, properties)?;
|
||||
|
||||
let mut buffer_mem: ffi::VkDeviceMemory = std::ptr::null_mut();
|
||||
|
||||
let result = unsafe {
|
||||
ffi::vkAllocateMemory(
|
||||
self.device,
|
||||
std::ptr::addr_of!(alloc_info),
|
||||
std::ptr::null(),
|
||||
std::ptr::addr_of_mut!(buffer_mem),
|
||||
)
|
||||
};
|
||||
if result != ffi::VkResult_VK_SUCCESS {
|
||||
return Err(String::from("Failed to allocate buffer memory"));
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ffi::vkBindBufferMemory(self.device, buffer, buffer_mem, 0);
|
||||
}
|
||||
|
||||
Ok((buffer, buffer_mem))
|
||||
}
|
||||
|
||||
fn copy_buffer(
|
||||
&mut self,
|
||||
src_buffer: ffi::VkBuffer,
|
||||
dst_buffer: ffi::VkBuffer,
|
||||
size: ffi::VkDeviceSize,
|
||||
) -> Result<(), String> {
|
||||
let mut alloc_info: ffi::VkCommandBufferAllocateInfo = unsafe { std::mem::zeroed() };
|
||||
alloc_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
alloc_info.level = ffi::VkCommandBufferLevel_VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
alloc_info.commandPool = self.command_pool;
|
||||
alloc_info.commandBufferCount = 1;
|
||||
|
||||
let mut command_buffer: ffi::VkCommandBuffer = std::ptr::null_mut();
|
||||
|
||||
unsafe {
|
||||
ffi::vkAllocateCommandBuffers(
|
||||
self.device,
|
||||
std::ptr::addr_of!(alloc_info),
|
||||
std::ptr::addr_of_mut!(command_buffer),
|
||||
);
|
||||
}
|
||||
|
||||
let mut begin_info: ffi::VkCommandBufferBeginInfo = unsafe { std::mem::zeroed() };
|
||||
begin_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.flags =
|
||||
ffi::VkCommandBufferUsageFlagBits_VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
|
||||
unsafe {
|
||||
ffi::vkBeginCommandBuffer(command_buffer, std::ptr::addr_of!(begin_info));
|
||||
}
|
||||
|
||||
let mut copy_region: ffi::VkBufferCopy = unsafe { std::mem::zeroed() };
|
||||
copy_region.srcOffset = 0;
|
||||
copy_region.dstOffset = 0;
|
||||
copy_region.size = size;
|
||||
|
||||
unsafe {
|
||||
ffi::vkCmdCopyBuffer(
|
||||
command_buffer,
|
||||
src_buffer,
|
||||
dst_buffer,
|
||||
1,
|
||||
std::ptr::addr_of!(copy_region),
|
||||
);
|
||||
ffi::vkEndCommandBuffer(command_buffer);
|
||||
}
|
||||
|
||||
let mut submit_info: ffi::VkSubmitInfo = unsafe { std::mem::zeroed() };
|
||||
submit_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = std::ptr::addr_of!(command_buffer);
|
||||
|
||||
unsafe {
|
||||
ffi::vkQueueSubmit(
|
||||
self.graphics_queue,
|
||||
1,
|
||||
std::ptr::addr_of!(submit_info),
|
||||
std::ptr::null_mut(),
|
||||
);
|
||||
ffi::vkQueueWaitIdle(self.graphics_queue);
|
||||
ffi::vkFreeCommandBuffers(
|
||||
self.device,
|
||||
self.command_pool,
|
||||
1,
|
||||
std::ptr::addr_of!(command_buffer),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VulkanApp {
|
||||
|
|
Loading…
Reference in a new issue