Skip to content

Commit

Permalink
feat: adding alignment for buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
SkillerRaptor committed Sep 8, 2024
1 parent 061e10e commit ad18487
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 20 deletions.
60 changes: 60 additions & 0 deletions crates/hyper_core/src/alignment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// Copyright (c) 2024, SkillerRaptor
//
// SPDX-License-Identifier: MIT
//

pub trait Alignment {
fn align_up(self, alignment: Self) -> Self;
fn align_down(self, alignment: Self) -> Self;

fn is_aligned(&self, alignment: Self) -> bool;
}

impl Alignment for u32 {
fn align_up(self, alignment: Self) -> Self {
assert!(alignment.is_power_of_two());
(self | (alignment - 1)) + 1
}

fn align_down(self, alignment: Self) -> Self {
assert!(alignment.is_power_of_two());
self & !(alignment - 1)
}

fn is_aligned(&self, alignment: Self) -> bool {
self.align_up(alignment) == *self
}
}

impl Alignment for u64 {
fn align_up(self, alignment: Self) -> Self {
assert!(alignment.is_power_of_two());
(self | (alignment - 1)) + 1
}

fn align_down(self, alignment: Self) -> Self {
assert!(alignment.is_power_of_two());
self & !(alignment - 1)
}

fn is_aligned(&self, alignment: Self) -> bool {
self.align_up(alignment) == *self
}
}

impl Alignment for usize {
fn align_up(self, alignment: Self) -> Self {
assert!(alignment.is_power_of_two());
(self | (alignment - 1)) + 1
}

fn align_down(self, alignment: Self) -> Self {
assert!(alignment.is_power_of_two());
self & !(alignment - 1)
}

fn is_aligned(&self, alignment: Self) -> bool {
self.align_up(alignment) == *self
}
}
2 changes: 2 additions & 0 deletions crates/hyper_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
//
// SPDX-License-Identifier: MIT
//

pub mod alignment;
2 changes: 2 additions & 0 deletions crates/hyper_rhi/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ bitflags::bitflags! {
}
}

pub(crate) const ALIGNMENT: usize = 64 * 1024;

#[derive(Clone, Debug)]
pub struct BufferDescriptor<'a> {
pub data: &'a [u8],
Expand Down
21 changes: 7 additions & 14 deletions crates/hyper_rhi/src/d3d12/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use gpu_allocator::{
d3d12::{ResourceCategory, ResourceCreateDesc, ResourceStateOrBarrierLayout, ResourceType},
MemoryLocation,
};
use hyper_core::alignment::Alignment;
use windows::{
core::Interface,
Win32::{
Expand Down Expand Up @@ -46,7 +47,7 @@ use windows::{
};

use crate::{
buffer::{BufferDescriptor, BufferUsage},
buffer::{self, BufferDescriptor, BufferUsage},
d3d12::{graphics_device::GraphicsDevice, resource_handle_pair::ResourceHandlePair},
resource::{Resource, ResourceHandle},
};
Expand All @@ -63,10 +64,8 @@ pub(crate) struct Buffer {

impl Buffer {
pub(crate) fn new(graphics_device: &GraphicsDevice, descriptor: &BufferDescriptor) -> Self {
let aligned_size =
((descriptor.data.len() as u32 + D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT - 1)
/ D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)
* D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
let size = descriptor.data.len();
let aligned_size = size.align_up(buffer::ALIGNMENT);

let create_info = ResourceCreateDesc {
name: "",
Expand Down Expand Up @@ -154,19 +153,13 @@ impl Buffer {
.create_resource(&upload_create_info)
.unwrap();

let size = aligned_size;

unsafe {
let mut data = std::ptr::null_mut();
upload_resource
.resource()
.Map(0, Some(&D3D12_RANGE { Begin: 0, End: 0 }), Some(&mut data))
.unwrap();
std::ptr::copy_nonoverlapping(
descriptor.data.as_ptr(),
data as *mut u8,
descriptor.data.len(),
);
std::ptr::copy_nonoverlapping(descriptor.data.as_ptr(), data as *mut u8, size);
upload_resource.resource().Unmap(0, None);
}

Expand Down Expand Up @@ -223,12 +216,12 @@ impl Buffer {
}
}

let data_size = descriptor.data.len();
let resource_handle_pair =
graphics_device.allocate_buffer_handle(resource.resource(), data_size);
graphics_device.allocate_buffer_handle(resource.resource(), size);

tracing::debug!(
size,
aligned_size,
srv_index = resource_handle_pair.srv().0,
uav_index = resource_handle_pair.uav().0,
"Buffer created"
Expand Down
17 changes: 11 additions & 6 deletions crates/hyper_rhi/src/vulkan/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use std::{
collections::VecDeque,
mem,
sync::{Arc, Mutex},
};

Expand All @@ -15,9 +14,10 @@ use gpu_allocator::{
vulkan::{Allocation, AllocationCreateDesc, AllocationScheme},
MemoryLocation,
};
use hyper_core::alignment::Alignment;

use crate::{
buffer::{BufferDescriptor, BufferUsage},
buffer::{self, BufferDescriptor, BufferUsage},
resource::{Resource, ResourceHandle},
vulkan::graphics_device::{GraphicsDevice, ResourceBuffer, ResourceHandler},
};
Expand All @@ -37,15 +37,20 @@ pub(crate) struct Buffer {

impl Buffer {
pub(crate) fn new(graphics_device: &GraphicsDevice, descriptor: &BufferDescriptor) -> Self {
let buffer = Self::create_buffer(graphics_device, descriptor.data);
let size = descriptor.data.len();
let aligned_size = size.align_up(buffer::ALIGNMENT);

let buffer = Self::create_buffer(graphics_device, aligned_size);
let allocation = Self::create_allocation(graphics_device, buffer);

// TODO: Add staging buffer
Self::set_data_internal(&allocation, descriptor.data);

let resource_handle = graphics_device.allocate_buffer_handle(buffer);

tracing::debug!(
size = descriptor.data.len(),
size,
aligned_size,
index = resource_handle.0,
"Buffer created"
);
Expand All @@ -63,15 +68,15 @@ impl Buffer {
}
}

fn create_buffer(graphics_device: &GraphicsDevice, data: &[u8]) -> vk::Buffer {
fn create_buffer(graphics_device: &GraphicsDevice, aligned_size: usize) -> vk::Buffer {
// NOTE: Will this hurt any performance?
let usage = vk::BufferUsageFlags::STORAGE_BUFFER
| vk::BufferUsageFlags::INDEX_BUFFER
| vk::BufferUsageFlags::TRANSFER_SRC
| vk::BufferUsageFlags::TRANSFER_DST;

let create_info = vk::BufferCreateInfo::default()
.size(mem::size_of_val(data) as u64)
.size(aligned_size as u64)
.usage(usage)
.sharing_mode(vk::SharingMode::EXCLUSIVE)
.queue_family_indices(&[]);
Expand Down

0 comments on commit ad18487

Please sign in to comment.