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(())
}
fn present(&self) -> Result<()> {
fn present(&mut self) -> Result<()> {
unsafe {
self.devices.device_context.ResolveSubresource(
&*self.resources.render_target,
@ -191,11 +191,26 @@ impl DirectXRenderer {
self.devices
.device_context
.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(())
}
fn handle_device_lost(&mut self) -> Result<()> {
Ok(())
}
pub(crate) fn draw(&mut self, scene: &Scene) -> Result<()> {
self.pre_draw()?;
for batch in scene.batches() {
@ -237,13 +252,33 @@ impl DirectXRenderer {
ManuallyDrop::drop(&mut self.resources.render_target);
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,
width,
height,
RENDER_TARGET_FORMAT,
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
.recreate_resources(&self.devices, width, height)?;