d3d11: cleanup error and api
This commit is contained in:
parent
6519a78df2
commit
873814b03b
15 changed files with 316 additions and 240 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@
|
||||||
/target
|
/target
|
||||||
*.rdc
|
*.rdc
|
||||||
*.cap
|
*.cap
|
||||||
|
/.vs/
|
||||||
|
|
|
@ -84,8 +84,6 @@ fn from_int(input: Span) -> Result<i32, ParsePresetError> {
|
||||||
col: input.get_column(),
|
col: input.get_column(),
|
||||||
kind: ParseErrorKind::Int,
|
kind: ParseErrorKind::Int,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
eprintln!("falling back to float trunc {result}");
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,3 +23,5 @@ pub enum FilterChainError {
|
||||||
#[error("lut loading error")]
|
#[error("lut loading error")]
|
||||||
LutLoadError(#[from] ImageError),
|
LutLoadError(#[from] ImageError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = std::result::Result<T, FilterChainError>;
|
||||||
|
|
|
@ -14,24 +14,26 @@ use librashader_reflect::reflect::semantics::{
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::error::Error;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::error::FilterChainError;
|
||||||
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
||||||
use crate::framebuffer::{OutputFramebuffer, OwnedFramebuffer};
|
use crate::framebuffer::OwnedFramebuffer;
|
||||||
|
use crate::options::{FilterChainOptions, FrameOptions};
|
||||||
use crate::quad_render::DrawQuad;
|
use crate::quad_render::DrawQuad;
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::util;
|
|
||||||
use crate::util::d3d11_compile_bound_shader;
|
use crate::util::d3d11_compile_bound_shader;
|
||||||
|
use crate::viewport::Viewport;
|
||||||
|
use crate::{error, util};
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use windows::Win32::Graphics::Direct3D11::{
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC,
|
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC,
|
||||||
D3D11_CPU_ACCESS_WRITE, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS,
|
D3D11_CPU_ACCESS_WRITE, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS,
|
||||||
D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC,
|
D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC,
|
||||||
};
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_R8G8B8A8_UNORM};
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
use crate::error::FilterChainError;
|
|
||||||
|
|
||||||
pub struct FilterMutable {
|
pub struct FilterMutable {
|
||||||
pub(crate) passes_enabled: usize,
|
pub(crate) passes_enabled: usize,
|
||||||
|
@ -48,18 +50,19 @@ type ShaderPassMeta = (
|
||||||
);
|
);
|
||||||
|
|
||||||
pub struct FilterChain {
|
pub struct FilterChain {
|
||||||
pub common: FilterCommon,
|
pub(crate) common: FilterCommon,
|
||||||
pub passes: Vec<FilterPass>,
|
pub(crate) passes: Vec<FilterPass>,
|
||||||
pub output_framebuffers: Box<[OwnedFramebuffer]>,
|
pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
pub feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
pub history_framebuffers: VecDeque<OwnedFramebuffer>,
|
pub(crate) history_framebuffers: VecDeque<OwnedFramebuffer>,
|
||||||
pub(crate) draw_quad: DrawQuad,
|
pub(crate) draw_quad: DrawQuad,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Direct3D11 {
|
pub(crate) struct Direct3D11 {
|
||||||
pub(crate) device: ID3D11Device,
|
pub(crate) device: ID3D11Device,
|
||||||
pub(crate) device_context: ID3D11DeviceContext,
|
pub(crate) current_context: ID3D11DeviceContext,
|
||||||
pub context_is_deferred: bool
|
pub(crate) immediate_context: ID3D11DeviceContext,
|
||||||
|
pub context_is_deferred: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FilterCommon {
|
pub struct FilterCommon {
|
||||||
|
@ -69,11 +72,128 @@ pub struct FilterCommon {
|
||||||
pub output_textures: Box<[Option<Texture>]>,
|
pub output_textures: Box<[Option<Texture>]>,
|
||||||
pub feedback_textures: Box<[Option<Texture>]>,
|
pub feedback_textures: Box<[Option<Texture>]>,
|
||||||
pub history_textures: Box<[Option<Texture>]>,
|
pub history_textures: Box<[Option<Texture>]>,
|
||||||
pub config: FilterMutable
|
pub config: FilterMutable,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterChain {
|
impl FilterChain {
|
||||||
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
|
pub fn load_from_path(
|
||||||
|
device: &ID3D11Device,
|
||||||
|
path: impl AsRef<Path>,
|
||||||
|
options: Option<&FilterChainOptions>,
|
||||||
|
) -> error::Result<FilterChain> {
|
||||||
|
// load passes from preset
|
||||||
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
|
Self::load_from_preset(device, preset, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
|
pub fn load_from_preset(
|
||||||
|
device: &ID3D11Device,
|
||||||
|
preset: ShaderPreset,
|
||||||
|
options: Option<&FilterChainOptions>,
|
||||||
|
) -> error::Result<FilterChain> {
|
||||||
|
let (passes, semantics) = FilterChain::load_preset(preset.shaders, &preset.textures)?;
|
||||||
|
|
||||||
|
let use_deferred_context = options.map(|f| f.use_deferred_context).unwrap_or(false);
|
||||||
|
|
||||||
|
let samplers = SamplerSet::new(device)?;
|
||||||
|
|
||||||
|
// initialize passes
|
||||||
|
let filters = FilterChain::init_passes(device, passes, &semantics)?;
|
||||||
|
|
||||||
|
let mut immediate_context = None;
|
||||||
|
unsafe {
|
||||||
|
device.GetImmediateContext(&mut immediate_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(immediate_context) = immediate_context else {
|
||||||
|
return Err(FilterChainError::Direct3DContextError)
|
||||||
|
};
|
||||||
|
|
||||||
|
let current_context = if use_deferred_context {
|
||||||
|
unsafe { device.CreateDeferredContext(0)? }
|
||||||
|
} else {
|
||||||
|
immediate_context.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
// initialize output framebuffers
|
||||||
|
let mut output_framebuffers = Vec::new();
|
||||||
|
output_framebuffers.resize_with(filters.len(), || {
|
||||||
|
OwnedFramebuffer::new(
|
||||||
|
device,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// resolve all results
|
||||||
|
let output_framebuffers = output_framebuffers
|
||||||
|
.into_iter()
|
||||||
|
.collect::<error::Result<Vec<OwnedFramebuffer>>>()?;
|
||||||
|
|
||||||
|
let mut output_textures = Vec::new();
|
||||||
|
output_textures.resize_with(filters.len(), || None);
|
||||||
|
//
|
||||||
|
// // initialize feedback framebuffers
|
||||||
|
let mut feedback_framebuffers = Vec::new();
|
||||||
|
feedback_framebuffers.resize_with(filters.len(), || {
|
||||||
|
OwnedFramebuffer::new(
|
||||||
|
device,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
// resolve all results
|
||||||
|
let feedback_framebuffers = feedback_framebuffers
|
||||||
|
.into_iter()
|
||||||
|
.collect::<error::Result<Vec<OwnedFramebuffer>>>()?;
|
||||||
|
|
||||||
|
let mut feedback_textures = Vec::new();
|
||||||
|
feedback_textures.resize_with(filters.len(), || None);
|
||||||
|
|
||||||
|
// load luts
|
||||||
|
let luts = FilterChain::load_luts(device, ¤t_context, &preset.textures)?;
|
||||||
|
|
||||||
|
let (history_framebuffers, history_textures) =
|
||||||
|
FilterChain::init_history(device, &filters)?;
|
||||||
|
|
||||||
|
let draw_quad = DrawQuad::new(device, ¤t_context)?;
|
||||||
|
|
||||||
|
// todo: make vbo: d3d11.c 1376
|
||||||
|
Ok(FilterChain {
|
||||||
|
passes: filters,
|
||||||
|
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||||
|
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||||
|
history_framebuffers,
|
||||||
|
draw_quad,
|
||||||
|
common: FilterCommon {
|
||||||
|
d3d11: Direct3D11 {
|
||||||
|
device: device.clone(),
|
||||||
|
current_context,
|
||||||
|
immediate_context,
|
||||||
|
context_is_deferred: use_deferred_context,
|
||||||
|
},
|
||||||
|
config: FilterMutable {
|
||||||
|
passes_enabled: preset.shader_count as usize,
|
||||||
|
parameters: preset
|
||||||
|
.parameters
|
||||||
|
.into_iter()
|
||||||
|
.map(|param| (param.name, param.value))
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
|
luts,
|
||||||
|
samplers,
|
||||||
|
output_textures: output_textures.into_boxed_slice(),
|
||||||
|
feedback_textures: feedback_textures.into_boxed_slice(),
|
||||||
|
history_textures,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FilterChain {
|
||||||
|
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> error::Result<ID3D11Buffer> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let buffer = device.CreateBuffer(
|
let buffer = device.CreateBuffer(
|
||||||
&D3D11_BUFFER_DESC {
|
&D3D11_BUFFER_DESC {
|
||||||
|
@ -95,7 +215,7 @@ impl FilterChain {
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
passes: Vec<ShaderPassMeta>,
|
passes: Vec<ShaderPassMeta>,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> util::Result<Vec<FilterPass>> {
|
) -> error::Result<Vec<FilterPass>> {
|
||||||
// let mut filters = Vec::new();
|
// let mut filters = Vec::new();
|
||||||
let mut filters = Vec::new();
|
let mut filters = Vec::new();
|
||||||
|
|
||||||
|
@ -190,108 +310,11 @@ impl FilterChain {
|
||||||
}
|
}
|
||||||
Ok(filters)
|
Ok(filters)
|
||||||
}
|
}
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
|
||||||
pub fn load_from_preset(
|
|
||||||
device: &ID3D11Device,
|
|
||||||
preset: ShaderPreset,
|
|
||||||
) -> util::Result<FilterChain> {
|
|
||||||
let (passes, semantics) = FilterChain::load_preset(preset.shaders, &preset.textures)?;
|
|
||||||
|
|
||||||
let samplers = SamplerSet::new(device)?;
|
|
||||||
|
|
||||||
// initialize passes
|
|
||||||
let filters = FilterChain::init_passes(device, passes, &semantics)?;
|
|
||||||
|
|
||||||
let mut device_context = None;
|
|
||||||
unsafe {
|
|
||||||
device.GetImmediateContext(&mut device_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
let device_context = device_context.unwrap();
|
|
||||||
|
|
||||||
let device_context =
|
|
||||||
unsafe {
|
|
||||||
device.CreateDeferredContext(0)?
|
|
||||||
};
|
|
||||||
// initialize output framebuffers
|
|
||||||
let mut output_framebuffers = Vec::new();
|
|
||||||
output_framebuffers.resize_with(filters.len(), || {
|
|
||||||
OwnedFramebuffer::new(
|
|
||||||
device,
|
|
||||||
&device_context,
|
|
||||||
Size::new(1, 1),
|
|
||||||
ImageFormat::R8G8B8A8Unorm,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
// resolve all results
|
|
||||||
let output_framebuffers = output_framebuffers
|
|
||||||
.into_iter().collect::<util::Result<Vec<OwnedFramebuffer>>>()?;
|
|
||||||
|
|
||||||
let mut output_textures = Vec::new();
|
|
||||||
output_textures.resize_with(filters.len(), || None);
|
|
||||||
//
|
|
||||||
// // initialize feedback framebuffers
|
|
||||||
let mut feedback_framebuffers = Vec::new();
|
|
||||||
feedback_framebuffers.resize_with(filters.len(), || {
|
|
||||||
OwnedFramebuffer::new(
|
|
||||||
device,
|
|
||||||
&device_context,
|
|
||||||
Size::new(1, 1),
|
|
||||||
ImageFormat::R8G8B8A8Unorm,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
// resolve all results
|
|
||||||
let feedback_framebuffers = feedback_framebuffers
|
|
||||||
.into_iter().collect::<util::Result<Vec<OwnedFramebuffer>>>()?;
|
|
||||||
|
|
||||||
let mut feedback_textures = Vec::new();
|
|
||||||
feedback_textures.resize_with(filters.len(), || None);
|
|
||||||
|
|
||||||
// load luts
|
|
||||||
let luts = FilterChain::load_luts(device,
|
|
||||||
&device_context, &preset.textures)?;
|
|
||||||
|
|
||||||
let (history_framebuffers, history_textures) =
|
|
||||||
FilterChain::init_history(device, &device_context, &filters)?;
|
|
||||||
|
|
||||||
let draw_quad = DrawQuad::new(device, &device_context)?;
|
|
||||||
|
|
||||||
// todo: make vbo: d3d11.c 1376
|
|
||||||
Ok(FilterChain {
|
|
||||||
passes: filters,
|
|
||||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
|
||||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
|
||||||
history_framebuffers,
|
|
||||||
draw_quad,
|
|
||||||
common: FilterCommon {
|
|
||||||
d3d11: Direct3D11 {
|
|
||||||
device: device.clone(),
|
|
||||||
device_context,
|
|
||||||
context_is_deferred: false
|
|
||||||
},
|
|
||||||
config: FilterMutable {
|
|
||||||
passes_enabled: preset.shader_count as usize,
|
|
||||||
parameters: preset
|
|
||||||
.parameters
|
|
||||||
.into_iter()
|
|
||||||
.map(|param| (param.name, param.value))
|
|
||||||
.collect(),
|
|
||||||
},
|
|
||||||
luts,
|
|
||||||
samplers,
|
|
||||||
output_textures: output_textures.into_boxed_slice(),
|
|
||||||
feedback_textures: feedback_textures.into_boxed_slice(),
|
|
||||||
history_textures,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_history(
|
fn init_history(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
context: &ID3D11DeviceContext,
|
|
||||||
filters: &[FilterPass],
|
filters: &[FilterPass],
|
||||||
) -> util::Result<(VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>)> {
|
) -> error::Result<(VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>)> {
|
||||||
let mut required_images = 0;
|
let mut required_images = 0;
|
||||||
|
|
||||||
for pass in filters {
|
for pass in filters {
|
||||||
|
@ -326,11 +349,12 @@ impl FilterChain {
|
||||||
eprintln!("[history] using frame history with {required_images} images");
|
eprintln!("[history] using frame history with {required_images} images");
|
||||||
let mut framebuffers = VecDeque::with_capacity(required_images);
|
let mut framebuffers = VecDeque::with_capacity(required_images);
|
||||||
framebuffers.resize_with(required_images, || {
|
framebuffers.resize_with(required_images, || {
|
||||||
OwnedFramebuffer::new(device, context, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm)
|
OwnedFramebuffer::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm)
|
||||||
});
|
});
|
||||||
|
|
||||||
let framebuffers = framebuffers
|
let framebuffers = framebuffers
|
||||||
.into_iter().collect::<util::Result<VecDeque<OwnedFramebuffer>>>()?;
|
.into_iter()
|
||||||
|
.collect::<error::Result<VecDeque<OwnedFramebuffer>>>()?;
|
||||||
|
|
||||||
let mut history_textures = Vec::new();
|
let mut history_textures = Vec::new();
|
||||||
history_textures.resize_with(required_images, || None);
|
history_textures.resize_with(required_images, || None);
|
||||||
|
@ -338,9 +362,9 @@ impl FilterChain {
|
||||||
Ok((framebuffers, history_textures.into_boxed_slice()))
|
Ok((framebuffers, history_textures.into_boxed_slice()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_history(&mut self, input: &DxImageView) -> util::Result<()> {
|
fn push_history(&mut self, input: &DxImageView) -> error::Result<()> {
|
||||||
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
||||||
back.copy_from(&input)?;
|
back.copy_from(input)?;
|
||||||
self.history_framebuffers.push_front(back)
|
self.history_framebuffers.push_front(back)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +375,7 @@ impl FilterChain {
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
context: &ID3D11DeviceContext,
|
context: &ID3D11DeviceContext,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureConfig],
|
||||||
) -> util::Result<FxHashMap<usize, LutTexture>> {
|
) -> error::Result<FxHashMap<usize, LutTexture>> {
|
||||||
let mut luts = FxHashMap::default();
|
let mut luts = FxHashMap::default();
|
||||||
|
|
||||||
for (index, texture) in textures.iter().enumerate() {
|
for (index, texture) in textures.iter().enumerate() {
|
||||||
|
@ -369,26 +393,23 @@ impl FilterChain {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let texture =
|
let texture = LutTexture::new(
|
||||||
LutTexture::new(device, context,&image, desc, texture.filter_mode, texture.wrap_mode)?;
|
device,
|
||||||
|
context,
|
||||||
|
&image,
|
||||||
|
desc,
|
||||||
|
texture.filter_mode,
|
||||||
|
texture.wrap_mode,
|
||||||
|
)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
fn load_preset(
|
||||||
pub fn load_from_path(
|
passes: Vec<ShaderPassConfig>,
|
||||||
device: &ID3D11Device,
|
textures: &[TextureConfig],
|
||||||
path: impl AsRef<Path>,
|
) -> error::Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
|
||||||
) -> util::Result<FilterChain> {
|
|
||||||
// load passes from preset
|
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
|
||||||
Self::load_from_preset(device, preset)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_preset( passes: Vec<ShaderPassConfig>,
|
|
||||||
textures: &[TextureConfig],
|
|
||||||
) -> util::Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
|
|
||||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
||||||
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
|
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
|
||||||
Default::default();
|
Default::default();
|
||||||
|
@ -414,7 +435,7 @@ impl FilterChain {
|
||||||
Ok::<_, FilterChainError>((shader, source, reflect))
|
Ok::<_, FilterChainError>((shader, source, reflect))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<util::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for details in &passes {
|
for details in &passes {
|
||||||
|
@ -425,7 +446,7 @@ impl FilterChain {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
librashader_runtime::semantics::insert_lut_semantics(
|
librashader_runtime::semantics::insert_lut_semantics(
|
||||||
&textures,
|
textures,
|
||||||
&mut uniform_semantics,
|
&mut uniform_semantics,
|
||||||
&mut texture_semantics,
|
&mut texture_semantics,
|
||||||
);
|
);
|
||||||
|
@ -440,12 +461,19 @@ impl FilterChain {
|
||||||
|
|
||||||
pub fn frame(
|
pub fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
count: usize,
|
|
||||||
viewport: &Size<u32>,
|
|
||||||
input: DxImageView,
|
input: DxImageView,
|
||||||
output: OutputFramebuffer,
|
viewport: &Viewport,
|
||||||
) -> util::Result<()> {
|
frame_count: usize,
|
||||||
let passes = &mut self.passes;
|
options: Option<&FrameOptions>,
|
||||||
|
) -> error::Result<()> {
|
||||||
|
let passes = &mut self.passes[0..self.common.config.passes_enabled];
|
||||||
|
if let Some(options) = options {
|
||||||
|
if options.clear_history {
|
||||||
|
for framebuffer in &mut self.history_framebuffers {
|
||||||
|
framebuffer.init(Size::new(1, 1), ImageFormat::R8G8B8A8Unorm)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if passes.is_empty() {
|
if passes.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -469,7 +497,7 @@ impl FilterChain {
|
||||||
self.output_framebuffers[index].scale(
|
self.output_framebuffers[index].scale(
|
||||||
pass.config.scaling.clone(),
|
pass.config.scaling.clone(),
|
||||||
pass.get_format(),
|
pass.get_format(),
|
||||||
viewport,
|
&viewport.size,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
)?;
|
)?;
|
||||||
|
@ -477,7 +505,7 @@ impl FilterChain {
|
||||||
self.feedback_framebuffers[index].scale(
|
self.feedback_framebuffers[index].scale(
|
||||||
pass.config.scaling.clone(),
|
pass.config.scaling.clone(),
|
||||||
pass.get_format(),
|
pass.get_format(),
|
||||||
viewport,
|
&viewport.size,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
)?;
|
)?;
|
||||||
|
@ -494,9 +522,9 @@ impl FilterChain {
|
||||||
index,
|
index,
|
||||||
&self.common,
|
&self.common,
|
||||||
if pass.config.frame_count_mod > 0 {
|
if pass.config.frame_count_mod > 0 {
|
||||||
count % pass.config.frame_count_mod as usize
|
frame_count % pass.config.frame_count_mod as usize
|
||||||
} else {
|
} else {
|
||||||
count
|
frame_count
|
||||||
} as u32,
|
} as u32,
|
||||||
1,
|
1,
|
||||||
viewport,
|
viewport,
|
||||||
|
@ -523,15 +551,15 @@ impl FilterChain {
|
||||||
passes_len - 1,
|
passes_len - 1,
|
||||||
&self.common,
|
&self.common,
|
||||||
if pass.config.frame_count_mod > 0 {
|
if pass.config.frame_count_mod > 0 {
|
||||||
count % pass.config.frame_count_mod as usize
|
frame_count % pass.config.frame_count_mod as usize
|
||||||
} else {
|
} else {
|
||||||
count
|
frame_count
|
||||||
} as u32,
|
} as u32,
|
||||||
1,
|
1,
|
||||||
viewport,
|
viewport,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
RenderTarget::new(output, None),
|
viewport.into(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// diverge so we don't need to clone output.
|
// diverge so we don't need to clone output.
|
||||||
|
@ -549,12 +577,14 @@ impl FilterChain {
|
||||||
|
|
||||||
self.push_history(&input)?;
|
self.push_history(&input)?;
|
||||||
|
|
||||||
unsafe {
|
if self.common.d3d11.context_is_deferred {
|
||||||
let list = self.common.d3d11.device_context.FinishCommandList(false)?;
|
unsafe {
|
||||||
let mut imm = None;
|
let command_list = self.common.d3d11.current_context.FinishCommandList(false)?;
|
||||||
self.common.d3d11.device.GetImmediateContext(&mut imm);
|
self.common
|
||||||
let imm = imm.unwrap();
|
.d3d11
|
||||||
imm.ExecuteCommandList(&list, true);
|
.immediate_context
|
||||||
|
.ExecuteCommandList(&command_list, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -10,17 +10,17 @@ use librashader_reflect::reflect::semantics::{
|
||||||
};
|
};
|
||||||
use librashader_reflect::reflect::ShaderReflection;
|
use librashader_reflect::reflect::ShaderReflection;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
use windows::Win32::Graphics::Direct3D11::{
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
|
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
|
||||||
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD,
|
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::error;
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
|
use crate::viewport::Viewport;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use crate::util;
|
|
||||||
|
|
||||||
pub struct ConstantBufferBinding {
|
pub struct ConstantBufferBinding {
|
||||||
pub binding: u32,
|
pub binding: u32,
|
||||||
|
@ -301,8 +301,6 @@ impl FilterPass {
|
||||||
{
|
{
|
||||||
let id = id.as_str();
|
let id = id.as_str();
|
||||||
|
|
||||||
// todo: cache parameters.
|
|
||||||
// presets override params
|
|
||||||
let default = self
|
let default = self
|
||||||
.source
|
.source
|
||||||
.parameters
|
.parameters
|
||||||
|
@ -345,19 +343,19 @@ impl FilterPass {
|
||||||
(textures, samplers)
|
(textures, samplers)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(
|
pub(crate) fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_index: usize,
|
pass_index: usize,
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
frame_direction: i32,
|
frame_direction: i32,
|
||||||
viewport: &Size<u32>,
|
viewport: &Viewport,
|
||||||
original: &Texture,
|
original: &Texture,
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
output: RenderTarget,
|
output: RenderTarget,
|
||||||
) -> util::Result<()> {
|
) -> error::Result<()> {
|
||||||
let _device = &parent.d3d11.device;
|
let _device = &parent.d3d11.device;
|
||||||
let context = &parent.d3d11.device_context;
|
let context = &parent.d3d11.current_context;
|
||||||
unsafe {
|
unsafe {
|
||||||
context.IASetInputLayout(&self.vertex_layout);
|
context.IASetInputLayout(&self.vertex_layout);
|
||||||
context.VSSetShader(&self.vertex_shader, None);
|
context.VSSetShader(&self.vertex_shader, None);
|
||||||
|
@ -371,7 +369,7 @@ impl FilterPass {
|
||||||
frame_count,
|
frame_count,
|
||||||
frame_direction,
|
frame_direction,
|
||||||
output.output.size,
|
output.output.size,
|
||||||
*viewport,
|
viewport.size,
|
||||||
original,
|
original,
|
||||||
source,
|
source,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
use windows::core::Interface;
|
use crate::error;
|
||||||
use crate::texture::{DxImageView, Texture};
|
use crate::texture::{DxImageView, Texture};
|
||||||
use crate::util;
|
|
||||||
use crate::util::d3d11_get_closest_format;
|
use crate::util::d3d11_get_closest_format;
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_presets::Scale2D;
|
use librashader_presets::Scale2D;
|
||||||
|
use windows::core::Interface;
|
||||||
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
||||||
use windows::Win32::Graphics::Direct3D11::{
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11Resource,
|
ID3D11Device, ID3D11RenderTargetView, ID3D11ShaderResourceView,
|
||||||
ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_RENDER_TARGET,
|
ID3D11Texture2D, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_CPU_ACCESS_WRITE,
|
||||||
D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_WRITE,
|
|
||||||
D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE,
|
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_FORMAT_SUPPORT_TEXTURE2D, D3D11_RENDER_TARGET_VIEW_DESC, D3D11_RENDER_TARGET_VIEW_DESC_0,
|
||||||
D3D11_RTV_DIMENSION_TEXTURE2D, D3D11_SHADER_RESOURCE_VIEW_DESC,
|
D3D11_RTV_DIMENSION_TEXTURE2D, D3D11_SHADER_RESOURCE_VIEW_DESC,
|
||||||
|
@ -18,22 +17,20 @@ use windows::Win32::Graphics::Direct3D11::{
|
||||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
|
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OwnedFramebuffer {
|
pub(crate) struct OwnedFramebuffer {
|
||||||
pub texture: ID3D11Texture2D,
|
pub texture: ID3D11Texture2D,
|
||||||
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(
|
pub fn new(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
context: &ID3D11DeviceContext,
|
|
||||||
size: Size<u32>,
|
size: Size<u32>,
|
||||||
format: ImageFormat,
|
format: ImageFormat,
|
||||||
) -> util::Result<OwnedFramebuffer> {
|
) -> error::Result<OwnedFramebuffer> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let format = d3d11_get_closest_format(
|
let format = d3d11_get_closest_format(
|
||||||
device,
|
device,
|
||||||
|
@ -50,7 +47,6 @@ impl OwnedFramebuffer {
|
||||||
size,
|
size,
|
||||||
format,
|
format,
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
context: context.clone(),
|
|
||||||
is_raw: false,
|
is_raw: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -63,7 +59,7 @@ impl OwnedFramebuffer {
|
||||||
viewport_size: &Size<u32>,
|
viewport_size: &Size<u32>,
|
||||||
_original: &Texture,
|
_original: &Texture,
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
) -> util::Result<Size<u32>> {
|
) -> error::Result<Size<u32>> {
|
||||||
if self.is_raw {
|
if self.is_raw {
|
||||||
return Ok(self.size);
|
return Ok(self.size);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +81,7 @@ impl OwnedFramebuffer {
|
||||||
Ok(size)
|
Ok(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self, size: Size<u32>, format: ImageFormat) -> util::Result<()> {
|
pub fn init(&mut self, size: Size<u32>, format: ImageFormat) -> error::Result<()> {
|
||||||
if self.is_raw {
|
if self.is_raw {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -110,7 +106,7 @@ impl OwnedFramebuffer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_shader_resource_view(&self) -> util::Result<ID3D11ShaderResourceView> {
|
pub fn create_shader_resource_view(&self) -> error::Result<ID3D11ShaderResourceView> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Ok(self.device.CreateShaderResourceView(
|
Ok(self.device.CreateShaderResourceView(
|
||||||
&self.texture,
|
&self.texture,
|
||||||
|
@ -128,7 +124,7 @@ impl OwnedFramebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_render_target_view(&self) -> util::Result<ID3D11RenderTargetView> {
|
pub fn create_render_target_view(&self) -> error::Result<ID3D11RenderTargetView> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Ok(self.device.CreateRenderTargetView(
|
Ok(self.device.CreateRenderTargetView(
|
||||||
&self.texture,
|
&self.texture,
|
||||||
|
@ -143,7 +139,7 @@ impl OwnedFramebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_output_framebuffer(&self) -> util::Result<OutputFramebuffer> {
|
pub fn as_output_framebuffer(&self) -> error::Result<OutputFramebuffer> {
|
||||||
Ok(OutputFramebuffer {
|
Ok(OutputFramebuffer {
|
||||||
rtv: self.create_render_target_view()?,
|
rtv: self.create_render_target_view()?,
|
||||||
size: self.size,
|
size: self.size,
|
||||||
|
@ -151,7 +147,7 @@ impl OwnedFramebuffer {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_from(&mut self, image: &DxImageView) -> util::Result<()> {
|
pub fn copy_from(&mut self, image: &DxImageView) -> error::Result<()> {
|
||||||
let resource: ID3D11Texture2D = unsafe {
|
let resource: ID3D11Texture2D = unsafe {
|
||||||
let mut resource = None;
|
let mut resource = None;
|
||||||
image.handle.GetResource(&mut resource);
|
image.handle.GetResource(&mut resource);
|
||||||
|
@ -172,12 +168,12 @@ impl OwnedFramebuffer {
|
||||||
self.init(image.size, ImageFormat::from(format))?;
|
self.init(image.size, ImageFormat::from(format))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.texture = resource.clone();
|
self.texture = resource;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OutputFramebuffer {
|
pub(crate) struct OutputFramebuffer {
|
||||||
pub rtv: ID3D11RenderTargetView,
|
pub rtv: ID3D11RenderTargetView,
|
||||||
pub size: Size<u32>,
|
pub size: Size<u32>,
|
||||||
pub viewport: D3D11_VIEWPORT,
|
pub viewport: D3D11_VIEWPORT,
|
||||||
|
|
|
@ -225,14 +225,14 @@ pub mod d3d11_hello_triangle {
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::filter_chain::FilterChain;
|
use crate::filter_chain::FilterChain;
|
||||||
use crate::framebuffer::OutputFramebuffer;
|
|
||||||
|
use crate::options::FilterChainOptions;
|
||||||
use crate::texture::DxImageView;
|
use crate::texture::DxImageView;
|
||||||
|
use crate::viewport::Viewport;
|
||||||
use librashader_common::Size;
|
use librashader_common::Size;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
const FRAME_COUNT: u32 = 2;
|
|
||||||
|
|
||||||
pub struct Sample {
|
pub struct Sample {
|
||||||
pub dxgi_factory: IDXGIFactory4,
|
pub dxgi_factory: IDXGIFactory4,
|
||||||
pub device: ID3D11Device,
|
pub device: ID3D11Device,
|
||||||
|
@ -263,9 +263,12 @@ pub mod d3d11_hello_triangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sample {
|
impl Sample {
|
||||||
pub(crate) fn new(filter: impl AsRef<Path>) -> Result<Self> {
|
pub(crate) fn new(
|
||||||
|
filter: impl AsRef<Path>,
|
||||||
|
filter_options: Option<&FilterChainOptions>,
|
||||||
|
) -> Result<Self> {
|
||||||
let (dxgi_factory, device, context) = create_device()?;
|
let (dxgi_factory, device, context) = create_device()?;
|
||||||
let filter = FilterChain::load_from_path(&device, filter).unwrap();
|
let filter = FilterChain::load_from_path(&device, filter, filter_options).unwrap();
|
||||||
Ok(Sample {
|
Ok(Sample {
|
||||||
filter,
|
filter,
|
||||||
dxgi_factory,
|
dxgi_factory,
|
||||||
|
@ -469,14 +472,25 @@ pub mod d3d11_hello_triangle {
|
||||||
}),
|
}),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
//
|
// OutputFramebuffer {
|
||||||
|
// rtv: resources.rtv.clone(),
|
||||||
|
// // rtv,
|
||||||
|
// size: Size {
|
||||||
|
// width: tex2d_desc.Width,
|
||||||
|
// height: tex2d_desc.Height,
|
||||||
|
// },
|
||||||
|
// viewport: resources.viewport, // 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,
|
||||||
|
// // },
|
||||||
|
// },
|
||||||
|
|
||||||
self.filter
|
self.filter
|
||||||
.frame(
|
.frame(
|
||||||
resources.frame_count,
|
|
||||||
&Size {
|
|
||||||
width: tex2d_desc.Width,
|
|
||||||
height: tex2d_desc.Height,
|
|
||||||
},
|
|
||||||
DxImageView {
|
DxImageView {
|
||||||
handle: srv,
|
handle: srv,
|
||||||
size: Size {
|
size: Size {
|
||||||
|
@ -484,22 +498,18 @@ pub mod d3d11_hello_triangle {
|
||||||
height: tex2d_desc.Height,
|
height: tex2d_desc.Height,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
OutputFramebuffer {
|
&Viewport {
|
||||||
rtv: resources.rtv.clone(),
|
x: resources.viewport.TopLeftX,
|
||||||
// rtv,
|
y: resources.viewport.TopLeftY,
|
||||||
size: Size {
|
size: Size {
|
||||||
width: tex2d_desc.Width,
|
width: tex2d_desc.Width,
|
||||||
height: tex2d_desc.Height,
|
height: tex2d_desc.Height,
|
||||||
},
|
},
|
||||||
viewport: resources.viewport, // viewport: D3D11_VIEWPORT {
|
output: resources.rtv.clone(),
|
||||||
// TopLeftX: 0.0,
|
mvp: None,
|
||||||
// TopLeftY: 0.0,
|
|
||||||
// Width: tex2d_desc.Width as f32,
|
|
||||||
// Height: tex2d_desc.Height as f32,
|
|
||||||
// MinDepth: 0.0,
|
|
||||||
// MaxDepth: 1.0,
|
|
||||||
// },
|
|
||||||
},
|
},
|
||||||
|
resources.frame_count,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -705,13 +715,7 @@ pub mod d3d11_hello_triangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn create_device() -> Result<(IDXGIFactory4, ID3D11Device, ID3D11DeviceContext)> {
|
fn create_device() -> Result<(IDXGIFactory4, ID3D11Device, ID3D11DeviceContext)> {
|
||||||
let dxgi_factory_flags = if cfg!(debug_assertions) {
|
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG) }?;
|
||||||
DXGI_CREATE_FACTORY_DEBUG
|
|
||||||
} else {
|
|
||||||
DXGI_CREATE_FACTORY_DEBUG
|
|
||||||
};
|
|
||||||
|
|
||||||
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(dxgi_factory_flags) }?;
|
|
||||||
let feature_levels = vec![D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1];
|
let feature_levels = vec![D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1];
|
||||||
|
|
||||||
let mut out_device = None;
|
let mut out_device = None;
|
||||||
|
|
|
@ -4,15 +4,17 @@
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
|
|
||||||
|
pub mod error;
|
||||||
mod filter_chain;
|
mod filter_chain;
|
||||||
mod filter_pass;
|
mod filter_pass;
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
|
pub mod options;
|
||||||
mod quad_render;
|
mod quad_render;
|
||||||
mod render_target;
|
mod render_target;
|
||||||
mod samplers;
|
mod samplers;
|
||||||
mod texture;
|
mod texture;
|
||||||
mod util;
|
mod util;
|
||||||
pub mod error;
|
mod viewport;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -21,11 +23,18 @@ 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(
|
let sample = hello_triangle::d3d11_hello_triangle::Sample::new(
|
||||||
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
"../test/slang-shaders/crt/crt-royale.slangp",
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
// let sample = hello_triangle::d3d11_hello_triangle::Sample::new(
|
||||||
|
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||||
|
// Some(&FilterChainOptions {
|
||||||
|
// use_deferred_context: true,
|
||||||
|
// })
|
||||||
|
// )
|
||||||
|
// .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();
|
||||||
|
|
||||||
|
|
11
librashader-runtime-d3d11/src/options.rs
Normal file
11
librashader-runtime-d3d11/src/options.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FrameOptions {
|
||||||
|
pub clear_history: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FilterChainOptions {
|
||||||
|
pub use_deferred_context: bool,
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::util;
|
use crate::error;
|
||||||
use bytemuck::offset_of;
|
use bytemuck::offset_of;
|
||||||
use windows::core::PCSTR;
|
use windows::core::PCSTR;
|
||||||
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||||
|
@ -50,7 +50,7 @@ pub(crate) struct DrawQuad {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawQuad {
|
impl DrawQuad {
|
||||||
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> util::Result<DrawQuad> {
|
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> error::Result<DrawQuad> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let buffer = device.CreateBuffer(
|
let buffer = device.CreateBuffer(
|
||||||
&D3D11_BUFFER_DESC {
|
&D3D11_BUFFER_DESC {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::framebuffer::OutputFramebuffer;
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
|
use crate::viewport::Viewport;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static DEFAULT_MVP: &[f32; 16] = &[
|
static DEFAULT_MVP: &[f32; 16] = &[
|
||||||
|
@ -9,7 +11,7 @@ static DEFAULT_MVP: &[f32; 16] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RenderTarget<'a> {
|
pub(crate) struct RenderTarget<'a> {
|
||||||
pub mvp: &'a [f32; 16],
|
pub mvp: &'a [f32; 16],
|
||||||
pub output: OutputFramebuffer,
|
pub output: OutputFramebuffer,
|
||||||
}
|
}
|
||||||
|
@ -29,3 +31,23 @@ impl<'a> RenderTarget<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&Viewport<'a>> for RenderTarget<'a> {
|
||||||
|
fn from(value: &Viewport<'a>) -> Self {
|
||||||
|
RenderTarget::new(
|
||||||
|
OutputFramebuffer {
|
||||||
|
rtv: value.output.clone(),
|
||||||
|
size: value.size,
|
||||||
|
viewport: D3D11_VIEWPORT {
|
||||||
|
TopLeftX: value.x,
|
||||||
|
TopLeftY: value.y,
|
||||||
|
Width: value.size.width as f32,
|
||||||
|
Height: value.size.height as f32,
|
||||||
|
MinDepth: 0.0,
|
||||||
|
MaxDepth: 1.0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
value.mvp,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::util::Result;
|
use crate::error::Result;
|
||||||
use librashader_common::{FilterMode, WrapMode};
|
use librashader_common::{FilterMode, WrapMode};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use windows::Win32::Graphics::Direct3D11::{
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::{FilterMode, Size, WrapMode};
|
use librashader_common::{FilterMode, Size, WrapMode};
|
||||||
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
||||||
use windows::Win32::Graphics::Direct3D11::{ID3D11Device, ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_FLAG, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_FLAG, D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE, D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_SUBRESOURCE_DATA, D3D11_TEX2D_SRV, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_USAGE_STAGING, ID3D11DeviceContext};
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
|
ID3D11Device, ID3D11DeviceContext, ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_FLAG,
|
||||||
|
D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_FLAG,
|
||||||
|
D3D11_CPU_ACCESS_WRITE, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS,
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_SUBRESOURCE_DATA,
|
||||||
|
D3D11_TEX2D_SRV, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_USAGE_STAGING,
|
||||||
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||||
use crate::filter_chain::Direct3D11;
|
|
||||||
|
|
||||||
use crate::util::Result;
|
use crate::error::Result;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DxImageView {
|
pub struct DxImageView {
|
||||||
|
@ -71,16 +76,8 @@ impl LutTexture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine if format is supported.
|
// Don't need to determine format support because LUTs are always DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
// bruh why does D3D11_FORMAT_SUPPORT not implement bitor???
|
// since we load them with the Image module.
|
||||||
let mut format_support =
|
|
||||||
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0;
|
|
||||||
if (desc.BindFlags & D3D11_BIND_RENDER_TARGET).0 != 0 {
|
|
||||||
format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len());
|
|
||||||
// eprintln!("{:#?}", desc);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::error::Error;
|
use crate::error;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use windows::core::PCSTR;
|
use windows::core::PCSTR;
|
||||||
use windows::Win32::Graphics::Direct3D::Fxc::{
|
use windows::Win32::Graphics::Direct3D::Fxc::{
|
||||||
|
@ -104,7 +104,7 @@ pub fn d3d11_get_closest_format(
|
||||||
DXGI_FORMAT_UNKNOWN
|
DXGI_FORMAT_UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result<ID3DBlob> {
|
pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> error::Result<ID3DBlob> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut blob = None;
|
let mut blob = None;
|
||||||
D3DCompile(
|
D3DCompile(
|
||||||
|
@ -115,7 +115,7 @@ pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result
|
||||||
None,
|
None,
|
||||||
PCSTR(entry.as_ptr()),
|
PCSTR(entry.as_ptr()),
|
||||||
PCSTR(version.as_ptr()),
|
PCSTR(version.as_ptr()),
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(feature = "debug-shader") {
|
||||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
|
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
@ -137,7 +137,7 @@ pub fn d3d11_compile_bound_shader<'a, T, L>(
|
||||||
blob: &ID3DBlob,
|
blob: &ID3DBlob,
|
||||||
linkage: L,
|
linkage: L,
|
||||||
factory: ShaderFactory<'a, L, T>,
|
factory: ShaderFactory<'a, L, T>,
|
||||||
) -> Result<T>
|
) -> error::Result<T>
|
||||||
where
|
where
|
||||||
L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>,
|
L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>,
|
||||||
{
|
{
|
||||||
|
@ -155,7 +155,7 @@ pub fn d3d11_create_input_layout(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
desc: &[D3D11_INPUT_ELEMENT_DESC],
|
desc: &[D3D11_INPUT_ELEMENT_DESC],
|
||||||
blob: &ID3DBlob,
|
blob: &ID3DBlob,
|
||||||
) -> Result<ID3D11InputLayout> {
|
) -> error::Result<ID3D11InputLayout> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// SAFETY: slice as valid for as long as vs_blob is alive.
|
// SAFETY: slice as valid for as long as vs_blob is alive.
|
||||||
let dxil =
|
let dxil =
|
||||||
|
@ -165,6 +165,3 @@ pub fn d3d11_create_input_layout(
|
||||||
Ok(compiled)
|
Ok(compiled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: d3d11.c 2097
|
|
||||||
pub type Result<T> = std::result::Result<T, crate::error::FilterChainError>;
|
|
||||||
|
|
11
librashader-runtime-d3d11/src/viewport.rs
Normal file
11
librashader-runtime-d3d11/src/viewport.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
use librashader_common::Size;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::ID3D11RenderTargetView;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Viewport<'a> {
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
pub size: Size<u32>,
|
||||||
|
pub output: ID3D11RenderTargetView,
|
||||||
|
pub mvp: Option<&'a [f32; 16]>,
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue