You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
6.0KB

  1. use crate::render::{
  2. CommandPool, Device, PhysicalDevice, Queue, Uniforms, Vertex,
  3. };
  4. use ash::{
  5. version::{DeviceV1_0, InstanceV1_0},
  6. vk,
  7. };
  8. use std::rc::Rc;
  9. pub struct Buffer {
  10. handle: vk::Buffer,
  11. memory: vk::DeviceMemory,
  12. pub device: Rc<Device>,
  13. }
  14. #[derive(Debug)]
  15. pub enum ErrBufferCreate {
  16. Vk(vk::Result),
  17. NoMemoryType(vk::MemoryPropertyFlags, u32),
  18. }
  19. fn get_memory_type(
  20. memory_props: vk::PhysicalDeviceMemoryProperties,
  21. filter_flags: vk::MemoryPropertyFlags,
  22. filter_types: u32,
  23. ) -> Result<u32, ErrBufferCreate> {
  24. let count = memory_props.memory_type_count as usize;
  25. let iter = memory_props.memory_types.iter().take(count).enumerate();
  26. for (i, memory_type) in iter {
  27. let has_flags = memory_type.property_flags.contains(filter_flags);
  28. let has_types = filter_types & 1 << i;
  29. if has_flags && has_types != 0 {
  30. return Ok(i as u32);
  31. }
  32. }
  33. Err(ErrBufferCreate::NoMemoryType(filter_flags, filter_types))
  34. }
  35. unsafe fn create_buffer(
  36. device: &Device,
  37. phys_device: &PhysicalDevice,
  38. size: vk::DeviceSize,
  39. usage: vk::BufferUsageFlags,
  40. mem_flags: vk::MemoryPropertyFlags,
  41. ) -> Result<(vk::Buffer, vk::DeviceMemory), ErrBufferCreate> {
  42. let create_info = vk::BufferCreateInfo {
  43. size,
  44. usage,
  45. sharing_mode: vk::SharingMode::EXCLUSIVE,
  46. ..Default::default()
  47. };
  48. let handle = device.create_buffer(&create_info, None)?;
  49. let memory_reqs = device.get_buffer_memory_requirements(handle);
  50. let memory_props =
  51. device.instance.get_physical_device_memory_properties(**phys_device);
  52. let memory_type_index = get_memory_type(
  53. memory_props,
  54. mem_flags,
  55. memory_reqs.memory_type_bits
  56. )?;
  57. let allocate_info = vk::MemoryAllocateInfo {
  58. memory_type_index,
  59. allocation_size: memory_reqs.size,
  60. ..Default::default()
  61. };
  62. let memory = device.allocate_memory(&allocate_info, None)?;
  63. device.bind_buffer_memory(handle, memory, 0)?;
  64. Ok((handle, memory))
  65. }
  66. /// Returns the size of `data` as a `vk::DeviceSize`.
  67. fn dev_size_of<T>(data: &[T]) -> vk::DeviceSize {
  68. (std::mem::size_of::<T>() * data.len()) as vk::DeviceSize
  69. }
  70. impl Buffer {
  71. /// Creates a vertex buffer.
  72. pub fn create_vertex(
  73. device: Rc<Device>,
  74. phys_device: &PhysicalDevice,
  75. vertices: &[Vertex],
  76. queue: &Queue,
  77. ) -> Result<Rc<Self>, ErrBufferCreate> {
  78. let size = dev_size_of(vertices);
  79. unsafe {
  80. let (handle, memory) = create_buffer(
  81. &device,
  82. phys_device,
  83. size,
  84. vk::BufferUsageFlags::TRANSFER_DST |
  85. vk::BufferUsageFlags::VERTEX_BUFFER,
  86. vk::MemoryPropertyFlags::DEVICE_LOCAL,
  87. )?;
  88. let dst = Self { handle, memory, device };
  89. dst.xfer_data(queue, phys_device, vertices)?;
  90. Ok(Rc::new(dst))
  91. }
  92. }
  93. /// Creates an index buffer.
  94. pub fn create_index(
  95. device: Rc<Device>,
  96. phys_device: &PhysicalDevice,
  97. indices: &[u16],
  98. queue: &Queue,
  99. ) -> Result<Rc<Self>, ErrBufferCreate> {
  100. let size = dev_size_of(indices);
  101. unsafe {
  102. let (handle, memory) = create_buffer(
  103. &device,
  104. phys_device,
  105. size,
  106. vk::BufferUsageFlags::TRANSFER_DST |
  107. vk::BufferUsageFlags::INDEX_BUFFER,
  108. vk::MemoryPropertyFlags::DEVICE_LOCAL,
  109. )?;
  110. let dst = Self { handle, memory, device };
  111. dst.xfer_data(queue, phys_device, indices)?;
  112. Ok(Rc::new(dst))
  113. }
  114. }
  115. /// Creates a uniform buffer.
  116. pub fn create_uniform(
  117. device: Rc<Device>,
  118. phys_device: &PhysicalDevice,
  119. ) -> Result<Rc<Self>, ErrBufferCreate> {
  120. let (handle, memory) = unsafe {
  121. create_buffer(
  122. &device,
  123. phys_device,
  124. std::mem::size_of::<Uniforms>() as vk::DeviceSize,
  125. vk::BufferUsageFlags::UNIFORM_BUFFER,
  126. vk::MemoryPropertyFlags::HOST_VISIBLE |
  127. vk::MemoryPropertyFlags::HOST_COHERENT,
  128. )?
  129. };
  130. Ok(Rc::new(Self { handle, memory, device }))
  131. }
  132. /// Copies the contents of `src` to `self` using a transient pool.
  133. unsafe fn copy_buffer(
  134. &self,
  135. src: &Self,
  136. size: vk::DeviceSize,
  137. queue: &Queue,
  138. ) -> Result<(), vk::Result> {
  139. let pool = CommandPool::create_transfer(
  140. self.device.clone(),
  141. queue.index,
  142. |cmd| cmd.transfer(src.handle, self.handle, size),
  143. )?;
  144. let submit_buffers = pool.buf_handles();
  145. let submit_info = [
  146. vk::SubmitInfo {
  147. command_buffer_count: submit_buffers.len() as u32,
  148. p_command_buffers: submit_buffers.as_ptr(),
  149. ..Default::default()
  150. }
  151. ];
  152. self.device.queue_submit(**queue, &submit_info, vk::Fence::null())?;
  153. self.device.queue_wait_idle(**queue)
  154. }
  155. /// Transfers `data` from the client to the server.
  156. pub fn xfer_data<T>(
  157. &self,
  158. queue: &Queue,
  159. phys_device: &PhysicalDevice,
  160. data: &[T],
  161. ) -> Result<(), ErrBufferCreate> {
  162. let size = dev_size_of(data);
  163. unsafe {
  164. let (handle, memory) = create_buffer(
  165. &self.device,
  166. phys_device,
  167. size,
  168. vk::BufferUsageFlags::TRANSFER_SRC,
  169. vk::MemoryPropertyFlags::HOST_VISIBLE |
  170. vk::MemoryPropertyFlags::HOST_COHERENT,
  171. )?;
  172. let src = Self { handle, memory, device: self.device.clone() };
  173. src.write_data(data)?;
  174. self.copy_buffer(&src, size, queue)?;
  175. }
  176. Ok(())
  177. }
  178. /// Writes `data` to `self`.
  179. pub fn write_data<T>(&self, data: &[T]) -> Result<(), vk::Result> {
  180. let size = dev_size_of(data);
  181. unsafe {
  182. let flg = vk::MemoryMapFlags::empty();
  183. let map = self.device.map_memory(self.memory, 0, size, flg)?;
  184. (map as *mut T).copy_from(data.as_ptr(), data.len());
  185. self.device.unmap_memory(self.memory);
  186. }
  187. Ok(())
  188. }
  189. }
  190. impl Drop for Buffer {
  191. fn drop(&mut self) {
  192. unsafe {
  193. self.device.free_memory(self.memory, None);
  194. self.device.destroy_buffer(self.handle, None);
  195. }
  196. }
  197. }
  198. impl std::ops::Deref for Buffer {
  199. type Target = vk::Buffer;
  200. fn deref(&self) -> &Self::Target {
  201. &self.handle
  202. }
  203. }
  204. impl std::error::Error for ErrBufferCreate {}
  205. impl From<vk::Result> for ErrBufferCreate {
  206. fn from(res: vk::Result) -> Self {
  207. Self::Vk(res)
  208. }
  209. }
  210. impl std::fmt::Display for ErrBufferCreate {
  211. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  212. match self {
  213. Self::Vk(res) => res.fmt(f),
  214. Self::NoMemoryType(filter_flags, filter_type) => write!(
  215. f,
  216. "No memory type matching {{ flags: {:?}, type: {} }}",
  217. filter_flags, filter_type,
  218. ),
  219. }
  220. }
  221. }
  222. // EOF