-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(d3d9): Add Direct3D 9 render test
Something seems to be broken though, it's not rendering the correct channel
- Loading branch information
Showing
5 changed files
with
183 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
use crate::render::RenderTest; | ||
use anyhow::anyhow; | ||
use image::RgbaImage; | ||
use librashader::runtime::d3d9::{FilterChain, FilterChainOptions}; | ||
use librashader::runtime::Viewport; | ||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, ARGB8, BGRA8}; | ||
use std::path::Path; | ||
use windows::Win32::Foundation::{HWND, TRUE}; | ||
use windows::Win32::Graphics::Direct3D9::{ | ||
Direct3DCreate9, IDirect3D9, IDirect3DDevice9, IDirect3DTexture9, D3DADAPTER_DEFAULT, | ||
D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_R8G8B8, | ||
D3DFMT_UNKNOWN, D3DLOCKED_RECT, D3DPOOL_DEFAULT, D3DPOOL_MANAGED, D3DPOOL_SCRATCH, | ||
D3DPOOL_SYSTEMMEM, D3DPRESENT_INTERVAL_IMMEDIATE, D3DPRESENT_PARAMETERS, D3DRS_CLIPPING, | ||
D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ZFUNC, D3DSURFACE_DESC, | ||
D3DSWAPEFFECT_DISCARD, D3DUSAGE_DYNAMIC, D3DUSAGE_RENDERTARGET, D3D_SDK_VERSION, | ||
}; | ||
|
||
pub struct Direct3D9 { | ||
pub texture: IDirect3DTexture9, | ||
pub image: Image<BGRA8>, | ||
pub direct3d: IDirect3D9, | ||
pub device: IDirect3DDevice9, | ||
} | ||
|
||
impl RenderTest for Direct3D9 { | ||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self> | ||
where | ||
Self: Sized, | ||
{ | ||
Direct3D9::new(path) | ||
} | ||
|
||
fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> { | ||
unsafe { | ||
let mut filter_chain = FilterChain::load_from_path( | ||
path, | ||
&self.device, | ||
Some(&FilterChainOptions { | ||
force_no_mipmaps: false, | ||
disable_cache: false, | ||
}), | ||
)?; | ||
|
||
let mut render_texture = None; | ||
|
||
self.device.CreateTexture( | ||
self.image.size.width, | ||
self.image.size.height, | ||
1, | ||
D3DUSAGE_RENDERTARGET as u32, | ||
D3DFMT_A8R8G8B8, | ||
D3DPOOL_DEFAULT, | ||
&mut render_texture, | ||
std::ptr::null_mut(), | ||
)?; | ||
|
||
let render_texture = render_texture | ||
.ok_or_else(|| anyhow!("Unable to create Direct3D 9 render texture"))?; | ||
|
||
let mut copy_texture = None; | ||
|
||
self.device.CreateOffscreenPlainSurface( | ||
self.image.size.width, | ||
self.image.size.height, | ||
D3DFMT_A8R8G8B8, | ||
D3DPOOL_SYSTEMMEM, | ||
&mut copy_texture, | ||
std::ptr::null_mut(), | ||
)?; | ||
|
||
let copy_texture = | ||
copy_texture.ok_or_else(|| anyhow!("Unable to create Direct3D 9 copy texture"))?; | ||
|
||
let surface = render_texture.GetSurfaceLevel(0)?; | ||
|
||
filter_chain.frame( | ||
self.texture.clone(), | ||
&Viewport::new_render_target_sized_origin(surface.clone(), None)?, | ||
frame_count, | ||
None, | ||
)?; | ||
|
||
self.device.GetRenderTargetData(&surface, ©_texture)?; | ||
|
||
let mut desc = D3DSURFACE_DESC::default(); | ||
surface.GetDesc(&mut desc)?; | ||
|
||
let mut lock = D3DLOCKED_RECT::default(); | ||
copy_texture.LockRect(&mut lock, std::ptr::null_mut(), 0)?; | ||
let mut buffer = vec![0u8; desc.Height as usize * lock.Pitch as usize]; | ||
|
||
std::ptr::copy_nonoverlapping(lock.pBits.cast(), buffer.as_mut_ptr(), buffer.len()); | ||
copy_texture.UnlockRect()?; | ||
|
||
BGRA8::convert(&mut buffer); | ||
|
||
let image = RgbaImage::from_raw(self.image.size.width, self.image.size.height, buffer) | ||
.ok_or(anyhow!("Unable to create image from data"))?; | ||
|
||
Ok(image) | ||
} | ||
} | ||
} | ||
|
||
impl Direct3D9 { | ||
pub fn new(image_path: impl AsRef<Path>) -> anyhow::Result<Self> { | ||
let direct3d = unsafe { | ||
Direct3DCreate9(D3D_SDK_VERSION) | ||
.ok_or_else(|| anyhow!("Unable to create Direct3D 9 device"))? | ||
}; | ||
|
||
let image = Image::<BGRA8>::load(image_path, UVDirection::TopLeft)?; | ||
|
||
let mut present_params: D3DPRESENT_PARAMETERS = Default::default(); | ||
present_params.BackBufferWidth = image.size.width; | ||
present_params.BackBufferHeight = image.size.height; | ||
present_params.Windowed = TRUE; | ||
present_params.SwapEffect = D3DSWAPEFFECT_DISCARD; | ||
present_params.BackBufferFormat = D3DFMT_A8R8G8B8; | ||
present_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE as u32; | ||
|
||
let device = unsafe { | ||
let mut device = None; | ||
direct3d.CreateDevice( | ||
D3DADAPTER_DEFAULT, | ||
D3DDEVTYPE_HAL, | ||
HWND(std::ptr::null_mut()), | ||
D3DCREATE_HARDWARE_VERTEXPROCESSING as u32, | ||
&mut present_params, | ||
&mut device, | ||
)?; | ||
device.ok_or_else(|| anyhow!("Unable to create Direct3D 9 device"))? | ||
}; | ||
|
||
let texture = unsafe { | ||
let mut texture = None; | ||
device.CreateTexture( | ||
image.size.width, | ||
image.size.height, | ||
1, | ||
0, | ||
D3DFMT_A8R8G8B8, | ||
D3DPOOL_MANAGED, | ||
&mut texture, | ||
std::ptr::null_mut(), | ||
)?; | ||
|
||
texture.ok_or_else(|| anyhow!("Unable to create Direct3D 9 texture"))? | ||
}; | ||
|
||
unsafe { | ||
let mut lock = D3DLOCKED_RECT::default(); | ||
texture.LockRect(0, &mut lock, std::ptr::null_mut(), 0)?; | ||
std::ptr::copy_nonoverlapping( | ||
image.bytes.as_ptr(), | ||
lock.pBits.cast(), | ||
image.bytes.len(), | ||
); | ||
texture.UnlockRect(0)?; | ||
} | ||
|
||
Ok(Self { | ||
texture, | ||
image, | ||
direct3d, | ||
device, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters