init handle_device_lost

This commit is contained in:
Junkui Zhang 2025-07-22 15:35:27 +08:00
parent 3978bba5a7
commit 275d84d566

View file

@ -179,7 +179,7 @@ impl DirectXRenderer {
Ok(()) Ok(())
} }
fn present(&self) -> Result<()> { fn present(&mut self) -> Result<()> {
unsafe { unsafe {
self.devices.device_context.ResolveSubresource( self.devices.device_context.ResolveSubresource(
&*self.resources.render_target, &*self.resources.render_target,
@ -191,11 +191,26 @@ impl DirectXRenderer {
self.devices self.devices
.device_context .device_context
.OMSetRenderTargets(Some(&self.resources.render_target_view), None); .OMSetRenderTargets(Some(&self.resources.render_target_view), None);
self.resources.swap_chain.Present(0, DXGI_PRESENT(0)).ok()?; let result = self.resources.swap_chain.Present(0, DXGI_PRESENT(0));
// Presenting the swap chain can fail if the DirectX device was removed or reset.
if result == DXGI_ERROR_DEVICE_REMOVED || result == DXGI_ERROR_DEVICE_RESET {
let reason = self.devices.device.GetDeviceRemovedReason();
log::error!(
"DirectX device removed or reset when drawing. Reason: {:?}",
reason
);
self.handle_device_lost()?;
} else {
result.ok()?;
}
} }
Ok(()) Ok(())
} }
fn handle_device_lost(&mut self) -> Result<()> {
Ok(())
}
pub(crate) fn draw(&mut self, scene: &Scene) -> Result<()> { pub(crate) fn draw(&mut self, scene: &Scene) -> Result<()> {
self.pre_draw()?; self.pre_draw()?;
for batch in scene.batches() { for batch in scene.batches() {
@ -237,13 +252,33 @@ impl DirectXRenderer {
ManuallyDrop::drop(&mut self.resources.render_target); ManuallyDrop::drop(&mut self.resources.render_target);
drop(self.resources.render_target_view[0].take().unwrap()); drop(self.resources.render_target_view[0].take().unwrap());
self.resources.swap_chain.ResizeBuffers( let result = self.resources.swap_chain.ResizeBuffers(
BUFFER_COUNT as u32, BUFFER_COUNT as u32,
width, width,
height, height,
RENDER_TARGET_FORMAT, RENDER_TARGET_FORMAT,
DXGI_SWAP_CHAIN_FLAG(0), DXGI_SWAP_CHAIN_FLAG(0),
)?; );
// Resizing the swap chain requires a call to the underlying DXGI adapter, which can return the device removed error.
// The app might have moved to a monitor that's attached to a different graphics device.
// When a graphics device is removed or reset, the desktop resolution often changes, resulting in a window size change.
match result {
Ok(_) => {}
Err(e) => {
if e.code() == DXGI_ERROR_DEVICE_REMOVED || e.code() == DXGI_ERROR_DEVICE_RESET
{
let reason = self.devices.device.GetDeviceRemovedReason();
log::error!(
"DirectX device removed or reset when resizing. Reason: {:?}",
reason
);
self.handle_device_lost()?;
return Ok(());
}
log::error!("Failed to resize swap chain: {:?}", e);
return Err(e.into());
}
}
self.resources self.resources
.recreate_resources(&self.devices, width, height)?; .recreate_resources(&self.devices, width, height)?;