checkpoint

Junkui Zhang created

Change summary

crates/gpui/src/platform/windows/directx_atlas.rs    | 14 +++
crates/gpui/src/platform/windows/directx_renderer.rs | 64 +++++++++++--
2 files changed, 66 insertions(+), 12 deletions(-)

Detailed changes

crates/gpui/src/platform/windows/directx_atlas.rs 🔗

@@ -53,6 +53,20 @@ impl DirectXAtlas {
         let tex = lock.texture(id);
         tex.view.clone()
     }
+
+    pub(crate) fn handle_device_lost(
+        &self,
+        device: ID3D11Device,
+        device_context: ID3D11DeviceContext,
+    ) -> anyhow::Result<()> {
+        let mut lock = self.0.lock();
+        lock.device = device;
+        lock.device_context = device_context;
+        lock.monochrome_textures = AtlasTextureList::default();
+        lock.polychrome_textures = AtlasTextureList::default();
+        lock.tiles_by_key.clear();
+        Ok(())
+    }
 }
 
 impl PlatformAtlas for DirectXAtlas {

crates/gpui/src/platform/windows/directx_renderer.rs 🔗

@@ -25,13 +25,14 @@ const RENDER_TARGET_FORMAT: DXGI_FORMAT = DXGI_FORMAT_B8G8R8A8_UNORM;
 const MULTISAMPLE_COUNT: u32 = 4;
 
 pub(crate) struct DirectXRenderer {
+    hwnd: HWND,
     atlas: Arc<DirectXAtlas>,
     devices: DirectXDevices,
     resources: DirectXResources,
     globals: DirectXGlobalElements,
     pipelines: DirectXRenderPipelines,
     #[cfg(not(feature = "enable-renderdoc"))]
-    _direct_composition: DirectComposition,
+    _direct_composition: ManuallyDrop<DirectComposition>,
 }
 
 /// Direct3D objects
@@ -121,19 +122,22 @@ impl DirectXRenderer {
         ));
 
         #[cfg(not(feature = "enable-renderdoc"))]
-        let resources = DirectXResources::new(devices)?;
+        let resources = DirectXResources::new(devices).unwrap();
         #[cfg(feature = "enable-renderdoc")]
         let resources = DirectXResources::new(devices, hwnd)?;
 
-        let globals = DirectXGlobalElements::new(&devices.device)?;
-        let pipelines = DirectXRenderPipelines::new(&devices.device)?;
+        let globals = DirectXGlobalElements::new(&devices.device).unwrap();
+        let pipelines = DirectXRenderPipelines::new(&devices.device).unwrap();
 
         #[cfg(not(feature = "enable-renderdoc"))]
-        let direct_composition = DirectComposition::new(&devices.dxgi_device, hwnd)?;
+        let direct_composition = DirectComposition::new(&devices.dxgi_device, hwnd).unwrap();
         #[cfg(not(feature = "enable-renderdoc"))]
-        direct_composition.set_swap_chain(&resources.swap_chain)?;
+        direct_composition
+            .set_swap_chain(&resources.swap_chain)
+            .unwrap();
 
         Ok(DirectXRenderer {
+            hwnd,
             atlas,
             devices: devices.clone(),
             resources,
@@ -208,6 +212,34 @@ impl DirectXRenderer {
     }
 
     fn handle_device_lost(&mut self) -> Result<()> {
+        let devices = DirectXDevices::new().context("Recreating DirectX devices")?;
+        unsafe {
+            ManuallyDrop::drop(&mut self._direct_composition);
+        }
+        self.atlas
+            .handle_device_lost(devices.device.clone(), devices.device_context.clone());
+        #[cfg(not(feature = "enable-renderdoc"))]
+        let resources = DirectXResources::new(&devices).unwrap();
+        #[cfg(feature = "enable-renderdoc")]
+        let resources = DirectXResources::new(devices, hwnd)?;
+        let globals = DirectXGlobalElements::new(&devices.device).unwrap();
+        let pipelines = DirectXRenderPipelines::new(&devices.device).unwrap();
+
+        #[cfg(not(feature = "enable-renderdoc"))]
+        let direct_composition = DirectComposition::new(&devices.dxgi_device, self.hwnd).unwrap();
+        #[cfg(not(feature = "enable-renderdoc"))]
+        direct_composition
+            .set_swap_chain(&resources.swap_chain)
+            .unwrap();
+
+        self.devices = devices;
+        self.resources = resources;
+        self.globals = globals;
+        self.pipelines = pipelines;
+        #[cfg(not(feature = "enable-renderdoc"))]
+        {
+            self._direct_composition = direct_composition;
+        }
         Ok(())
     }
 
@@ -553,16 +585,16 @@ impl DirectXRenderPipelines {
 
 #[cfg(not(feature = "enable-renderdoc"))]
 impl DirectComposition {
-    pub fn new(dxgi_device: &IDXGIDevice, hwnd: HWND) -> Result<Self> {
-        let comp_device = get_comp_device(&dxgi_device)?;
-        let comp_target = unsafe { comp_device.CreateTargetForHwnd(hwnd, true) }?;
-        let comp_visual = unsafe { comp_device.CreateVisual() }?;
+    pub fn new(dxgi_device: &IDXGIDevice, hwnd: HWND) -> Result<ManuallyDrop<Self>> {
+        let comp_device = get_comp_device(&dxgi_device).unwrap();
+        let comp_target = unsafe { comp_device.CreateTargetForHwnd(hwnd, true) }.unwrap();
+        let comp_visual = unsafe { comp_device.CreateVisual() }.unwrap();
 
-        Ok(Self {
+        Ok(ManuallyDrop::new(Self {
             comp_device,
             comp_target,
             comp_visual,
-        })
+        }))
     }
 
     pub fn set_swap_chain(&self, swap_chain: &IDXGISwapChain1) -> Result<()> {
@@ -945,6 +977,14 @@ struct PathSprite {
     color: Background,
 }
 
+impl Drop for DirectXRenderer {
+    fn drop(&mut self) {
+        unsafe {
+            ManuallyDrop::drop(&mut self._direct_composition);
+        }
+    }
+}
+
 impl Drop for DirectXResources {
     fn drop(&mut self) {
         unsafe {