feat(renderer): implement vertex buffer allocation and memory mapping
This commit is contained in:
parent
8af89292b6
commit
e6f8414817
|
|
@ -2,10 +2,16 @@ use thiserror::Error;
|
|||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RendererError {
|
||||
/// The Vulkan library could not be loaded from the system.
|
||||
#[error("Failed to load Vulkan library")]
|
||||
LoadFailed(#[from] ash::LoadingError),
|
||||
/// A raw Vulkan result indicated a failure.
|
||||
#[error("Vulkan error")]
|
||||
VulkanError(#[from] ash::vk::Result),
|
||||
/// No GPU was found that meets the engine's requirements.
|
||||
#[error("No suitable GPU found")]
|
||||
NoSuitableGpu,
|
||||
/// An error occurred during GPU memory allocation.
|
||||
#[error("GPU allocation error")]
|
||||
AllocationError(#[from] gpu_allocator::AllocationError),
|
||||
}
|
||||
|
|
@ -89,6 +89,8 @@ impl Renderer {
|
|||
let sync =
|
||||
sync::create_sync_primitives(&device, MAX_FRAMES_IN_FLIGHT, swapchain_images.len())?;
|
||||
|
||||
// 11. GPU Memory Allocator
|
||||
// The allocator handles the complexity of sub-allocating memory blocks from the GPU.
|
||||
let allocator_create_info = gpu_allocator::vulkan::AllocatorCreateDesc {
|
||||
instance: instance.clone(),
|
||||
device: device.clone(),
|
||||
|
|
@ -101,10 +103,53 @@ impl Renderer {
|
|||
let allocator = gpu_allocator::vulkan::Allocator::new(&allocator_create_info)
|
||||
.expect("Failed to create Vulkan allocator");
|
||||
|
||||
// 12. Graphics Pipeline Configuration
|
||||
// The pipeline defines the fixed-function and programmable state for rendering voxel geometry.
|
||||
let pipeline_layout = pipeline::create_pipeline_layout(&device);
|
||||
let graphics_pipeline =
|
||||
pipeline::create_graphics_pipeline(&device, pipeline_layout, swapchain_format);
|
||||
|
||||
// 13. Vertex Buffer Initialization
|
||||
// A simple triangle is defined in normalized device coordinates and moved to GPU memory.
|
||||
let vertices = [
|
||||
mesh::Vertex { position: [0.0, -0.5, 0.0], tex_coord: [0.5, 0.0] },
|
||||
mesh::Vertex { position: [0.5, 0.5, 0.0], tex_coord: [1.0, 1.0] },
|
||||
mesh::Vertex { position: [-0.5, 0.5, 0.0], tex_coord: [0.0, 1.0] },
|
||||
];
|
||||
|
||||
// Create the buffer handle and query its memory requirements.
|
||||
let buffer_info = vk::BufferCreateInfo::default()
|
||||
.size(std::mem::size_of_val(&vertices) as u64)
|
||||
.usage(vk::BufferUsageFlags::VERTEX_BUFFER);
|
||||
|
||||
let vertex_buffer = unsafe { device.create_buffer(&buffer_info, None)? };
|
||||
let requirements = unsafe { device.get_buffer_memory_requirements(vertex_buffer) };
|
||||
|
||||
let mut allocator = allocator;
|
||||
|
||||
// Allocate memory that is visible to the CPU for data transfer.
|
||||
let vertex_allocation = allocator.allocate(&gpu_allocator::vulkan::AllocationCreateDesc {
|
||||
name: "Vertex Buffer",
|
||||
requirements,
|
||||
location: gpu_allocator::MemoryLocation::CpuToGpu,
|
||||
linear: true,
|
||||
allocation_scheme: gpu_allocator::vulkan::AllocationScheme::GpuAllocatorManaged,
|
||||
})?;
|
||||
|
||||
// Bind the allocated memory to the buffer handle and copy the vertex data.
|
||||
unsafe {
|
||||
device.bind_buffer_memory(vertex_buffer, vertex_allocation.memory(), vertex_allocation.offset())?;
|
||||
|
||||
let ptr = vertex_allocation.mapped_ptr()
|
||||
.expect("Failed to map vertex buffer memory")
|
||||
.as_ptr();
|
||||
|
||||
std::ptr::copy_nonoverlapping(
|
||||
vertices.as_ptr() as *const u8,
|
||||
ptr as *mut u8,
|
||||
std::mem::size_of_val(&vertices));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
_entry: entry,
|
||||
instance,
|
||||
|
|
@ -127,6 +172,8 @@ impl Renderer {
|
|||
allocator,
|
||||
pipeline_layout,
|
||||
graphics_pipeline,
|
||||
vertex_buffer,
|
||||
vertex_allocation,
|
||||
sync,
|
||||
current_frame: 0,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::error::RendererError;
|
||||
use crate::sync::SyncPrimitives;
|
||||
use ash::{Device, Instance, khr, vk};
|
||||
use gpu_allocator::vulkan::Allocator;
|
||||
use gpu_allocator::vulkan::{Allocation, Allocator};
|
||||
|
||||
|
||||
|
||||
|
|
@ -49,6 +49,10 @@ pub struct Renderer {
|
|||
pub(crate) graphics_pipeline: vk::Pipeline,
|
||||
/// Memory manager for GPU allocations.
|
||||
pub(crate) allocator: Allocator,
|
||||
/// Buffer containing the vertex data for the initial triangle.
|
||||
pub(crate) vertex_buffer: vk::Buffer,
|
||||
/// Memory allocation for the vertex buffer.
|
||||
pub(crate) vertex_allocation: Allocation,
|
||||
/// Synchronization primitives for frame-by-frame execution.
|
||||
pub(crate) sync: SyncPrimitives,
|
||||
/// Index of the current frame being processed (0 to crate::MAX_FRAMES_IN_FLIGHT - 1).
|
||||
|
|
@ -202,6 +206,11 @@ impl Drop for Renderer {
|
|||
self.device
|
||||
.destroy_pipeline_layout(self.pipeline_layout, None);
|
||||
|
||||
self.allocator.free(std::ptr::read(&self.vertex_allocation))
|
||||
.expect(" Failed to free vertex buffer allocation");
|
||||
|
||||
self.device.destroy_buffer(self.vertex_buffer, None);
|
||||
|
||||
self.device.destroy_command_pool(self.command_pool, None);
|
||||
|
||||
// Use the safe cleanup function from sync module
|
||||
|
|
|
|||
Loading…
Reference in a new issue