This commit is contained in:
Junkui Zhang 2025-07-17 15:52:51 +08:00
parent 499b3b6b50
commit 8c1d9f75d1

View file

@ -29,6 +29,8 @@ pub(crate) struct DirectXRenderer {
resources: DirectXResources,
globals: DirectXGlobalElements,
pipelines: DirectXRenderPipelines,
// #[cfg(not(feature = "enable-renderdoc"))]
_direct_composition: DirectComposition,
}
/// Direct3D objects
@ -42,17 +44,14 @@ pub(crate) struct DirectXDevices {
struct DirectXResources {
// Direct3D rendering objects
swap_chain: ManuallyDrop<IDXGISwapChain1>,
swap_chain: IDXGISwapChain1,
render_target: ManuallyDrop<ID3D11Texture2D>,
render_target_view: [Option<ID3D11RenderTargetView>; 1],
msaa_target: ID3D11Texture2D,
msaa_view: ID3D11RenderTargetView,
msaa_view: [Option<ID3D11RenderTargetView>; 1],
// Cached viewport
viewport: [D3D11_VIEWPORT; 1],
// #[cfg(not(feature = "enable-renderdoc"))]
_direct_composition: DirectComposition,
}
struct DirectXRenderPipelines {
@ -115,12 +114,18 @@ impl DirectXRenderer {
let resources = DirectXResources::new(devices, hwnd)?;
let globals = DirectXGlobalElements::new(&devices.device)?;
let pipelines = DirectXRenderPipelines::new(&devices.device)?;
// #[cfg(not(feature = "enable-renderdoc"))]
let direct_composition = DirectComposition::new(&devices.dxgi_device, hwnd)?;
// #[cfg(not(feature = "enable-renderdoc"))]
direct_composition.set_swap_chain(&resources.swap_chain)?;
Ok(DirectXRenderer {
atlas,
devices: devices.clone(),
resources,
globals,
pipelines,
// #[cfg(not(feature = "enable-renderdoc"))]
_direct_composition: direct_composition,
})
}
@ -143,10 +148,10 @@ impl DirectXRenderer {
unsafe {
self.devices
.device_context
.ClearRenderTargetView(&self.resources.msaa_view, &[0.0; 4]);
.ClearRenderTargetView(self.resources.msaa_view[0].as_ref().unwrap(), &[0.0; 4]);
self.devices
.device_context
.OMSetRenderTargets(Some(&[Some(self.resources.msaa_view.clone())]), None);
.OMSetRenderTargets(Some(&self.resources.msaa_view), None);
self.devices
.device_context
.RSSetViewports(Some(&self.resources.viewport));
@ -159,6 +164,23 @@ impl DirectXRenderer {
Ok(())
}
fn present(&self) -> Result<()> {
unsafe {
self.devices.device_context.ResolveSubresource(
&*self.resources.render_target,
0,
&self.resources.msaa_target,
0,
RENDER_TARGET_FORMAT,
);
self.devices
.device_context
.OMSetRenderTargets(Some(&self.resources.render_target_view), None);
self.resources.swap_chain.Present(0, DXGI_PRESENT(0)).ok()?;
}
Ok(())
}
pub(crate) fn draw(&mut self, scene: &Scene) -> Result<()> {
self.pre_draw()?;
for batch in scene.batches() {
@ -185,64 +207,29 @@ impl DirectXRenderer {
scene.polychrome_sprites.len(),
scene.surfaces.len(),))?;
}
unsafe {
self.devices.device_context.ResolveSubresource(
&*self.resources.render_target,
0,
&self.resources.msaa_target,
0,
RENDER_TARGET_FORMAT,
);
self.devices
.device_context
.OMSetRenderTargets(Some(&self.resources.render_target_view), None);
self.resources.swap_chain.Present(0, DXGI_PRESENT(0)).ok()?;
}
Ok(())
self.present()
}
pub(crate) fn resize(&mut self, new_size: Size<DevicePixels>) -> Result<()> {
unsafe {
let width = new_size.width.0 as u32;
let height = new_size.height.0 as u32;
self.devices.device_context.OMSetRenderTargets(None, None);
ManuallyDrop::drop(&mut self.resources.render_target);
}
drop(self.resources.render_target_view[0].take().unwrap());
unsafe {
drop(self.resources.render_target_view[0].take().unwrap());
self.resources.swap_chain.ResizeBuffers(
BUFFER_COUNT as u32,
width,
height,
RENDER_TARGET_FORMAT,
DXGI_SWAP_CHAIN_FLAG(0),
)?;
self.resources
.swap_chain
.ResizeBuffers(
BUFFER_COUNT as u32,
new_size.width.0 as u32,
new_size.height.0 as u32,
RENDER_TARGET_FORMAT,
DXGI_SWAP_CHAIN_FLAG(0),
)
.unwrap();
}
let (render_target, render_target_view) =
create_render_target_and_its_view(&self.resources.swap_chain, &self.devices.device)
.unwrap();
self.resources.render_target = render_target;
self.resources.render_target_view = render_target_view;
unsafe {
.recreate_resources(&self.devices, width, height)?;
self.devices
.device_context
.OMSetRenderTargets(Some(&self.resources.render_target_view), None);
}
let (msaa_target, msaa_view) = create_msaa_target_and_its_view(
&self.devices.device,
new_size.width.0 as u32,
new_size.height.0 as u32,
)?;
self.resources.msaa_target = msaa_target;
self.resources.msaa_view = msaa_view;
self.resources.viewport = set_viewport(
&self.devices.device_context,
new_size.width.0 as f32,
new_size.height.0 as f32,
);
Ok(())
}
@ -411,20 +398,13 @@ impl DirectXResources {
// #[cfg(feature = "enable-renderdoc")]
// let swap_chain =
// create_swap_chain_default(&devices.dxgi_factory, &devices.device, hwnd, transparent)?;
// #[cfg(not(feature = "enable-renderdoc"))]
let direct_composition = DirectComposition::new(&devices.dxgi_device, hwnd)?;
// #[cfg(not(feature = "enable-renderdoc"))]
direct_composition.set_swap_chain(&swap_chain)?;
let (render_target, render_target_view) =
create_render_target_and_its_view(&swap_chain, &devices.device)?;
let (msaa_target, msaa_view) =
create_msaa_target_and_its_view(&devices.device, width, height)?;
let viewport = set_viewport(&devices.device_context, width as f32, height as f32);
unsafe {
devices
.device_context
.OMSetRenderTargets(Some(&render_target_view), None);
}
let (render_target, render_target_view, msaa_target, msaa_view, viewport) =
create_resources(devices, &swap_chain, width, height)?;
// unsafe {
// devices
// .device_context
// .OMSetRenderTargets(Some(&render_target_view), None);
// }
set_rasterizer_state(&devices.device, &devices.device_context)?;
Ok(Self {
@ -434,10 +414,25 @@ impl DirectXResources {
msaa_target,
msaa_view,
viewport,
// #[cfg(not(feature = "enable-renderdoc"))]
_direct_composition: direct_composition,
})
}
#[inline]
fn recreate_resources(
&mut self,
devices: &DirectXDevices,
width: u32,
height: u32,
) -> Result<()> {
let (render_target, render_target_view, msaa_target, msaa_view, viewport) =
create_resources(devices, &self.swap_chain, width, height)?;
self.render_target = render_target;
self.render_target_view = render_target_view;
self.msaa_target = msaa_target;
self.msaa_view = msaa_view;
self.viewport = viewport;
Ok(())
}
}
impl DirectXRenderPipelines {
@ -909,7 +904,6 @@ impl Drop for DirectXResources {
fn drop(&mut self) {
unsafe {
ManuallyDrop::drop(&mut self.render_target);
ManuallyDrop::drop(&mut self.swap_chain);
}
}
}
@ -961,6 +955,8 @@ fn get_device(
D3D_DRIVER_TYPE_UNKNOWN,
HMODULE::default(),
device_flags,
// 4x MSAA is required for Direct3D Feature Level 10.1 or better
// 8x MSAA is required for Direct3D Feature Level 11.0 or better
Some(&[D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1]),
D3D11_SDK_VERSION,
device,
@ -980,7 +976,7 @@ fn create_swap_chain(
device: &ID3D11Device,
width: u32,
height: u32,
) -> Result<ManuallyDrop<IDXGISwapChain1>> {
) -> Result<IDXGISwapChain1> {
let desc = DXGI_SWAP_CHAIN_DESC1 {
Width: width,
Height: height,
@ -998,9 +994,7 @@ fn create_swap_chain(
AlphaMode: DXGI_ALPHA_MODE_PREMULTIPLIED,
Flags: 0,
};
Ok(ManuallyDrop::new(unsafe {
dxgi_factory.CreateSwapChainForComposition(device, &desc, None)?
}))
Ok(unsafe { dxgi_factory.CreateSwapChainForComposition(device, &desc, None)? })
}
// #[cfg(feature = "enable-renderdoc")]
@ -1010,7 +1004,7 @@ fn create_swap_chain_default(
hwnd: HWND,
width: u32,
height: u32,
) -> Result<ManuallyDrop<IDXGISwapChain1>> {
) -> Result<IDXGISwapChain1> {
use windows::Win32::Graphics::Dxgi::DXGI_MWA_NO_ALT_ENTER;
let desc = DXGI_SWAP_CHAIN_DESC1 {
@ -1032,7 +1026,33 @@ fn create_swap_chain_default(
let swap_chain =
unsafe { dxgi_factory.CreateSwapChainForHwnd(device, hwnd, &desc, None, None) }?;
unsafe { dxgi_factory.MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER) }?;
Ok(ManuallyDrop::new(swap_chain))
Ok(swap_chain)
}
#[inline]
fn create_resources(
devices: &DirectXDevices,
swap_chain: &IDXGISwapChain1,
width: u32,
height: u32,
) -> Result<(
ManuallyDrop<ID3D11Texture2D>,
[Option<ID3D11RenderTargetView>; 1],
ID3D11Texture2D,
[Option<ID3D11RenderTargetView>; 1],
[D3D11_VIEWPORT; 1],
)> {
let (render_target, render_target_view) =
create_render_target_and_its_view(&swap_chain, &devices.device)?;
let (msaa_target, msaa_view) = create_msaa_target_and_its_view(&devices.device, width, height)?;
let viewport = set_viewport(&devices.device_context, width as f32, height as f32);
Ok((
render_target,
render_target_view,
msaa_target,
msaa_view,
viewport,
))
}
#[inline]
@ -1057,7 +1077,7 @@ fn create_msaa_target_and_its_view(
device: &ID3D11Device,
width: u32,
height: u32,
) -> Result<(ID3D11Texture2D, ID3D11RenderTargetView)> {
) -> Result<(ID3D11Texture2D, [Option<ID3D11RenderTargetView>; 1])> {
let msaa_target = unsafe {
let mut output = None;
let desc = D3D11_TEXTURE2D_DESC {
@ -1083,7 +1103,7 @@ fn create_msaa_target_and_its_view(
device.CreateRenderTargetView(&msaa_target, None, Some(&mut output))?;
output.unwrap()
};
Ok((msaa_target, msaa_view))
Ok((msaa_target, [Some(msaa_view)]))
}
#[inline]