test(d3d9): Add Direct3D 9 render test
Something seems to be broken though, it's not rendering the correct channel
This commit is contained in:
parent
5a35a2bd1e
commit
d33c2a84b2
|
@ -195,10 +195,10 @@ pub mod d3d9_hello_triangle {
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use librashader_common::{GetSize, Viewport};
|
use librashader_common::{GetSize, Viewport};
|
||||||
|
use librashader_runtime::image::{Image, UVDirection, ARGB8, BGRA8, RGBA8};
|
||||||
use librashader_runtime_d3d9::options::FilterChainOptionsD3D9;
|
use librashader_runtime_d3d9::options::FilterChainOptionsD3D9;
|
||||||
use librashader_runtime_d3d9::FilterChainD3D9;
|
use librashader_runtime_d3d9::FilterChainD3D9;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use librashader_runtime::image::{Image, UVDirection, ARGB8, BGRA8, RGBA8};
|
|
||||||
|
|
||||||
pub struct Sample {
|
pub struct Sample {
|
||||||
pub direct3d: IDirect3D9,
|
pub direct3d: IDirect3D9,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
|
|
||||||
const FILTER_PATH: &str = "../test/shaders_slang/test/feedback.slangp";
|
const FILTER_PATH: &str = "../test/shaders_slang/crt/crt-geom.slangp";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn triangle_d3d9() {
|
fn triangle_d3d9() {
|
||||||
|
|
|
@ -29,6 +29,8 @@ wgpu = ["librashader/runtime-wgpu", "dep:wgpu", "dep:wgpu-types"]
|
||||||
|
|
||||||
d3d11 = ["librashader/runtime-d3d11", "dep:windows"]
|
d3d11 = ["librashader/runtime-d3d11", "dep:windows"]
|
||||||
d3d12 = ["librashader/runtime-d3d12", "dep:windows"]
|
d3d12 = ["librashader/runtime-d3d12", "dep:windows"]
|
||||||
|
d3d9 = ["librashader/runtime-d3d9", "dep:windows"]
|
||||||
|
|
||||||
metal = ["librashader/runtime-metal", "dep:objc2", "dep:objc2-metal"]
|
metal = ["librashader/runtime-metal", "dep:objc2", "dep:objc2-metal"]
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies.windows]
|
[target.'cfg(windows)'.dependencies.windows]
|
||||||
|
|
169
librashader-test/src/render/d3d9.rs
Normal file
169
librashader-test/src/render/d3d9.rs
Normal file
|
@ -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,
|
||||||
|
&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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,9 @@ pub mod d3d11;
|
||||||
#[cfg(feature = "d3d12")]
|
#[cfg(feature = "d3d12")]
|
||||||
pub mod d3d12;
|
pub mod d3d12;
|
||||||
|
|
||||||
|
#[cfg(feature = "d3d9")]
|
||||||
|
pub mod d3d9;
|
||||||
|
|
||||||
#[cfg(feature = "opengl")]
|
#[cfg(feature = "opengl")]
|
||||||
pub mod gl;
|
pub mod gl;
|
||||||
|
|
||||||
|
@ -48,7 +51,7 @@ mod test {
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
const IMAGE_PATH: &str = "../triangle.png";
|
const IMAGE_PATH: &str = "../triangle.png";
|
||||||
const FILTER_PATH: &str = "../test/shaders_slang/crt/crt-royale.slangp";
|
const FILTER_PATH: &str = "../test/shaders_slang/crt/crt-geom.slangp";
|
||||||
|
|
||||||
// const FILTER_PATH: &str =
|
// const FILTER_PATH: &str =
|
||||||
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
|
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
|
||||||
|
@ -98,6 +101,12 @@ mod test {
|
||||||
do_test::<crate::render::mtl::Metal>()
|
do_test::<crate::render::mtl::Metal>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "d3d9")]
|
||||||
|
pub fn test_d3d9() -> anyhow::Result<()> {
|
||||||
|
do_test::<crate::render::d3d9::Direct3D9>()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn compare<A: RenderTest, B: RenderTest>() -> anyhow::Result<()> {
|
pub fn compare<A: RenderTest, B: RenderTest>() -> anyhow::Result<()> {
|
||||||
let a = A::new(IMAGE_PATH)?;
|
let a = A::new(IMAGE_PATH)?;
|
||||||
let b = B::new(IMAGE_PATH)?;
|
let b = B::new(IMAGE_PATH)?;
|
||||||
|
|
Loading…
Reference in a new issue