Call Vec::set_len()
after checking for Vulkan errors (#684)
The entire reason for calling `unsafe` `set_len()` after the Vulkan driver function call is to ensure the `Vec` never gives safe access to uninitialized values (as allocted via `Vec::with_capacity()`). This contract is broken within the implementation of these functions by temporarily setting a nonzero length when the Vulkan driver may not have initialized the underlying data at all, and communicated this by returning an error code. Simply check the error code first, before jumping to a now-infallible codepath that calls `.set_len()` and always returns `Ok()`.
This commit is contained in:
parent
47ec56c30e
commit
d176eef678
|
@ -1502,14 +1502,15 @@ impl Device {
|
|||
create_info: &vk::DescriptorSetAllocateInfo,
|
||||
) -> VkResult<Vec<vk::DescriptorSet>> {
|
||||
let mut desc_set = Vec::with_capacity(create_info.descriptor_set_count as usize);
|
||||
let err_code = (self.device_fn_1_0.allocate_descriptor_sets)(
|
||||
(self.device_fn_1_0.allocate_descriptor_sets)(
|
||||
self.handle(),
|
||||
create_info,
|
||||
desc_set.as_mut_ptr(),
|
||||
);
|
||||
)
|
||||
.result()?;
|
||||
|
||||
desc_set.set_len(create_info.descriptor_set_count as usize);
|
||||
err_code.result_with_success(desc_set)
|
||||
Ok(desc_set)
|
||||
}
|
||||
|
||||
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateDescriptorSetLayout.html>
|
||||
|
@ -2490,13 +2491,14 @@ impl Device {
|
|||
create_info: &vk::CommandBufferAllocateInfo,
|
||||
) -> VkResult<Vec<vk::CommandBuffer>> {
|
||||
let mut buffers = Vec::with_capacity(create_info.command_buffer_count as usize);
|
||||
let err_code = (self.device_fn_1_0.allocate_command_buffers)(
|
||||
(self.device_fn_1_0.allocate_command_buffers)(
|
||||
self.handle(),
|
||||
create_info,
|
||||
buffers.as_mut_ptr(),
|
||||
);
|
||||
)
|
||||
.result()?;
|
||||
buffers.set_len(create_info.command_buffer_count as usize);
|
||||
err_code.result_with_success(buffers)
|
||||
Ok(buffers)
|
||||
}
|
||||
|
||||
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateCommandPool.html>
|
||||
|
|
|
@ -28,15 +28,16 @@ impl DisplaySwapchain {
|
|||
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||
) -> VkResult<Vec<vk::SwapchainKHR>> {
|
||||
let mut swapchains = Vec::with_capacity(create_infos.len());
|
||||
let err_code = (self.fp.create_shared_swapchains_khr)(
|
||||
(self.fp.create_shared_swapchains_khr)(
|
||||
self.handle,
|
||||
create_infos.len() as u32,
|
||||
create_infos.as_ptr(),
|
||||
allocation_callbacks.as_raw_ptr(),
|
||||
swapchains.as_mut_ptr(),
|
||||
);
|
||||
)
|
||||
.result()?;
|
||||
swapchains.set_len(create_infos.len());
|
||||
err_code.result_with_success(swapchains)
|
||||
Ok(swapchains)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -90,16 +90,17 @@ impl RayTracingPipeline {
|
|||
data_size: usize,
|
||||
) -> VkResult<Vec<u8>> {
|
||||
let mut data = Vec::<u8>::with_capacity(data_size);
|
||||
let err_code = (self.fp.get_ray_tracing_shader_group_handles_khr)(
|
||||
(self.fp.get_ray_tracing_shader_group_handles_khr)(
|
||||
self.handle,
|
||||
pipeline,
|
||||
first_group,
|
||||
group_count,
|
||||
data_size,
|
||||
data.as_mut_ptr() as *mut std::ffi::c_void,
|
||||
);
|
||||
data.as_mut_ptr().cast(),
|
||||
)
|
||||
.result()?;
|
||||
data.set_len(data_size);
|
||||
err_code.result_with_success(data)
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetRayTracingCaptureReplayShaderGroupHandlesKHR.html>
|
||||
|
@ -111,8 +112,8 @@ impl RayTracingPipeline {
|
|||
group_count: u32,
|
||||
data_size: usize,
|
||||
) -> VkResult<Vec<u8>> {
|
||||
let mut data: Vec<u8> = Vec::with_capacity(data_size);
|
||||
let err_code = (self
|
||||
let mut data = Vec::<u8>::with_capacity(data_size);
|
||||
(self
|
||||
.fp
|
||||
.get_ray_tracing_capture_replay_shader_group_handles_khr)(
|
||||
self.handle,
|
||||
|
@ -120,10 +121,11 @@ impl RayTracingPipeline {
|
|||
first_group,
|
||||
group_count,
|
||||
data_size,
|
||||
data.as_mut_ptr() as *mut _,
|
||||
);
|
||||
data.as_mut_ptr().cast(),
|
||||
)
|
||||
.result()?;
|
||||
data.set_len(data_size);
|
||||
err_code.result_with_success(data)
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdTraceRaysIndirectKHR.html>
|
||||
|
|
|
@ -49,8 +49,9 @@ where
|
|||
|
||||
let err_code = f(&mut count, data.as_mut_ptr());
|
||||
if err_code != vk::Result::INCOMPLETE {
|
||||
err_code.result()?;
|
||||
data.set_len(count.try_into().expect("`N` failed to convert to `usize`"));
|
||||
break err_code.result_with_success(data);
|
||||
break Ok(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue