From 6cdc3a0d34e7ff354866fb6f231ba12f9eb45a6f Mon Sep 17 00:00:00 2001 From: John Wells Date: Tue, 20 Dec 2022 12:18:43 -0500 Subject: [PATCH] Add configurable buffer alignment (cherry picked from commit cb7b6234c526590f3633ac660dd706b19b4bb88e) --- contrib/screen-13-fx/src/bitmap_font.rs | 6 +---- contrib/screen-13-fx/src/image_loader.rs | 9 ++++---- contrib/screen-13-imgui/src/lib.rs | 18 +++------------ examples/fuzzer.rs | 28 +++++++++++++++--------- examples/ray_trace.rs | 21 ++++++++++-------- examples/rt_triangle.rs | 21 ++++++++++-------- src/driver/buffer.rs | 21 +++++++----------- src/graph/pass_ref.rs | 24 ++------------------ 8 files changed, 60 insertions(+), 88 deletions(-) diff --git a/contrib/screen-13-fx/src/bitmap_font.rs b/contrib/screen-13-fx/src/bitmap_font.rs index b844edf1..67beda2b 100644 --- a/contrib/screen-13-fx/src/bitmap_font.rs +++ b/contrib/screen-13-fx/src/bitmap_font.rs @@ -163,11 +163,7 @@ impl BitmapFont { let vertex_buf_len = 120 * text.chars().count() as vk::DeviceSize; let mut vertex_buf = self .cache - .lease(BufferInfo { - size: vertex_buf_len, - usage: vk::BufferUsageFlags::VERTEX_BUFFER, - can_map: true, - }) + .lease(BufferInfo::new_mappable(vertex_buf_len, vk::BufferUsageFlags::VERTEX_BUFFER)) .unwrap(); let mut vertex_count = 0; diff --git a/contrib/screen-13-fx/src/image_loader.rs b/contrib/screen-13-fx/src/image_loader.rs index ddac1575..e84ee2cd 100644 --- a/contrib/screen-13-fx/src/image_loader.rs +++ b/contrib/screen-13-fx/src/image_loader.rs @@ -159,11 +159,10 @@ impl ImageLoader { //trace!("pixel_buf_len={pixel_buf_len} pixel_buf_stride={pixel_buf_stride}"); // Lease a temporary buffer from the cache pool - let mut pixel_buf = self.pool.lease(BufferInfo { - size: pixel_buf_len, - usage: vk::BufferUsageFlags::STORAGE_BUFFER, - can_map: true, - })?; + let mut pixel_buf = self.pool.lease(BufferInfo::new_mappable( + pixel_buf_len, + vk::BufferUsageFlags::STORAGE_BUFFER, + ))?; { let pixel_buf = diff --git a/contrib/screen-13-imgui/src/lib.rs b/contrib/screen-13-imgui/src/lib.rs index 456d96bb..f158d86d 100644 --- a/contrib/screen-13-imgui/src/lib.rs +++ b/contrib/screen-13-imgui/src/lib.rs @@ -119,11 +119,7 @@ impl ImGui { let indices = cast_slice(draw_list.idx_buffer()); let mut index_buf = self .pool - .lease(BufferInfo { - size: indices.len() as _, - usage: vk::BufferUsageFlags::INDEX_BUFFER, - can_map: true, - }) + .lease(BufferInfo::new_mappable(indices.len() as _, vk::BufferUsageFlags::INDEX_BUFFER)) .unwrap(); { @@ -136,11 +132,7 @@ impl ImGui { let vertex_buf_len = vertices.len() * 20; let mut vertex_buf = self .pool - .lease(BufferInfo { - size: vertex_buf_len as _, - usage: vk::BufferUsageFlags::VERTEX_BUFFER, - can_map: true, - }) + .lease(BufferInfo::new_mappable(vertex_buf_len as _, vk::BufferUsageFlags::VERTEX_BUFFER)) .unwrap(); { @@ -268,11 +260,7 @@ impl ImGui { let temp_buf_len = texture.data.len(); let mut temp_buf = self .pool - .lease(BufferInfo { - size: temp_buf_len as _, - usage: vk::BufferUsageFlags::TRANSFER_SRC, - can_map: true, - }) + .lease(BufferInfo::new_mappable(temp_buf_len as _, vk::BufferUsageFlags::TRANSFER_SRC)) .unwrap(); { diff --git a/examples/fuzzer.rs b/examples/fuzzer.rs index 047ac571..4413e85d 100644 --- a/examples/fuzzer.rs +++ b/examples/fuzzer.rs @@ -159,12 +159,13 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { ) .unwrap(); - let scratch_buf_padding = frame + let accel_struct_scratch_offset_alignment = frame .device .accel_struct_properties .as_ref() .unwrap() - .min_accel_struct_scratch_offset_alignment as vk::DeviceSize; + .min_accel_struct_scratch_offset_alignment + as vk::DeviceSize; // Lease and bind a bunch of bottom-level acceleration structures and add to instance buffer let mut blas_nodes = Vec::with_capacity(BLAS_COUNT as _); @@ -195,10 +196,14 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { let blas_node = frame.render_graph.bind_node(blas); let scratch_buf = frame.render_graph.bind_node( - pool.lease(BufferInfo::new( - blas_size.build_size + scratch_buf_padding, - vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, - )) + pool.lease( + BufferInfo::new( + blas_size.build_size, + vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS + | vk::BufferUsageFlags::STORAGE_BUFFER, + ) + .alignment(accel_struct_scratch_offset_alignment), + ) .unwrap(), ); @@ -228,10 +233,13 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { .unwrap(); let tlas_node = frame.render_graph.bind_node(tlas); let tlas_scratch_buf = frame.render_graph.bind_node( - pool.lease(BufferInfo::new( - tlas_size.build_size + scratch_buf_padding, - vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, - )) + pool.lease( + BufferInfo::new( + tlas_size.build_size, + vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, + ) + .alignment(accel_struct_scratch_offset_alignment), + ) .unwrap(), ); diff --git a/examples/ray_trace.rs b/examples/ray_trace.rs index ad5a08f3..a9a87ca7 100644 --- a/examples/ray_trace.rs +++ b/examples/ray_trace.rs @@ -505,9 +505,9 @@ fn main() -> anyhow::Result<()> { // ------------------------------------------------------------------------------------------ // let sbt_handle_size = align_up(shader_group_handle_size, shader_group_handle_alignment); - let sbt_rgen_size = align_up(sbt_handle_size, shader_group_base_alignment); - let sbt_hit_size = align_up(sbt_handle_size, shader_group_base_alignment); - let sbt_miss_size = align_up(2 * sbt_handle_size, shader_group_base_alignment); + let sbt_rgen_size = sbt_handle_size; + let sbt_hit_size = sbt_handle_size; + let sbt_miss_size = 2 * sbt_handle_size; let sbt_buf = Arc::new({ let mut buf = Buffer::create( &event_loop.device, @@ -515,7 +515,8 @@ fn main() -> anyhow::Result<()> { (sbt_rgen_size + sbt_hit_size + sbt_miss_size) as _, vk::BufferUsageFlags::SHADER_BINDING_TABLE_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, - ), + ) + .alignment(shader_group_base_alignment as _), ) .unwrap(); @@ -659,7 +660,7 @@ fn main() -> anyhow::Result<()> { // ------------------------------------------------------------------------------------------ // { - let scratch_buf_padding = event_loop + let accel_struct_scratch_offset_alignment = event_loop .device .accel_struct_properties .as_ref() @@ -675,10 +676,11 @@ fn main() -> anyhow::Result<()> { let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, BufferInfo::new( - blas_size.build_size + scratch_buf_padding, + blas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, - ), + ) + .alignment(accel_struct_scratch_offset_alignment), )?); render_graph @@ -706,10 +708,11 @@ fn main() -> anyhow::Result<()> { let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, BufferInfo::new( - tlas_size.build_size + scratch_buf_padding, + tlas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, - ), + ) + .alignment(accel_struct_scratch_offset_alignment), )?); let instance_node = render_graph.bind_node(&instance_buf); let tlas_node = render_graph.bind_node(&tlas); diff --git a/examples/rt_triangle.rs b/examples/rt_triangle.rs index e27b1d7c..03577d28 100644 --- a/examples/rt_triangle.rs +++ b/examples/rt_triangle.rs @@ -118,9 +118,9 @@ fn main() -> anyhow::Result<()> { // ------------------------------------------------------------------------------------------ // let sbt_handle_size = align_up(shader_group_handle_size, shader_group_handle_alignment); - let sbt_rgen_size = align_up(sbt_handle_size, shader_group_base_alignment); - let sbt_hit_size = align_up(sbt_handle_size, shader_group_base_alignment); - let sbt_miss_size = align_up(2 * sbt_handle_size, shader_group_base_alignment); + let sbt_rgen_size = sbt_handle_size; + let sbt_hit_size = sbt_handle_size; + let sbt_miss_size = 2 * sbt_handle_size; let sbt_buf = Arc::new({ let mut buf = Buffer::create( &event_loop.device, @@ -128,7 +128,8 @@ fn main() -> anyhow::Result<()> { (sbt_rgen_size + sbt_hit_size + sbt_miss_size) as _, vk::BufferUsageFlags::SHADER_BINDING_TABLE_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, - ), + ) + .alignment(shader_group_base_alignment as _), ) .unwrap(); @@ -324,7 +325,7 @@ fn main() -> anyhow::Result<()> { // ------------------------------------------------------------------------------------------ // { - let scratch_buf_padding = event_loop + let accel_struct_scratch_offset_alignment = event_loop .device .accel_struct_properties .as_ref() @@ -340,10 +341,11 @@ fn main() -> anyhow::Result<()> { let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, BufferInfo::new( - blas_size.build_size + scratch_buf_padding, + blas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, - ), + ) + .alignment(accel_struct_scratch_offset_alignment), )?); render_graph @@ -372,10 +374,11 @@ fn main() -> anyhow::Result<()> { let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, BufferInfo::new( - tlas_size.build_size + scratch_buf_padding, + tlas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, - ), + ) + .alignment(accel_struct_scratch_offset_alignment), )?); let tlas_node = render_graph.bind_node(&tlas); diff --git a/src/driver/buffer.rs b/src/driver/buffer.rs index df47c700..b6925e62 100644 --- a/src/driver/buffer.rs +++ b/src/driver/buffer.rs @@ -105,14 +105,7 @@ impl Buffer { })? }; let mut requirements = unsafe { device.get_buffer_memory_requirements(buffer) }; - - if info - .usage - .contains(vk::BufferUsageFlags::SHADER_BINDING_TABLE_KHR) - { - // TODO: query device props - requirements.alignment = requirements.alignment.max(64); - } + requirements.alignment = requirements.alignment.max(info.alignment); let memory_location = if info.can_map { MemoryLocation::CpuToGpu @@ -183,11 +176,7 @@ impl Buffer { usage: vk::BufferUsageFlags, slice: &[u8], ) -> Result { - let info = BufferInfo { - can_map: true, - size: slice.len() as vk::DeviceSize, - usage, - }; + let info = BufferInfo::new_mappable(slice.len() as _, usage); let mut buffer = Self::create(device, info)?; Self::copy_from_slice(&mut buffer, 0, slice); @@ -419,6 +408,12 @@ impl Drop for Buffer { pattern = "owned" )] pub struct BufferInfo { + /// Byte alignment of the base device address of the buffer. + /// + /// Must be a power of two. + #[builder(default)] + pub alignment: vk::DeviceSize, + /// Size in bytes of the buffer to be created. #[builder(default)] pub size: vk::DeviceSize, diff --git a/src/graph/pass_ref.rs b/src/graph/pass_ref.rs index 38097b51..d8b89d8f 100644 --- a/src/graph/pass_ref.rs +++ b/src/graph/pass_ref.rs @@ -40,10 +40,6 @@ pub type BindingOffset = u32; /// Alias for the descriptor set index of a shader descriptor. pub type DescriptorSetIndex = u32; -fn align_up_device_size(val: vk::DeviceSize, atom: vk::DeviceSize) -> vk::DeviceSize { - (val + atom - 1) & !(atom - 1) -} - /// Recording interface for acceleration structure commands. /// /// This structure provides a strongly-typed set of methods which allow acceleration structures to @@ -192,15 +188,7 @@ impl<'a> Acceleration<'a> { .geometries(&tls.geometries) .dst_acceleration_structure(*self.bindings[accel_struct_node]) .scratch_data(vk::DeviceOrHostAddressKHR { - device_address: align_up_device_size( - Buffer::device_address(&self.bindings[scratch_buf_node]), - self.device - .accel_struct_properties - .as_ref() - .expect("ray tracing feature must be enabled") - .min_accel_struct_scratch_offset_alignment - as _, - ), + device_address: Buffer::device_address(&self.bindings[scratch_buf_node]), }); self.device @@ -267,15 +255,7 @@ impl<'a> Acceleration<'a> { .dst_acceleration_structure(*self.bindings[dst_accel_node]) .src_acceleration_structure(*self.bindings[src_accel_node]) .scratch_data(vk::DeviceOrHostAddressKHR { - device_address: align_up_device_size( - Buffer::device_address(&self.bindings[scratch_buf_node]), - self.device - .accel_struct_properties - .as_ref() - .expect("ray tracing feature must be enabled") - .min_accel_struct_scratch_offset_alignment - as _, - ), + device_address: Buffer::device_address(&self.bindings[scratch_buf_node]), }); self.device