From a0db2a2355234efb47f8fe49921f042c697ba53f Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 19 Jan 2024 12:32:10 -0500 Subject: [PATCH] Make sure to copy all of the buffers into the resource array for dx12. (#5091) * Make sure to copy all of the buffers into the resource array for dx12. Fixes #5088. Even though we're telling DX12 that the maximum frame latency should be our non-padded value, the swap chain may request any of the buffers allocated to it. * Up the maximum frame latency on the DX12 backend to allow a larger range. --- wgpu-hal/src/dx12/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index d56e5efa0..362097e74 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -660,10 +660,14 @@ impl crate::Surface for Surface { let non_srgb_format = auxil::dxgi::conv::map_texture_format_nosrgb(config.format); + // The range for `SetMaximumFrameLatency` is 1-16 so the maximum latency requested should be 15 because we add 1. + // https://learn.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgidevice1-setmaximumframelatency + debug_assert!(config.maximum_frame_latency <= 15); + // Nvidia recommends to use 1-2 more buffers than the maximum latency // https://developer.nvidia.com/blog/advanced-api-performance-swap-chains/ // For high latency extra buffers seems excessive, so go with a minimum of 3 and beyond that add 1. - let swap_chain_buffer = (config.maximum_frame_latency + 1).min(3); + let swap_chain_buffer = (config.maximum_frame_latency + 1).min(16); let swap_chain = match self.swap_chain.write().take() { //Note: this path doesn't properly re-initialize all of the things @@ -805,8 +809,8 @@ impl crate::Surface for Surface { unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) }; let waitable = unsafe { swap_chain.GetFrameLatencyWaitableObject() }; - let mut resources = Vec::with_capacity(config.maximum_frame_latency as usize); - for i in 0..config.maximum_frame_latency { + let mut resources = Vec::with_capacity(swap_chain_buffer as usize); + for i in 0..swap_chain_buffer { let mut resource = d3d12::Resource::null(); unsafe { swap_chain.GetBuffer(i, &d3d12_ty::ID3D12Resource::uuidof(), resource.mut_void())