diff options
Diffstat (limited to 'adapters/fparkan-render-vulkan/src/ffi/resources.rs')
| -rw-r--r-- | adapters/fparkan-render-vulkan/src/ffi/resources.rs | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/resources.rs b/adapters/fparkan-render-vulkan/src/ffi/resources.rs index 0b43565..498a472 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)", ) @@ -515,7 +528,7 @@ pub(super) fn create_static_texture_image( }) } -/// Allocates two aligned camera slots used by the dynamic frame UBO. +/// Allocates a main and reflected view slot for each in-flight frame. pub(super) fn create_frame_uniform_buffer( instance: &VulkanInstanceProbe, device: &VulkanLogicalDeviceProbe, @@ -532,7 +545,7 @@ pub(super) fn create_frame_uniform_buffer( )? / alignment * alignment; let size = stride - .checked_mul(super::VULKAN_FRAME_SLOT_COUNT as u64) + .checked_mul(2 * super::VULKAN_FRAME_SLOT_COUNT as u64) .ok_or(VulkanSmokeRendererError::InvalidStaticMesh { context: "frame uniform buffer size overflow", })?; @@ -875,7 +888,7 @@ pub(super) fn write_frame_uniform( .ok_or(VulkanSmokeRendererError::InvariantViolation { context: "frame uniform slot offset", })?; - // SAFETY: The offset is one of the two allocated aligned slots and the + // SAFETY: The caller supplies an allocated, fence-safe main or reflection slot; the // mapped range is exactly one complete frame block. let mapped = unsafe { device.device().map_memory( @@ -1372,7 +1385,7 @@ fn create_host_visible_buffer( Ok(VulkanAllocatedBuffer { buffer, memory }) } -fn find_memory_type( +pub(super) fn find_memory_type( instance: &VulkanInstanceProbe, physical_device: vk::PhysicalDevice, type_bits: u32, |
