diff --git a/src/renderer/vulkan/mod.rs b/src/renderer/vulkan/mod.rs index a8ceee9..a00ef58 100644 --- a/src/renderer/vulkan/mod.rs +++ b/src/renderer/vulkan/mod.rs @@ -39,3 +39,7 @@ pub use vk_fence::VkFence; mod utils; mod vertex; +mod vk_buffer; +pub use vk_buffer::VkBuffer; + +pub use vertex::Vertex; diff --git a/src/renderer/vulkan/vertex.rs b/src/renderer/vulkan/vertex.rs index fcbd4c5..5d97213 100644 --- a/src/renderer/vulkan/vertex.rs +++ b/src/renderer/vulkan/vertex.rs @@ -8,6 +8,10 @@ pub struct Vertex { } impl Vertex { + pub fn new(position: [f32; 2], color: [f32; 3]) -> Self { + Self { position, color } + } + pub fn get_binding_description() -> vk::VertexInputBindingDescription { vk::VertexInputBindingDescription::default() .binding(0) diff --git a/src/renderer/vulkan/vk_buffer.rs b/src/renderer/vulkan/vk_buffer.rs new file mode 100644 index 0000000..b03dea4 --- /dev/null +++ b/src/renderer/vulkan/vk_buffer.rs @@ -0,0 +1,31 @@ +use std::sync::Arc; +use ash::prelude::VkResult; +use ash::vk; +use crate::renderer::vulkan::VkDevice; + +pub struct VkBuffer { + device: Arc, + + handle: vk::Buffer, +} + +impl VkBuffer { + pub fn new(device: &Arc, info: &vk::BufferCreateInfo) -> VkResult { + let buffer = unsafe { device.handle.create_buffer(info, None)? }; + + Ok(VkBuffer { device: Arc::clone(device), handle: buffer }) + } + + + pub fn mem_requirements(&self) -> vk::MemoryRequirements { + unsafe { self.device.handle.get_buffer_memory_requirements(self.handle) } + } +} + +impl Drop for VkBuffer { + fn drop(&mut self) { + unsafe { + self.device.handle.destroy_buffer(self.handle, None); + } + } +} \ No newline at end of file diff --git a/src/renderer/vulkan/vk_device.rs b/src/renderer/vulkan/vk_device.rs index eaf73e4..9f14630 100644 --- a/src/renderer/vulkan/vk_device.rs +++ b/src/renderer/vulkan/vk_device.rs @@ -5,6 +5,8 @@ use std::sync::Arc; pub struct VkDevice { instance: Arc, + physical_device: Arc, + pub handle: ash::Device, pub swapchain_loader: ash::khr::swapchain::Device, pub queue_family_index: u32, @@ -17,7 +19,7 @@ pub struct VkDevice { impl VkDevice { pub fn new_graphics_device( instance: &Arc, - physical_device: &VkPhysicalDevice, + physical_device: &Arc, queue_family_index: u32, ) -> anyhow::Result { let device_extension_names_raw = [ @@ -56,7 +58,8 @@ impl VkDevice { let swapchain_loader = ash::khr::swapchain::Device::new(&instance.handle, &device); Ok(Self { - instance: instance.clone(), + instance: Arc::clone(instance), + physical_device: Arc::clone(&physical_device), handle: device, swapchain_loader, queue_family_index, diff --git a/src/renderer/vulkan/vk_instance.rs b/src/renderer/vulkan/vk_instance.rs index 6f13f3c..101dec2 100644 --- a/src/renderer/vulkan/vk_instance.rs +++ b/src/renderer/vulkan/vk_instance.rs @@ -5,6 +5,7 @@ use crate::renderer::vulkan::{ use ash::khr::surface; use ash::{vk, Entry, Instance}; use std::ffi::{c_char, CStr, CString}; +use std::sync::Arc; pub struct VkInstance { pub entry: Entry, @@ -107,12 +108,12 @@ impl VkInstance { } } - pub fn get_physical_devices(&self) -> Vec { - let physical_devices = unsafe { self.handle.enumerate_physical_devices() }; + pub fn get_physical_devices(instance: &Arc) -> Vec { + let physical_devices = unsafe { instance.handle.enumerate_physical_devices() }; physical_devices .unwrap_or_default() .iter() - .map(|physical_device| VkPhysicalDevice::new(&self.handle, *physical_device)) + .map(|physical_device| VkPhysicalDevice::new(&instance, *physical_device)) .collect() } } diff --git a/src/renderer/vulkan/vk_physical_device.rs b/src/renderer/vulkan/vk_physical_device.rs index 2edc8e3..3534f24 100644 --- a/src/renderer/vulkan/vk_physical_device.rs +++ b/src/renderer/vulkan/vk_physical_device.rs @@ -1,26 +1,29 @@ -use super::VkSurface; +use std::sync::Arc; +use super::{VkInstance, VkSurface}; use ash::vk; pub struct VkPhysicalDevice { - // Vulkan properties + instance: Arc, pub handle: vk::PhysicalDevice, + pub properties: vk::PhysicalDeviceProperties, pub features: vk::PhysicalDeviceFeatures, pub queue_family_properties: Vec, } impl VkPhysicalDevice { - pub fn new(instance: &ash::Instance, physical_device: vk::PhysicalDevice) -> Self { + pub fn new(instance: &Arc, physical_device: vk::PhysicalDevice) -> Self { log::debug!("New physical device"); - let device_properties = unsafe { instance.get_physical_device_properties(physical_device) }; + let device_properties = unsafe { instance.handle.get_physical_device_properties(physical_device) }; log::debug!("{device_properties:#?}"); - let device_features = unsafe { instance.get_physical_device_features(physical_device) }; + let device_features = unsafe { instance.handle.get_physical_device_features(physical_device) }; log::debug!("{device_features:#?}"); let device_queue_families = - unsafe { instance.get_physical_device_queue_family_properties(physical_device) }; + unsafe { instance.handle.get_physical_device_queue_family_properties(physical_device) }; log::debug!("{device_queue_families:#?}"); Self { + instance: Arc::clone(instance), handle: physical_device, properties: device_properties, features: device_features, diff --git a/src/renderer/vulkan/vk_render_context.rs b/src/renderer/vulkan/vk_render_context.rs index aa39b39..68dd304 100644 --- a/src/renderer/vulkan/vk_render_context.rs +++ b/src/renderer/vulkan/vk_render_context.rs @@ -29,7 +29,7 @@ impl VkRenderContext { let instance = Arc::new(VkInstance::new(&required_extensions)); let surface = Arc::new(VkSurface::new(&window, instance.clone())?); - let mut physical_devices = instance.get_physical_devices(); + let mut physical_devices = VkInstance::get_physical_devices(&instance); physical_devices.sort_by(|a, b| b.priority().cmp(&a.priority())); let (physical_device, queue_family_index, properties) = diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 4b37d74..46be2e9 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -1,2 +1,4 @@ mod triangle; -pub use triangle::Triangle as TriangleScene; \ No newline at end of file +mod vertex; + +pub use triangle::TriangleScene; diff --git a/src/scene/triangle.rs b/src/scene/triangle.rs index c256429..f699930 100644 --- a/src/scene/triangle.rs +++ b/src/scene/triangle.rs @@ -1,20 +1,20 @@ -use std::sync::Arc; -use ash::vk; use crate::renderer::vulkan::{VkDevice, VkGraphicsPipeline, VkRenderPass, VkSwapchain}; use crate::renderer::Renderable; +use ash::vk; use ash::vk::CommandBuffer; +use std::sync::Arc; -pub struct Triangle { +pub struct TriangleScene { pipeline: Option, } -impl Triangle { +impl TriangleScene { pub fn new() -> Self { Self { pipeline: None } } } -impl Renderable for Triangle { +impl Renderable for TriangleScene { fn init(&mut self, device: &Arc, render_pass: &Arc) -> anyhow::Result<()> { let pipeline = VkGraphicsPipeline::new(&device, &render_pass)?; self.pipeline = Some(pipeline); diff --git a/src/scene/vertex.rs b/src/scene/vertex.rs new file mode 100644 index 0000000..0384d0c --- /dev/null +++ b/src/scene/vertex.rs @@ -0,0 +1,39 @@ +use std::sync::Arc; +use ash::prelude::VkResult; +use ash::vk; +use crate::renderer::vulkan::{Vertex, VkBuffer, VkDevice}; + +#[derive(Default)] +struct VertexScene { + vertices: Vec, + + vertices_buffer: Option, +} + +impl VertexScene { + pub fn new() -> Self { + let vertices = vec![ + Vertex::new([0.0, -0.5], [1.0, 0.0, 0.0]), + Vertex::new([0.5, 0.5], [0.0, 1.0, 0.0]), + Vertex::new([-0.5, 0.5], [0.0, 0.0, 1.0]), + ]; + + Self { + vertices, + ..Default::default() + } + } + + + fn create_buffer(&mut self, device: &Arc) -> VkResult<()> { + let buffer_info = vk::BufferCreateInfo::default() + .usage(vk::BufferUsageFlags::VERTEX_BUFFER) + .sharing_mode(vk::SharingMode::EXCLUSIVE) + .size(self.vertices.len() as u64 * size_of::() as u64); + + let buffer = VkBuffer::new(device, &buffer_info)?; + self.vertices_buffer = Some(buffer); + + Ok(()) + } +} \ No newline at end of file