aboutsummaryrefslogtreecommitdiff
path: root/adapters/fparkan-render-vulkan/src/ffi/resources.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-11-01 00:09:36 +0300
committerValentin Popov <valentin@popov.link>2026-11-01 00:09:36 +0300
commit5890416fd74f4868d16814bd87221370e34062db (patch)
treee0cbc447d76907e423454b371ae735d1a4b70b47 /adapters/fparkan-render-vulkan/src/ffi/resources.rs
parent8fab4b44b8241ffc6450780c6590908f4406f4da (diff)
downloadfparkan-5890416fd74f4868d16814bd87221370e34062db.tar.xz
fparkan-5890416fd74f4868d16814bd87221370e34062db.zip
perf(render): retain static mesh prefixes between frames
Diffstat (limited to 'adapters/fparkan-render-vulkan/src/ffi/resources.rs')
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/resources.rs41
1 files changed, 27 insertions, 14 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/resources.rs b/adapters/fparkan-render-vulkan/src/ffi/resources.rs
index 0b43565..fe71d12 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/resources.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/resources.rs
@@ -243,18 +243,25 @@ pub(super) fn create_vertex_buffer(
/// Replaces the bytes of a host-visible static vertex allocation.
///
-/// The live renderer waits for the device before calling this helper, so a
+/// The live renderer waits for submitted readers before calling this helper, so a
/// single shared allocation can safely carry camera-relative sky and weather
/// geometry between frames.
pub(super) fn write_static_mesh_vertex_buffer(
device: &VulkanLogicalDeviceProbe,
buffer: &VulkanAllocatedBuffer,
+ first_vertex: usize,
vertices: &[super::VulkanStaticVertex],
) -> Result<(), VulkanSmokeRendererError> {
let bytes = encode_static_vertices(vertices)?;
+ let offset = first_vertex
+ .checked_mul(14 * std::mem::size_of::<f32>())
+ .ok_or(VulkanSmokeRendererError::InvalidStaticMesh {
+ context: "static mesh vertex upload offset overflows address space",
+ })?;
write_mapped_buffer(
device,
buffer,
+ offset,
&bytes,
"vkMapMemory(static mesh vertex update)",
)
@@ -295,29 +302,28 @@ fn encode_static_vertices(
fn write_mapped_buffer(
device: &VulkanLogicalDeviceProbe,
buffer: &VulkanAllocatedBuffer,
+ offset: usize,
bytes: &[u8],
context: &'static str,
) -> Result<(), VulkanSmokeRendererError> {
- let byte_len =
- u64::try_from(bytes.len()).map_err(|_| VulkanSmokeRendererError::InvalidStaticMesh {
- context: "static mesh upload exceeds address space",
- })?;
- if byte_len == 0 {
- return Err(VulkanSmokeRendererError::InvalidStaticMesh {
- context: "static mesh upload cannot be empty",
- });
+ if bytes.is_empty() {
+ return Ok(());
}
// SAFETY: The caller validates that the allocation is large enough and
// waits for all queue work that could read it before this write.
let mapped = unsafe {
- device
- .device()
- .map_memory(buffer.memory, 0, byte_len, vk::MemoryMapFlags::empty())
+ device.device().map_memory(
+ buffer.memory,
+ 0,
+ vk::WHOLE_SIZE,
+ vk::MemoryMapFlags::empty(),
+ )
}
.map_err(|result| VulkanSmokeRendererError::VulkanOperation { context, result })?;
- // SAFETY: `mapped` covers exactly the byte slice copied below.
+ // SAFETY: The caller bounds the upload against the allocation. Mapping
+ // from zero also meets minMemoryMapAlignment for arbitrary vertex offsets.
unsafe {
- std::ptr::copy_nonoverlapping(bytes.as_ptr(), mapped.cast::<u8>(), bytes.len());
+ std::ptr::copy_nonoverlapping(bytes.as_ptr(), mapped.cast::<u8>().add(offset), bytes.len());
device.device().unmap_memory(buffer.memory);
}
Ok(())
@@ -351,12 +357,19 @@ pub(super) fn create_index_buffer(
pub(super) fn write_static_mesh_index_buffer(
device: &VulkanLogicalDeviceProbe,
buffer: &VulkanAllocatedBuffer,
+ first_index: usize,
indices: &[u32],
) -> Result<(), VulkanSmokeRendererError> {
let bytes = encode_static_indices(indices)?;
+ let offset = first_index.checked_mul(std::mem::size_of::<u32>()).ok_or(
+ VulkanSmokeRendererError::InvalidStaticMesh {
+ context: "static mesh index upload offset overflows address space",
+ },
+ )?;
write_mapped_buffer(
device,
buffer,
+ offset,
&bytes,
"vkMapMemory(static mesh index update)",
)