dx11: get single pass working
This commit is contained in:
parent
5078015605
commit
2c953d638f
7 changed files with 248 additions and 55 deletions
|
@ -1,4 +1,4 @@
|
||||||
use crate::texture::OwnedTexture;
|
use crate::texture::{DxImageView, OwnedTexture, Texture};
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::Size;
|
use librashader_common::Size;
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
|
@ -15,13 +15,17 @@ use std::path::Path;
|
||||||
use bytemuck::offset_of;
|
use bytemuck::offset_of;
|
||||||
use windows::core::PCSTR;
|
use windows::core::PCSTR;
|
||||||
use windows::s;
|
use windows::s;
|
||||||
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_CONSTANT_BUFFER, D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext};
|
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_CONSTANT_BUFFER, D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
||||||
use crate::filter_pass::{ConstantBuffer, ConstantBufferBinding, FilterPass};
|
use crate::filter_pass::{ConstantBuffer, ConstantBufferBinding, FilterPass};
|
||||||
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
|
use crate::quad_render::DrawQuad;
|
||||||
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::d3d11_compile_bound_shader;
|
use crate::util::d3d11_compile_bound_shader;
|
||||||
|
|
||||||
|
// todo: get rid of preset
|
||||||
type ShaderPassMeta<'a> = (
|
type ShaderPassMeta<'a> = (
|
||||||
&'a ShaderPassConfig,
|
&'a ShaderPassConfig,
|
||||||
ShaderSource,
|
ShaderSource,
|
||||||
|
@ -30,14 +34,6 @@ type ShaderPassMeta<'a> = (
|
||||||
>,
|
>,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Default)]
|
|
||||||
struct D3D11VertexLayout {
|
|
||||||
position: [f32; 2],
|
|
||||||
texcoord: [f32; 2],
|
|
||||||
color: [f32; 4],
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct FilterChain {
|
pub struct FilterChain {
|
||||||
pub common: FilterCommon,
|
pub common: FilterCommon,
|
||||||
pub passes: Vec<FilterPass>,
|
pub passes: Vec<FilterPass>,
|
||||||
|
@ -53,6 +49,7 @@ pub struct FilterCommon {
|
||||||
pub(crate) preset: ShaderPreset,
|
pub(crate) preset: ShaderPreset,
|
||||||
pub(crate) luts: FxHashMap<usize, OwnedTexture>,
|
pub(crate) luts: FxHashMap<usize, OwnedTexture>,
|
||||||
pub samplers: SamplerSet,
|
pub samplers: SamplerSet,
|
||||||
|
pub(crate) draw_quad: DrawQuad,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterChain {
|
impl FilterChain {
|
||||||
|
@ -108,7 +105,7 @@ impl FilterChain {
|
||||||
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
||||||
eprintln!("{size}");
|
eprintln!("{size}");
|
||||||
unsafe {
|
unsafe {
|
||||||
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
||||||
ByteWidth: size,
|
ByteWidth: size,
|
||||||
Usage: D3D11_USAGE_DYNAMIC,
|
Usage: D3D11_USAGE_DYNAMIC,
|
||||||
BindFlags: D3D11_BIND_CONSTANT_BUFFER,
|
BindFlags: D3D11_BIND_CONSTANT_BUFFER,
|
||||||
|
@ -142,27 +139,8 @@ impl FilterChain {
|
||||||
let vs = d3d11_compile_bound_shader(device, &vertex_dxil, None,
|
let vs = d3d11_compile_bound_shader(device, &vertex_dxil, None,
|
||||||
ID3D11Device::CreateVertexShader)?;
|
ID3D11Device::CreateVertexShader)?;
|
||||||
|
|
||||||
let ia_desc = [
|
let ia_desc = DrawQuad::get_spirv_cross_vbo_desc();
|
||||||
D3D11_INPUT_ELEMENT_DESC {
|
let vao = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxil)?;
|
||||||
SemanticName: PCSTR(b"TEXCOORD\0".as_ptr()),
|
|
||||||
SemanticIndex: 0,
|
|
||||||
Format: DXGI_FORMAT_R32G32_FLOAT,
|
|
||||||
InputSlot: 0,
|
|
||||||
AlignedByteOffset: offset_of!(D3D11VertexLayout, position) as u32,
|
|
||||||
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
|
||||||
InstanceDataStepRate: 0,
|
|
||||||
},
|
|
||||||
D3D11_INPUT_ELEMENT_DESC {
|
|
||||||
SemanticName: PCSTR(b"TEXCOORD\0".as_ptr()),
|
|
||||||
SemanticIndex: 1,
|
|
||||||
Format: DXGI_FORMAT_R32G32_FLOAT,
|
|
||||||
InputSlot: 0,
|
|
||||||
AlignedByteOffset: offset_of!(D3D11VertexLayout, texcoord) as u32,
|
|
||||||
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
|
||||||
InstanceDataStepRate: 0,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
let vertex_ia = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxil)?;
|
|
||||||
|
|
||||||
let fragment_dxil = util::d3d_compile_shader(
|
let fragment_dxil = util::d3d_compile_shader(
|
||||||
hlsl.fragment.as_bytes(),
|
hlsl.fragment.as_bytes(),
|
||||||
|
@ -223,7 +201,7 @@ impl FilterChain {
|
||||||
reflection,
|
reflection,
|
||||||
compiled: hlsl,
|
compiled: hlsl,
|
||||||
vertex_shader: vs,
|
vertex_shader: vs,
|
||||||
vertex_layout: vertex_ia,
|
vertex_layout: vao,
|
||||||
pixel_shader: ps,
|
pixel_shader: ps,
|
||||||
uniform_bindings,
|
uniform_bindings,
|
||||||
uniform_buffer: ConstantBuffer::new(ubo_cbuffer),
|
uniform_buffer: ConstantBuffer::new(ubo_cbuffer),
|
||||||
|
@ -231,7 +209,6 @@ impl FilterChain {
|
||||||
source,
|
source,
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
Ok(filters)
|
Ok(filters)
|
||||||
}
|
}
|
||||||
|
@ -273,6 +250,8 @@ impl FilterChain {
|
||||||
unsafe {
|
unsafe {
|
||||||
device.GetImmediateContext(&mut device_context);
|
device.GetImmediateContext(&mut device_context);
|
||||||
}
|
}
|
||||||
|
let device_context = device_context.unwrap();
|
||||||
|
let draw_quad = DrawQuad::new(device, &device_context)?;
|
||||||
|
|
||||||
// todo: make vbo: d3d11.c 1376
|
// todo: make vbo: d3d11.c 1376
|
||||||
Ok(FilterChain {
|
Ok(FilterChain {
|
||||||
|
@ -284,7 +263,7 @@ impl FilterChain {
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
d3d11: Direct3D11 {
|
d3d11: Direct3D11 {
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
device_context: device_context.unwrap()
|
device_context
|
||||||
},
|
},
|
||||||
luts,
|
luts,
|
||||||
samplers,
|
samplers,
|
||||||
|
@ -294,7 +273,7 @@ impl FilterChain {
|
||||||
// output_textures: output_textures.into_boxed_slice(),
|
// output_textures: output_textures.into_boxed_slice(),
|
||||||
// feedback_textures: feedback_textures.into_boxed_slice(),
|
// feedback_textures: feedback_textures.into_boxed_slice(),
|
||||||
// history_textures,
|
// history_textures,
|
||||||
// draw_quad,
|
draw_quad,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -397,4 +376,38 @@ impl FilterChain {
|
||||||
|
|
||||||
Ok((passes, semantics))
|
Ok((passes, semantics))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn frame(&mut self, count: usize, viewport: &Size<u32>, input: DxImageView, output: OutputFramebuffer) -> util::Result<()> {
|
||||||
|
|
||||||
|
let passes = &mut self.passes;
|
||||||
|
|
||||||
|
if passes.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let filter = passes[0].config.filter;
|
||||||
|
let wrap_mode = passes[0].config.wrap_mode;
|
||||||
|
|
||||||
|
self.common.draw_quad.bind_vertices();
|
||||||
|
|
||||||
|
let original = Texture {
|
||||||
|
view: input,
|
||||||
|
filter,
|
||||||
|
wrap_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut source = original.clone();
|
||||||
|
|
||||||
|
|
||||||
|
for (index, pass) in passes.iter_mut().enumerate() {
|
||||||
|
pass.draw(index, &self.common, if pass.config.frame_count_mod > 0 {
|
||||||
|
count % pass.config.frame_count_mod as usize
|
||||||
|
} else {
|
||||||
|
count
|
||||||
|
} as u32, 1, viewport, &original, &source, RenderTarget::new(output.clone(), None))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl FilterPass {
|
||||||
binding: &TextureBinding,
|
binding: &TextureBinding,
|
||||||
texture: &Texture,
|
texture: &Texture,
|
||||||
) {
|
) {
|
||||||
texture_binding[binding.binding as usize] = Some(texture.handle.clone());
|
texture_binding[binding.binding as usize] = Some(texture.view.handle.clone());
|
||||||
sampler_binding[binding.binding as usize] = Some(samplers.get(texture.wrap_mode, texture.filter).clone());
|
sampler_binding[binding.binding as usize] = Some(samplers.get(texture.wrap_mode, texture.filter).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ impl FilterPass {
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset),
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset),
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset),
|
||||||
};
|
};
|
||||||
FilterPass::build_vec4(&mut buffer[offset..][..16], original.size);
|
FilterPass::build_vec4(&mut buffer[offset..][..16], original.view.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind Source sampler
|
// bind Source sampler
|
||||||
|
@ -203,7 +203,7 @@ impl FilterPass {
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset),
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset),
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset),
|
||||||
};
|
};
|
||||||
FilterPass::build_vec4(&mut buffer[offset..][..16], source.size);
|
FilterPass::build_vec4(&mut buffer[offset..][..16], source.view.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(binding) = self
|
if let Some(binding) = self
|
||||||
|
@ -223,7 +223,7 @@ impl FilterPass {
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset),
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset),
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset),
|
||||||
};
|
};
|
||||||
FilterPass::build_vec4(&mut buffer[offset..][..16], original.size);
|
FilterPass::build_vec4(&mut buffer[offset..][..16], original.view.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (index, output) in parent.history_textures.iter().enumerate() {
|
// for (index, output) in parent.history_textures.iter().enumerate() {
|
||||||
|
@ -365,7 +365,7 @@ impl FilterPass {
|
||||||
};
|
};
|
||||||
FilterPass::build_vec4(
|
FilterPass::build_vec4(
|
||||||
&mut buffer[offset..][..16],
|
&mut buffer[offset..][..16],
|
||||||
lut.image.size,
|
lut.image.view.size,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,10 +67,6 @@ use gfx_maths::Mat4;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
|
||||||
pub trait DXSample {
|
pub trait DXSample {
|
||||||
fn new() -> Result<Self>
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
|
|
||||||
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()>;
|
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()>;
|
||||||
|
|
||||||
fn update(&mut self) {}
|
fn update(&mut self) {}
|
||||||
|
@ -228,10 +224,15 @@ struct TriangleUniforms {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod d3d11_hello_triangle {
|
pub mod d3d11_hello_triangle {
|
||||||
|
use std::path::Path;
|
||||||
use super::*;
|
use super::*;
|
||||||
use gfx_maths::{Quaternion, Vec3};
|
use gfx_maths::{Quaternion, Vec3};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
use librashader_common::Size;
|
||||||
|
use crate::filter_chain::FilterChain;
|
||||||
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
|
use crate::texture::DxImageView;
|
||||||
|
|
||||||
const FRAME_COUNT: u32 = 2;
|
const FRAME_COUNT: u32 = 2;
|
||||||
|
|
||||||
|
@ -240,6 +241,7 @@ pub mod d3d11_hello_triangle {
|
||||||
pub device: ID3D11Device,
|
pub device: ID3D11Device,
|
||||||
pub context: ID3D11DeviceContext,
|
pub context: ID3D11DeviceContext,
|
||||||
pub resources: Option<Resources>,
|
pub resources: Option<Resources>,
|
||||||
|
pub filter: FilterChain,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Resources {
|
pub struct Resources {
|
||||||
|
@ -259,18 +261,24 @@ pub mod d3d11_hello_triangle {
|
||||||
pub backbuffer: ID3D11Texture2D,
|
pub backbuffer: ID3D11Texture2D,
|
||||||
pub rtv: ID3D11RenderTargetView,
|
pub rtv: ID3D11RenderTargetView,
|
||||||
pub viewport: D3D11_VIEWPORT,
|
pub viewport: D3D11_VIEWPORT,
|
||||||
|
pub shader_output: Option<ID3D11Texture2D>
|
||||||
}
|
}
|
||||||
impl DXSample for Sample {
|
|
||||||
fn new() -> Result<Self> {
|
|
||||||
let (dxgi_factory, device, context) = create_device()?;
|
|
||||||
|
|
||||||
|
impl Sample {
|
||||||
|
pub(crate) fn new(filter: impl AsRef<Path>) -> Result<Self> {
|
||||||
|
let (dxgi_factory, device, context) = create_device()?;
|
||||||
|
let filter = FilterChain::load_from_path(&device, filter).unwrap();
|
||||||
Ok(Sample {
|
Ok(Sample {
|
||||||
|
filter,
|
||||||
dxgi_factory,
|
dxgi_factory,
|
||||||
device,
|
device,
|
||||||
context,
|
context,
|
||||||
resources: None,
|
resources: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
impl DXSample for Sample {
|
||||||
|
|
||||||
|
|
||||||
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()> {
|
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()> {
|
||||||
let swapchain = create_swapchain(&self.dxgi_factory, &self.device, *hwnd)?;
|
let swapchain = create_swapchain(&self.dxgi_factory, &self.device, *hwnd)?;
|
||||||
|
@ -308,6 +316,7 @@ pub mod d3d11_hello_triangle {
|
||||||
self.context.RSSetState(&raster_state);
|
self.context.RSSetState(&raster_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
self.resources = Some(Resources {
|
self.resources = Some(Resources {
|
||||||
swapchain,
|
swapchain,
|
||||||
rtv,
|
rtv,
|
||||||
|
@ -332,6 +341,7 @@ pub mod d3d11_hello_triangle {
|
||||||
MinDepth: D3D11_MIN_DEPTH,
|
MinDepth: D3D11_MIN_DEPTH,
|
||||||
MaxDepth: D3D11_MAX_DEPTH,
|
MaxDepth: D3D11_MAX_DEPTH,
|
||||||
},
|
},
|
||||||
|
shader_output: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -422,6 +432,64 @@ pub mod d3d11_hello_triangle {
|
||||||
self.context.DrawIndexed(3, 0, 0);
|
self.context.DrawIndexed(3, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut tex2d_desc = Default::default();
|
||||||
|
resources.backbuffer.GetDesc(&mut tex2d_desc);
|
||||||
|
let backup = self.device.CreateTexture2D(&D3D11_TEXTURE2D_DESC {
|
||||||
|
BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
|
||||||
|
CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
|
||||||
|
..tex2d_desc
|
||||||
|
}, None)?;
|
||||||
|
|
||||||
|
self.context.CopyResource(&backup, &resources.backbuffer);
|
||||||
|
|
||||||
|
let srv = self.device.CreateShaderResourceView(&backup, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
||||||
|
Format: tex2d_desc.Format,
|
||||||
|
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
||||||
|
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
||||||
|
Texture2D: D3D11_TEX2D_SRV {
|
||||||
|
MostDetailedMip: 0,
|
||||||
|
MipLevels: u32::MAX,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}))?;
|
||||||
|
|
||||||
|
let shader_out = self.device.CreateTexture2D(&tex2d_desc, None)?;
|
||||||
|
|
||||||
|
let rtv = self.device.CreateRenderTargetView(&shader_out, Some(&D3D11_RENDER_TARGET_VIEW_DESC {
|
||||||
|
Format: tex2d_desc.Format,
|
||||||
|
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||||
|
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
|
||||||
|
Texture2D: D3D11_TEX2D_RTV {
|
||||||
|
MipSlice: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))?;
|
||||||
|
|
||||||
|
//
|
||||||
|
self.filter.frame(1, &Size {
|
||||||
|
width: tex2d_desc.Width,
|
||||||
|
height: tex2d_desc.Height,
|
||||||
|
}, DxImageView { handle: srv, size: Size {
|
||||||
|
width: tex2d_desc.Width,
|
||||||
|
height: tex2d_desc.Height,
|
||||||
|
} }, OutputFramebuffer {
|
||||||
|
rtv,
|
||||||
|
size: Size {
|
||||||
|
width: tex2d_desc.Width,
|
||||||
|
height: tex2d_desc.Height,
|
||||||
|
},
|
||||||
|
viewport: D3D11_VIEWPORT {
|
||||||
|
TopLeftX: 0.0,
|
||||||
|
TopLeftY: 0.0,
|
||||||
|
Width: tex2d_desc.Width as f32,
|
||||||
|
Height: tex2d_desc.Height as f32,
|
||||||
|
MinDepth: 0.0,
|
||||||
|
MaxDepth: 1.0,
|
||||||
|
},
|
||||||
|
}).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
resources.swapchain.Present(0, 0).ok()?;
|
resources.swapchain.Present(0, 0).ok()?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ mod util;
|
||||||
mod samplers;
|
mod samplers;
|
||||||
mod render_target;
|
mod render_target;
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
|
mod quad_render;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -33,10 +34,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn triangle_d3d11() {
|
fn triangle_d3d11() {
|
||||||
let sample = hello_triangle::d3d11_hello_triangle::Sample::new().unwrap();
|
let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/crt/crt-royale.slangp").unwrap();
|
||||||
let device = sample.device.clone();
|
|
||||||
let chain = filter_chain::FilterChain::load_from_path(&device, "../test/slang-shaders/crt/crt-royale.slangp").unwrap();
|
|
||||||
std::mem::forget(chain);
|
|
||||||
hello_triangle::main(sample).unwrap();
|
hello_triangle::main(sample).unwrap();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
use bytemuck::offset_of;
|
||||||
|
use windows::core::PCSTR;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_VERTEX_BUFFER, D3D11_BUFFER_DESC, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_SUBRESOURCE_DATA, D3D11_USAGE_IMMUTABLE, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext};
|
||||||
|
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||||
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
||||||
|
use crate::util;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
|
struct D3D11Vertex {
|
||||||
|
position: [f32; 2],
|
||||||
|
texcoord: [f32; 2],
|
||||||
|
color: [f32; 4]
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLEAR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
|
||||||
|
|
||||||
|
static QUAD_VBO_DATA: &'static [D3D11Vertex; 4] = &[
|
||||||
|
D3D11Vertex {
|
||||||
|
position: [0.0, 0.0],
|
||||||
|
texcoord: [0.0, 1.0],
|
||||||
|
color: CLEAR,
|
||||||
|
},
|
||||||
|
|
||||||
|
D3D11Vertex {
|
||||||
|
position: [0.0, 1.0],
|
||||||
|
texcoord: [0.0, 0.0],
|
||||||
|
color: CLEAR,
|
||||||
|
},
|
||||||
|
|
||||||
|
D3D11Vertex {
|
||||||
|
position: [1.0, 0.0],
|
||||||
|
texcoord: [1.0, 1.0],
|
||||||
|
color: CLEAR,
|
||||||
|
},
|
||||||
|
|
||||||
|
D3D11Vertex {
|
||||||
|
position: [1.0, 1.0],
|
||||||
|
texcoord: [1.0, 0.0],
|
||||||
|
color: CLEAR,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub(crate) struct DrawQuad {
|
||||||
|
buffer: ID3D11Buffer,
|
||||||
|
context: ID3D11DeviceContext,
|
||||||
|
offset: u32,
|
||||||
|
stride: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DrawQuad {
|
||||||
|
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> util::Result<DrawQuad> {
|
||||||
|
unsafe {
|
||||||
|
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
||||||
|
ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32,
|
||||||
|
Usage: D3D11_USAGE_IMMUTABLE,
|
||||||
|
BindFlags: D3D11_BIND_VERTEX_BUFFER,
|
||||||
|
CPUAccessFlags: Default::default(),
|
||||||
|
MiscFlags: Default::default(),
|
||||||
|
StructureByteStride: 0,
|
||||||
|
}, Some(&D3D11_SUBRESOURCE_DATA {
|
||||||
|
pSysMem: QUAD_VBO_DATA.as_ptr().cast(),
|
||||||
|
SysMemPitch: 0,
|
||||||
|
SysMemSlicePitch: 0,
|
||||||
|
}))?;
|
||||||
|
|
||||||
|
Ok(DrawQuad {
|
||||||
|
buffer,
|
||||||
|
context: context.clone(),
|
||||||
|
offset: 0,
|
||||||
|
stride: std::mem::size_of::<D3D11Vertex>() as u32
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_vertices(&self) {
|
||||||
|
unsafe {
|
||||||
|
self.context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
|
self.context.IASetVertexBuffers(0, 1, Some(&Some(self.buffer.clone())),
|
||||||
|
Some(&self.stride), Some(&self.offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
pub fn get_spirv_cross_vbo_desc() -> [D3D11_INPUT_ELEMENT_DESC; 2] {
|
||||||
|
[
|
||||||
|
D3D11_INPUT_ELEMENT_DESC {
|
||||||
|
SemanticName: PCSTR(b"TEXCOORD\0".as_ptr()),
|
||||||
|
SemanticIndex: 0,
|
||||||
|
Format: DXGI_FORMAT_R32G32_FLOAT,
|
||||||
|
InputSlot: 0,
|
||||||
|
AlignedByteOffset: offset_of!(D3D11Vertex, position) as u32,
|
||||||
|
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
||||||
|
InstanceDataStepRate: 0,
|
||||||
|
},
|
||||||
|
D3D11_INPUT_ELEMENT_DESC {
|
||||||
|
SemanticName: PCSTR(b"TEXCOORD\0".as_ptr()),
|
||||||
|
SemanticIndex: 1,
|
||||||
|
Format: DXGI_FORMAT_R32G32_FLOAT,
|
||||||
|
InputSlot: 0,
|
||||||
|
AlignedByteOffset: offset_of!(D3D11Vertex, texcoord) as u32,
|
||||||
|
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
||||||
|
InstanceDataStepRate: 0,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,9 +7,13 @@ use crate::util::d3d11_get_closest_format;
|
||||||
use crate::util::Result;
|
use crate::util::Result;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Texture {
|
pub struct DxImageView {
|
||||||
pub handle: ID3D11ShaderResourceView,
|
pub handle: ID3D11ShaderResourceView,
|
||||||
pub size: Size<u32>, // pub image: GlImage,
|
pub size: Size<u32>, // pub image: GlImage,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Texture {
|
||||||
|
pub view: DxImageView,
|
||||||
pub filter: FilterMode,
|
pub filter: FilterMode,
|
||||||
pub wrap_mode: WrapMode,
|
pub wrap_mode: WrapMode,
|
||||||
// pub mip_filter: FilterMode,
|
// pub mip_filter: FilterMode,
|
||||||
|
@ -135,8 +139,10 @@ impl OwnedTexture {
|
||||||
// staging,
|
// staging,
|
||||||
desc,
|
desc,
|
||||||
image: Texture {
|
image: Texture {
|
||||||
handle: srv,
|
view: DxImageView {
|
||||||
size: source.size,
|
handle: srv,
|
||||||
|
size: source.size,
|
||||||
|
},
|
||||||
filter,
|
filter,
|
||||||
wrap_mode
|
wrap_mode
|
||||||
}
|
}
|
||||||
|
|
|
@ -666,6 +666,7 @@ impl FilterChain {
|
||||||
} else {
|
} else {
|
||||||
count
|
count
|
||||||
} as u32,
|
} as u32,
|
||||||
|
// todo: put this in options
|
||||||
1,
|
1,
|
||||||
viewport,
|
viewport,
|
||||||
&original,
|
&original,
|
||||||
|
|
Loading…
Add table
Reference in a new issue