d3d11: implement history
This commit is contained in:
parent
a091cff6ae
commit
7acf208f39
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -418,7 +418,6 @@ dependencies = [
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
"librashader-runtime-d3d11",
|
"librashader-runtime-d3d11",
|
||||||
"librashader-runtime-gl",
|
"librashader-runtime-gl",
|
||||||
"librashader-runtime-gl46",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -512,23 +511,6 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "librashader-runtime-gl46"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
"gl",
|
|
||||||
"glfw",
|
|
||||||
"librashader-common",
|
|
||||||
"librashader-preprocess",
|
|
||||||
"librashader-presets",
|
|
||||||
"librashader-reflect",
|
|
||||||
"librashader-runtime",
|
|
||||||
"rustc-hash",
|
|
||||||
"spirv_cross",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
|
|
@ -8,5 +8,4 @@ members = [
|
||||||
"librashader-runtime",
|
"librashader-runtime",
|
||||||
"librashader-runtime-d3d11",
|
"librashader-runtime-d3d11",
|
||||||
"librashader-runtime-gl",
|
"librashader-runtime-gl",
|
||||||
"librashader-runtime-gl46",
|
|
||||||
]
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{FilterMode, ImageFormat, WrapMode};
|
use crate::{FilterMode, ImageFormat, WrapMode};
|
||||||
use windows::Win32::Graphics::Direct3D11;
|
use windows::Win32::Graphics::Direct3D11;
|
||||||
use windows::Win32::Graphics::Dxgi::Common as dxgi;
|
use windows::Win32::Graphics::Dxgi::Common as dxgi;
|
||||||
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
|
||||||
|
|
||||||
impl From<ImageFormat> for dxgi::DXGI_FORMAT {
|
impl From<ImageFormat> for dxgi::DXGI_FORMAT {
|
||||||
fn from(format: ImageFormat) -> Self {
|
fn from(format: ImageFormat) -> Self {
|
||||||
|
@ -40,6 +41,45 @@ impl From<ImageFormat> for dxgi::DXGI_FORMAT {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<DXGI_FORMAT> for ImageFormat {
|
||||||
|
fn from(format: DXGI_FORMAT) -> Self {
|
||||||
|
match format {
|
||||||
|
dxgi::DXGI_FORMAT_UNKNOWN => ImageFormat::Unknown,
|
||||||
|
dxgi::DXGI_FORMAT_R8_UNORM => ImageFormat::R8Unorm,
|
||||||
|
dxgi::DXGI_FORMAT_R8_UINT => ImageFormat::R8Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R8_SINT => ImageFormat::R8Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R8G8_UNORM => ImageFormat::R8G8Unorm,
|
||||||
|
dxgi::DXGI_FORMAT_R8G8_UINT => ImageFormat::R8G8Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R8G8_SINT => ImageFormat::R8G8Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R8G8B8A8_UNORM => ImageFormat::R8G8B8A8Unorm,
|
||||||
|
dxgi::DXGI_FORMAT_R8G8B8A8_UINT => ImageFormat::R8G8B8A8Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R8G8B8A8_SINT => ImageFormat::R8G8B8A8Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB => ImageFormat::R8G8B8A8Srgb,
|
||||||
|
dxgi::DXGI_FORMAT_R10G10B10A2_UNORM => ImageFormat::A2B10G10R10UnormPack32,
|
||||||
|
dxgi::DXGI_FORMAT_R10G10B10A2_UINT => ImageFormat::A2B10G10R10UintPack32,
|
||||||
|
dxgi::DXGI_FORMAT_R16_UINT => ImageFormat::R16Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R16_SINT => ImageFormat::R16Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R16_FLOAT => ImageFormat::R16Sfloat,
|
||||||
|
dxgi::DXGI_FORMAT_R16G16_UINT => ImageFormat::R16G16Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R16G16_SINT => ImageFormat::R16G16Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R16G16_FLOAT => ImageFormat::R16G16Sfloat,
|
||||||
|
dxgi::DXGI_FORMAT_R16G16B16A16_UINT => ImageFormat::R16G16B16A16Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R16G16B16A16_SINT => ImageFormat::R16G16B16A16Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R16G16B16A16_FLOAT => ImageFormat::R16G16B16A16Sfloat,
|
||||||
|
dxgi::DXGI_FORMAT_R32_UINT => ImageFormat::R32Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R32_SINT => ImageFormat::R32Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R32_FLOAT => ImageFormat::R32Sfloat,
|
||||||
|
dxgi::DXGI_FORMAT_R32G32_UINT => ImageFormat::R32G32Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R32G32_SINT => ImageFormat::R32G32Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R32G32_FLOAT => ImageFormat::R32G32Sfloat,
|
||||||
|
dxgi::DXGI_FORMAT_R32G32B32A32_UINT => ImageFormat::R32G32B32A32Uint,
|
||||||
|
dxgi::DXGI_FORMAT_R32G32B32A32_SINT => ImageFormat::R32G32B32A32Sint,
|
||||||
|
dxgi::DXGI_FORMAT_R32G32B32A32_FLOAT => ImageFormat::R32G32B32A32Sfloat,
|
||||||
|
_ => ImageFormat::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<WrapMode> for Direct3D11::D3D11_TEXTURE_ADDRESS_MODE {
|
impl From<WrapMode> for Direct3D11::D3D11_TEXTURE_ADDRESS_MODE {
|
||||||
fn from(value: WrapMode) -> Self {
|
fn from(value: WrapMode) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
use crate::texture::{DxImageView, OwnedTexture, Texture};
|
use crate::texture::{DxImageView, OwnedTexture, Texture};
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::cross::GlslangHlslContext;
|
use librashader_reflect::back::cross::GlslangHlslContext;
|
||||||
|
@ -16,7 +17,7 @@ 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, ID3D11RenderTargetView, ID3D11ShaderResourceView};
|
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, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
||||||
use crate::framebuffer::{OutputFramebuffer, OwnedFramebuffer};
|
use crate::framebuffer::{OutputFramebuffer, OwnedFramebuffer};
|
||||||
|
@ -39,6 +40,9 @@ pub struct FilterChain {
|
||||||
pub common: FilterCommon,
|
pub common: FilterCommon,
|
||||||
pub passes: Vec<FilterPass>,
|
pub passes: Vec<FilterPass>,
|
||||||
pub output_framebuffers: Box<[OwnedFramebuffer]>,
|
pub output_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
|
pub feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
|
pub history_framebuffers: VecDeque<OwnedFramebuffer>,
|
||||||
|
pub(crate) draw_quad: DrawQuad,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Direct3D11 {
|
pub struct Direct3D11 {
|
||||||
|
@ -51,8 +55,9 @@ 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,
|
pub output_textures: Box<[Option<Texture>]>,
|
||||||
pub output_textures: Box<[Option<Texture>]>
|
pub feedback_textures: Box<[Option<Texture>]>,
|
||||||
|
pub history_textures: Box<[Option<Texture>]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterChain {
|
impl FilterChain {
|
||||||
|
@ -187,46 +192,42 @@ impl FilterChain {
|
||||||
// initialize passes
|
// initialize passes
|
||||||
let filters = FilterChain::init_passes(device, passes, &semantics).unwrap();
|
let filters = FilterChain::init_passes(device, passes, &semantics).unwrap();
|
||||||
|
|
||||||
let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default();
|
let mut device_context = None;
|
||||||
let default_wrap = filters
|
unsafe {
|
||||||
.first()
|
device.GetImmediateContext(&mut device_context);
|
||||||
.map(|f| f.config.wrap_mode)
|
}
|
||||||
.unwrap_or_default();
|
let device_context = device_context.unwrap();
|
||||||
|
|
||||||
// initialize output framebuffers
|
// initialize output framebuffers
|
||||||
let mut output_framebuffers = Vec::new();
|
let mut output_framebuffers = Vec::new();
|
||||||
output_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, Size::new(1, 1),
|
output_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
|
||||||
ImageFormat::R8G8B8A8Unorm).unwrap());
|
ImageFormat::R8G8B8A8Unorm).unwrap());
|
||||||
let mut output_textures = Vec::new();
|
let mut output_textures = Vec::new();
|
||||||
output_textures.resize_with(filters.len(), || None);
|
output_textures.resize_with(filters.len(), || None);
|
||||||
//
|
//
|
||||||
// // initialize feedback framebuffers
|
// // initialize feedback framebuffers
|
||||||
// let mut feedback_framebuffers = Vec::new();
|
let mut feedback_framebuffers = Vec::new();
|
||||||
// feedback_framebuffers.resize_with(filters.len(), || Framebuffer::new(1));
|
feedback_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
|
||||||
// let mut feedback_textures = Vec::new();
|
ImageFormat::R8G8B8A8Unorm).unwrap());
|
||||||
// feedback_textures.resize_with(filters.len(), Texture::default);
|
let mut feedback_textures = Vec::new();
|
||||||
|
feedback_textures.resize_with(filters.len(), || None);
|
||||||
|
|
||||||
// load luts
|
// load luts
|
||||||
let luts = FilterChain::load_luts(device, &preset.textures)?;
|
let luts = FilterChain::load_luts(device, &preset.textures)?;
|
||||||
|
|
||||||
// let (history_framebuffers, history_textures) =
|
let (history_framebuffers, history_textures) =
|
||||||
// FilterChain::init_history(&filters, default_filter, default_wrap);
|
FilterChain::init_history(device, &device_context, &filters);
|
||||||
|
|
||||||
let mut device_context = None;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
device.GetImmediateContext(&mut device_context);
|
|
||||||
}
|
|
||||||
let device_context = device_context.unwrap();
|
|
||||||
let draw_quad = DrawQuad::new(device, &device_context)?;
|
let draw_quad = DrawQuad::new(device, &device_context)?;
|
||||||
|
|
||||||
// todo: make vbo: d3d11.c 1376
|
// todo: make vbo: d3d11.c 1376
|
||||||
Ok(FilterChain {
|
Ok(FilterChain {
|
||||||
passes: filters,
|
passes: filters,
|
||||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||||
// feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||||
// history_framebuffers,
|
history_framebuffers,
|
||||||
// filter_vao,
|
draw_quad,
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
d3d11: Direct3D11 {
|
d3d11: Direct3D11 {
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
|
@ -238,13 +239,90 @@ impl FilterChain {
|
||||||
// semantics,
|
// semantics,
|
||||||
preset,
|
preset,
|
||||||
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,
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn init_history(
|
||||||
|
device: &ID3D11Device,
|
||||||
|
context: &ID3D11DeviceContext,
|
||||||
|
filters: &[FilterPass],
|
||||||
|
) -> (VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>) {
|
||||||
|
let mut required_images = 0;
|
||||||
|
|
||||||
|
for pass in filters {
|
||||||
|
// If a shader uses history size, but not history, we still need to keep the texture.
|
||||||
|
let texture_count = pass
|
||||||
|
.reflection
|
||||||
|
.meta
|
||||||
|
.texture_meta
|
||||||
|
.iter()
|
||||||
|
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||||
|
.count();
|
||||||
|
let texture_size_count = pass
|
||||||
|
.reflection
|
||||||
|
.meta
|
||||||
|
.texture_size_meta
|
||||||
|
.iter()
|
||||||
|
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
required_images = std::cmp::max(required_images, texture_count);
|
||||||
|
required_images = std::cmp::max(required_images, texture_size_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// not using frame history;
|
||||||
|
if required_images <= 1 {
|
||||||
|
println!("[history] not using frame history");
|
||||||
|
return (VecDeque::new(), Box::new([]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// history0 is aliased with the original
|
||||||
|
|
||||||
|
eprintln!("[history] using frame history with {required_images} images");
|
||||||
|
let mut framebuffers = VecDeque::with_capacity(required_images);
|
||||||
|
framebuffers.resize_with(required_images, || OwnedFramebuffer::new(device, &context, Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm).unwrap());
|
||||||
|
|
||||||
|
let mut history_textures = Vec::new();
|
||||||
|
history_textures.resize_with(required_images, || None);
|
||||||
|
|
||||||
|
(framebuffers, history_textures.into_boxed_slice())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_history(&mut self, input: &DxImageView) -> util::Result<()> {
|
||||||
|
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
||||||
|
let resource = unsafe {
|
||||||
|
let mut resource = None;
|
||||||
|
input.handle.GetResource(&mut resource);
|
||||||
|
|
||||||
|
// todo: make panic-free
|
||||||
|
resource.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let format = unsafe {
|
||||||
|
let mut desc = Default::default();
|
||||||
|
input.handle.GetDesc(&mut desc);
|
||||||
|
desc.Format
|
||||||
|
};
|
||||||
|
|
||||||
|
if back.size != input.size || (format != DXGI_FORMAT(0) && format != back.format) {
|
||||||
|
eprintln!("[history] resizing");
|
||||||
|
back.init(input.size, ImageFormat::from(format))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
back.copy_from(&resource)?;
|
||||||
|
|
||||||
|
self.history_framebuffers.push_front(back)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureConfig],
|
||||||
|
@ -339,10 +417,10 @@ impl FilterChain {
|
||||||
let filter = passes[0].config.filter;
|
let filter = passes[0].config.filter;
|
||||||
let wrap_mode = passes[0].config.wrap_mode;
|
let wrap_mode = passes[0].config.wrap_mode;
|
||||||
|
|
||||||
self.common.draw_quad.bind_vertices();
|
self.draw_quad.bind_vertices();
|
||||||
|
|
||||||
let original = Texture {
|
let original = Texture {
|
||||||
view: input,
|
view: input.clone(),
|
||||||
filter,
|
filter,
|
||||||
wrap_mode,
|
wrap_mode,
|
||||||
};
|
};
|
||||||
|
@ -358,11 +436,21 @@ impl FilterChain {
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
self.feedback_framebuffers[index].scale(
|
||||||
|
pass.config.scaling.clone(),
|
||||||
|
pass.get_format(),
|
||||||
|
viewport,
|
||||||
|
&original,
|
||||||
|
&source,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let passes_len = passes.len();
|
||||||
|
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
||||||
|
|
||||||
|
|
||||||
for (index, pass) in passes.iter_mut().enumerate() {
|
for (index, pass) in pass.iter_mut().enumerate() {
|
||||||
let target = &self.output_framebuffers[index];
|
let target = &self.output_framebuffers[index];
|
||||||
let size = target.size;
|
let size = target.size;
|
||||||
|
|
||||||
|
@ -380,6 +468,33 @@ impl FilterChain {
|
||||||
self.common.output_textures[index] = Some(source.clone());
|
self.common.output_textures[index] = Some(source.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_eq!(last.len(), 1);
|
||||||
|
for pass in last {
|
||||||
|
source.filter = pass.config.filter;
|
||||||
|
pass.draw(
|
||||||
|
passes_len - 1,
|
||||||
|
&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, None))?;
|
||||||
|
|
||||||
|
// diverge so we don't need to clone output.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// swap feedback framebuffers with output
|
||||||
|
for (output, feedback) in self
|
||||||
|
.output_framebuffers
|
||||||
|
.iter_mut()
|
||||||
|
.zip(self.feedback_framebuffers.iter_mut())
|
||||||
|
{
|
||||||
|
std::mem::swap(output, feedback);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.push_history(&input)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::array;
|
||||||
use crate::filter_chain::FilterCommon;
|
use crate::filter_chain::FilterCommon;
|
||||||
use crate::texture::{Texture, OwnedTexture};
|
use crate::texture::{Texture, OwnedTexture};
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{ImageFormat, Size};
|
||||||
|
@ -12,6 +13,7 @@ use std::error::Error;
|
||||||
use windows::core::ConstBuffer;
|
use windows::core::ConstBuffer;
|
||||||
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
||||||
use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout};
|
use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout};
|
||||||
|
use windows::Win32::Graphics::Gdi::NULL_PEN;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
|
@ -39,6 +41,11 @@ pub struct FilterPass {
|
||||||
pub source: ShaderSource,
|
pub source: ShaderSource,
|
||||||
pub config: ShaderPassConfig,
|
pub config: ShaderPassConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://doc.rust-lang.org/nightly/core/array/fn.from_fn.html is not ~const :(
|
||||||
|
const NULL_TEXTURES: &[Option<ID3D11ShaderResourceView>; 16] =
|
||||||
|
&[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None];
|
||||||
|
|
||||||
// slang_process.cpp 229
|
// slang_process.cpp 229
|
||||||
impl FilterPass {
|
impl FilterPass {
|
||||||
pub fn get_format(&self) -> ImageFormat {
|
pub fn get_format(&self) -> ImageFormat {
|
||||||
|
@ -215,33 +222,26 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PassFeedback
|
// PassFeedback
|
||||||
// for (index, feedback) in parent.feedback_textures.iter().enumerate() {
|
for (index, feedback) in parent.feedback_textures.iter().enumerate() {
|
||||||
// // if let Some(binding) = self
|
let Some(feedback) = feedback else {
|
||||||
// // .reflection
|
continue;
|
||||||
// // .meta
|
};
|
||||||
// // .texture_meta
|
if let Some(binding) = self
|
||||||
// // .get(&TextureSemantics::PassFeedback.semantics(index))
|
.reflection
|
||||||
// // {
|
.meta
|
||||||
// // if feedback.image.handle == 0 {
|
.texture_meta
|
||||||
// // eprintln!("[WARNING] trying to bind PassFeedback: {index} which has texture 0 to slot {} in pass {pass_index}", binding.binding)
|
.get(&TextureSemantics::PassFeedback.semantics(index))
|
||||||
// // }
|
{
|
||||||
// // FilterPass::bind_texture(binding, feedback);
|
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, feedback);
|
||||||
// // }
|
}
|
||||||
//
|
|
||||||
// if let Some(offset) = self
|
if let Some(offset) = self
|
||||||
// .uniform_bindings
|
.uniform_bindings
|
||||||
// .get(&TextureSemantics::PassFeedback.semantics(index).into())
|
.get(&TextureSemantics::PassFeedback.semantics(index).into())
|
||||||
// {
|
{
|
||||||
// let (buffer, offset) = match offset {
|
self.uniform_storage.bind_vec4(*offset, feedback.view.size, None);
|
||||||
// MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
}
|
||||||
// MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset),
|
}
|
||||||
// };
|
|
||||||
// FilterPass::build_uniform(
|
|
||||||
// &mut buffer[offset..][..16],
|
|
||||||
// feedback.image.size,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bind float parameters
|
// bind float parameters
|
||||||
for (id, offset) in
|
for (id, offset) in
|
||||||
|
@ -381,7 +381,7 @@ impl FilterPass {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// unbind resources.
|
// unbind resources.
|
||||||
context.PSSetShaderResources(0, Some(&[None; 16]));
|
context.PSSetShaderResources(0, Some(NULL_TEXTURES));
|
||||||
context.OMSetRenderTargets(None, None);
|
context.OMSetRenderTargets(None, None);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE, D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RENDER_TARGET_VIEW_DESC, D3D11_RENDER_TARGET_VIEW_DESC_0, D3D11_RTV_DIMENSION_TEXTURE2D, D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_RTV, D3D11_TEX2D_SRV, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, D3D11_VIEWPORT, ID3D11Device, ID3D11RenderTargetView, ID3D11ShaderResourceView, ID3D11Texture2D};
|
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE, D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RENDER_TARGET_VIEW_DESC, D3D11_RENDER_TARGET_VIEW_DESC_0, D3D11_RTV_DIMENSION_TEXTURE2D, D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_RTV, D3D11_TEX2D_SRV, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, D3D11_VIEWPORT, ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11Resource, ID3D11ShaderResourceView, ID3D11Texture2D};
|
||||||
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
||||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
|
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_presets::{Scale2D, ScaleType, Scaling};
|
use librashader_presets::{Scale2D, ScaleType, Scaling};
|
||||||
use crate::texture::Texture;
|
use crate::texture::{DxImageView, Texture};
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::d3d11_get_closest_format;
|
use crate::util::d3d11_get_closest_format;
|
||||||
|
|
||||||
|
@ -13,11 +13,12 @@ pub struct OwnedFramebuffer {
|
||||||
pub size: Size<u32>,
|
pub size: Size<u32>,
|
||||||
pub format: DXGI_FORMAT,
|
pub format: DXGI_FORMAT,
|
||||||
device: ID3D11Device,
|
device: ID3D11Device,
|
||||||
|
context: ID3D11DeviceContext,
|
||||||
is_raw: bool
|
is_raw: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedFramebuffer {
|
impl OwnedFramebuffer {
|
||||||
pub fn new(device: &ID3D11Device, size: Size<u32>, format: ImageFormat) -> util::Result<OwnedFramebuffer> {
|
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext, size: Size<u32>, format: ImageFormat) -> util::Result<OwnedFramebuffer> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let format = d3d11_get_closest_format(device, DXGI_FORMAT::from(format),
|
let format = d3d11_get_closest_format(device, DXGI_FORMAT::from(format),
|
||||||
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0);
|
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0);
|
||||||
|
@ -30,6 +31,7 @@ impl OwnedFramebuffer {
|
||||||
size,
|
size,
|
||||||
format,
|
format,
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
|
context: context.clone(),
|
||||||
is_raw: false,
|
is_raw: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -120,6 +122,22 @@ impl OwnedFramebuffer {
|
||||||
viewport: default_viewport(self.size)
|
viewport: default_viewport(self.size)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copy_from(&self, image: &ID3D11Resource) -> util::Result<()> {
|
||||||
|
unsafe {
|
||||||
|
|
||||||
|
self.context.CopySubresourceRegion(&self.texture, 0, 0, 0, 0,
|
||||||
|
image, 0, Some(&D3D11_BOX {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
front: 0,
|
||||||
|
right: self.size.width,
|
||||||
|
bottom: self.size.height,
|
||||||
|
back: 1,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OutputFramebuffer {
|
pub struct OutputFramebuffer {
|
||||||
|
|
|
@ -261,7 +261,8 @@ 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>
|
pub shader_output: Option<ID3D11Texture2D>,
|
||||||
|
pub frame_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sample {
|
impl Sample {
|
||||||
|
@ -342,6 +343,7 @@ pub mod d3d11_hello_triangle {
|
||||||
MaxDepth: D3D11_MAX_DEPTH,
|
MaxDepth: D3D11_MAX_DEPTH,
|
||||||
},
|
},
|
||||||
shader_output: None,
|
shader_output: None,
|
||||||
|
frame_count: 0usize
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -467,7 +469,7 @@ pub mod d3d11_hello_triangle {
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
//
|
//
|
||||||
self.filter.frame(1, &Size {
|
self.filter.frame(resources.frame_count, &Size {
|
||||||
width: tex2d_desc.Width,
|
width: tex2d_desc.Width,
|
||||||
height: tex2d_desc.Height,
|
height: tex2d_desc.Height,
|
||||||
}, DxImageView { handle: srv, size: Size {
|
}, DxImageView { handle: srv, size: Size {
|
||||||
|
@ -480,14 +482,15 @@ pub mod d3d11_hello_triangle {
|
||||||
width: tex2d_desc.Width,
|
width: tex2d_desc.Width,
|
||||||
height: tex2d_desc.Height,
|
height: tex2d_desc.Height,
|
||||||
},
|
},
|
||||||
viewport: D3D11_VIEWPORT {
|
viewport: resources.viewport
|
||||||
TopLeftX: 0.0,
|
// viewport: D3D11_VIEWPORT {
|
||||||
TopLeftY: 0.0,
|
// TopLeftX: 0.0,
|
||||||
Width: tex2d_desc.Width as f32,
|
// TopLeftY: 0.0,
|
||||||
Height: tex2d_desc.Height as f32,
|
// Width: tex2d_desc.Width as f32,
|
||||||
MinDepth: 0.0,
|
// Height: tex2d_desc.Height as f32,
|
||||||
MaxDepth: 1.0,
|
// MinDepth: 0.0,
|
||||||
},
|
// MaxDepth: 1.0,
|
||||||
|
// },
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
// self.context.CopyResource(&resources.backbuffer, &backup);
|
// self.context.CopyResource(&resources.backbuffer, &backup);
|
||||||
|
@ -496,6 +499,7 @@ pub mod d3d11_hello_triangle {
|
||||||
unsafe {
|
unsafe {
|
||||||
resources.swapchain.Present(0, 0).ok()?;
|
resources.swapchain.Present(0, 0).ok()?;
|
||||||
}
|
}
|
||||||
|
resources.frame_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn triangle_d3d11() {
|
fn triangle_d3d11() {
|
||||||
let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/crt/crt-royale.slangp").unwrap();
|
// let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/crt/crt-royale.slangp").unwrap();
|
||||||
|
let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp").unwrap();
|
||||||
|
|
||||||
// let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap();
|
// let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap();
|
||||||
|
|
||||||
hello_triangle::main(sample).unwrap();
|
hello_triangle::main(sample).unwrap();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use bytemuck::offset_of;
|
use bytemuck::offset_of;
|
||||||
use windows::core::PCSTR;
|
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::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::Direct3D::{D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ impl DrawQuad {
|
||||||
self.context.IASetVertexBuffers(0, 1, Some(&Some(self.buffer.clone())),
|
self.context.IASetVertexBuffers(0, 1, Some(&Some(self.buffer.clone())),
|
||||||
Some(&self.stride), Some(&self.offset));
|
Some(&self.stride), Some(&self.offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_spirv_cross_vbo_desc() -> [D3D11_INPUT_ELEMENT_DESC; 2] {
|
pub fn get_spirv_cross_vbo_desc() -> [D3D11_INPUT_ELEMENT_DESC; 2] {
|
||||||
[
|
[
|
||||||
D3D11_INPUT_ELEMENT_DESC {
|
D3D11_INPUT_ELEMENT_DESC {
|
||||||
|
|
|
@ -11,7 +11,6 @@ librashader-preprocess = { path = "../librashader-preprocess" }
|
||||||
librashader-reflect = { path = "../librashader-reflect" }
|
librashader-reflect = { path = "../librashader-reflect" }
|
||||||
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11" }
|
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11" }
|
||||||
librashader-runtime-gl = { path = "../librashader-runtime-gl" }
|
librashader-runtime-gl = { path = "../librashader-runtime-gl" }
|
||||||
librashader-runtime-gl46 = { path = "../librashader-runtime-gl46" }
|
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
Loading…
Reference in a new issue