d3d11: make error unboxed
This commit is contained in:
parent
759cd4bc28
commit
6519a78df2
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -491,6 +491,8 @@ dependencies = [
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
"librashader-runtime",
|
"librashader-runtime",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
"spirv_cross",
|
||||||
|
"thiserror",
|
||||||
"windows",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,10 @@ librashader-presets = { path = "../librashader-presets" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess" }
|
librashader-preprocess = { path = "../librashader-preprocess" }
|
||||||
librashader-reflect = { path = "../librashader-reflect" }
|
librashader-reflect = { path = "../librashader-reflect" }
|
||||||
librashader-runtime = { path = "../librashader-runtime" }
|
librashader-runtime = { path = "../librashader-runtime" }
|
||||||
|
thiserror = "1.0.37"
|
||||||
|
spirv_cross = "0.23.1"
|
||||||
|
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
gfx-maths = "0.2.8"
|
|
||||||
bytemuck = "1.12.3"
|
bytemuck = "1.12.3"
|
||||||
|
|
||||||
[dependencies.windows]
|
[dependencies.windows]
|
||||||
|
@ -33,3 +34,4 @@ features = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
gfx-maths = "0.2.8"
|
||||||
|
|
25
librashader-runtime-d3d11/src/error.rs
Normal file
25
librashader-runtime-d3d11/src/error.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
use librashader_common::image::ImageError;
|
||||||
|
use librashader_preprocess::PreprocessError;
|
||||||
|
use librashader_presets::ParsePresetError;
|
||||||
|
use librashader_reflect::error::{ShaderCompileError, ShaderReflectError};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum FilterChainError {
|
||||||
|
#[error("unable to get direct3d context")]
|
||||||
|
Direct3DContextError,
|
||||||
|
#[error("direct3d driver error")]
|
||||||
|
Direct3DError(#[from] windows::core::Error),
|
||||||
|
#[error("SPIRV reflection error")]
|
||||||
|
SpirvCrossReflectError(#[from] spirv_cross::ErrorCode),
|
||||||
|
#[error("shader preset parse error")]
|
||||||
|
ShaderPresetError(#[from] ParsePresetError),
|
||||||
|
#[error("shader preprocess error")]
|
||||||
|
ShaderPreprocessError(#[from] PreprocessError),
|
||||||
|
#[error("shader compile error")]
|
||||||
|
ShaderCompileError(#[from] ShaderCompileError),
|
||||||
|
#[error("shader reflect error")]
|
||||||
|
ShaderReflectError(#[from] ShaderReflectError),
|
||||||
|
#[error("lut loading error")]
|
||||||
|
LutLoadError(#[from] ImageError),
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::texture::{DxImageView, OwnedTexture, Texture};
|
use crate::texture::{DxImageView, LutTexture, Texture};
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
|
@ -31,10 +31,16 @@ use windows::Win32::Graphics::Direct3D11::{
|
||||||
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, DXGI_FORMAT_R8G8B8A8_UNORM};
|
||||||
|
use crate::error::FilterChainError;
|
||||||
|
|
||||||
|
pub struct FilterMutable {
|
||||||
|
pub(crate) passes_enabled: usize,
|
||||||
|
pub(crate) parameters: FxHashMap<String, f32>,
|
||||||
|
}
|
||||||
|
|
||||||
// todo: get rid of preset
|
// todo: get rid of preset
|
||||||
type ShaderPassMeta<'a> = (
|
type ShaderPassMeta = (
|
||||||
&'a ShaderPassConfig,
|
ShaderPassConfig,
|
||||||
ShaderSource,
|
ShaderSource,
|
||||||
CompilerBackend<
|
CompilerBackend<
|
||||||
impl CompileShader<HLSL, Options = Option<()>, Context = GlslangHlslContext> + ReflectShader,
|
impl CompileShader<HLSL, Options = Option<()>, Context = GlslangHlslContext> + ReflectShader,
|
||||||
|
@ -53,16 +59,17 @@ pub struct FilterChain {
|
||||||
pub struct Direct3D11 {
|
pub struct Direct3D11 {
|
||||||
pub(crate) device: ID3D11Device,
|
pub(crate) device: ID3D11Device,
|
||||||
pub(crate) device_context: ID3D11DeviceContext,
|
pub(crate) device_context: ID3D11DeviceContext,
|
||||||
|
pub context_is_deferred: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FilterCommon {
|
pub struct FilterCommon {
|
||||||
pub(crate) d3d11: Direct3D11,
|
pub(crate) d3d11: Direct3D11,
|
||||||
pub(crate) preset: ShaderPreset,
|
pub(crate) luts: FxHashMap<usize, LutTexture>,
|
||||||
pub(crate) luts: FxHashMap<usize, OwnedTexture>,
|
|
||||||
pub samplers: SamplerSet,
|
pub samplers: SamplerSet,
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterChain {
|
impl FilterChain {
|
||||||
|
@ -188,17 +195,18 @@ impl FilterChain {
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
) -> util::Result<FilterChain> {
|
) -> util::Result<FilterChain> {
|
||||||
let (passes, semantics) = FilterChain::load_preset(&preset)?;
|
let (passes, semantics) = FilterChain::load_preset(preset.shaders, &preset.textures)?;
|
||||||
|
|
||||||
let samplers = SamplerSet::new(device)?;
|
let samplers = SamplerSet::new(device)?;
|
||||||
|
|
||||||
// initialize passes
|
// initialize passes
|
||||||
let filters = FilterChain::init_passes(device, passes, &semantics).unwrap();
|
let filters = FilterChain::init_passes(device, passes, &semantics)?;
|
||||||
|
|
||||||
let mut device_context = None;
|
let mut device_context = None;
|
||||||
unsafe {
|
unsafe {
|
||||||
device.GetImmediateContext(&mut device_context);
|
device.GetImmediateContext(&mut device_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
let device_context = device_context.unwrap();
|
let device_context = device_context.unwrap();
|
||||||
|
|
||||||
let device_context =
|
let device_context =
|
||||||
|
@ -214,8 +222,12 @@ impl FilterChain {
|
||||||
Size::new(1, 1),
|
Size::new(1, 1),
|
||||||
ImageFormat::R8G8B8A8Unorm,
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
)
|
)
|
||||||
.unwrap()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// resolve all results
|
||||||
|
let output_framebuffers = output_framebuffers
|
||||||
|
.into_iter().collect::<util::Result<Vec<OwnedFramebuffer>>>()?;
|
||||||
|
|
||||||
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);
|
||||||
//
|
//
|
||||||
|
@ -228,16 +240,20 @@ impl FilterChain {
|
||||||
Size::new(1, 1),
|
Size::new(1, 1),
|
||||||
ImageFormat::R8G8B8A8Unorm,
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
)
|
)
|
||||||
.unwrap()
|
|
||||||
});
|
});
|
||||||
|
// resolve all results
|
||||||
|
let feedback_framebuffers = feedback_framebuffers
|
||||||
|
.into_iter().collect::<util::Result<Vec<OwnedFramebuffer>>>()?;
|
||||||
|
|
||||||
let mut feedback_textures = Vec::new();
|
let mut feedback_textures = Vec::new();
|
||||||
feedback_textures.resize_with(filters.len(), || None);
|
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,
|
||||||
|
&device_context, &preset.textures)?;
|
||||||
|
|
||||||
let (history_framebuffers, history_textures) =
|
let (history_framebuffers, history_textures) =
|
||||||
FilterChain::init_history(device, &device_context, &filters);
|
FilterChain::init_history(device, &device_context, &filters)?;
|
||||||
|
|
||||||
let draw_quad = DrawQuad::new(device, &device_context)?;
|
let draw_quad = DrawQuad::new(device, &device_context)?;
|
||||||
|
|
||||||
|
@ -252,12 +268,18 @@ impl FilterChain {
|
||||||
d3d11: Direct3D11 {
|
d3d11: Direct3D11 {
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
device_context,
|
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,
|
luts,
|
||||||
samplers,
|
samplers,
|
||||||
// we don't need the reflect semantics once all locations have been bound per pass.
|
|
||||||
// semantics,
|
|
||||||
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,
|
||||||
|
@ -269,7 +291,7 @@ impl FilterChain {
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
context: &ID3D11DeviceContext,
|
context: &ID3D11DeviceContext,
|
||||||
filters: &[FilterPass],
|
filters: &[FilterPass],
|
||||||
) -> (VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>) {
|
) -> util::Result<(VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>)> {
|
||||||
let mut required_images = 0;
|
let mut required_images = 0;
|
||||||
|
|
||||||
for pass in filters {
|
for pass in filters {
|
||||||
|
@ -296,7 +318,7 @@ impl FilterChain {
|
||||||
// not using frame history;
|
// not using frame history;
|
||||||
if required_images <= 1 {
|
if required_images <= 1 {
|
||||||
println!("[history] not using frame history");
|
println!("[history] not using frame history");
|
||||||
return (VecDeque::new(), Box::new([]));
|
return Ok((VecDeque::new(), Box::new([])));
|
||||||
}
|
}
|
||||||
|
|
||||||
// history0 is aliased with the original
|
// history0 is aliased with the original
|
||||||
|
@ -305,13 +327,15 @@ impl FilterChain {
|
||||||
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, context, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm)
|
||||||
.unwrap()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let framebuffers = framebuffers
|
||||||
|
.into_iter().collect::<util::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);
|
||||||
|
|
||||||
(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) -> util::Result<()> {
|
||||||
|
@ -325,8 +349,9 @@ impl FilterChain {
|
||||||
|
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
|
context: &ID3D11DeviceContext,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureConfig],
|
||||||
) -> util::Result<FxHashMap<usize, OwnedTexture>> {
|
) -> util::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() {
|
||||||
|
@ -345,7 +370,7 @@ impl FilterChain {
|
||||||
};
|
};
|
||||||
|
|
||||||
let texture =
|
let texture =
|
||||||
OwnedTexture::new(device, &image, desc, texture.filter_mode, texture.wrap_mode)?;
|
LutTexture::new(device, context,&image, desc, texture.filter_mode, texture.wrap_mode)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
|
@ -361,14 +386,15 @@ impl FilterChain {
|
||||||
Self::load_from_preset(device, preset)
|
Self::load_from_preset(device, preset)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_preset(preset: &ShaderPreset) -> util::Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
|
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();
|
||||||
|
|
||||||
let passes = preset
|
let passes = passes
|
||||||
.shaders
|
.into_iter()
|
||||||
.iter()
|
|
||||||
.map(|shader| {
|
.map(|shader| {
|
||||||
eprintln!("[dx11] loading {}", &shader.name.display());
|
eprintln!("[dx11] loading {}", &shader.name.display());
|
||||||
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
let source: ShaderSource = ShaderSource::load(&shader.name)?;
|
||||||
|
@ -385,21 +411,21 @@ impl FilterChain {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok::<_, Box<dyn Error>>((shader, source, reflect))
|
Ok::<_, FilterChainError>((shader, source, reflect))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<util::Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
.collect::<util::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for details in &passes {
|
for details in &passes {
|
||||||
librashader_runtime::semantics::insert_pass_semantics(
|
librashader_runtime::semantics::insert_pass_semantics(
|
||||||
&mut uniform_semantics,
|
&mut uniform_semantics,
|
||||||
&mut texture_semantics,
|
&mut texture_semantics,
|
||||||
details.0,
|
&details.0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
librashader_runtime::semantics::insert_lut_semantics(
|
librashader_runtime::semantics::insert_lut_semantics(
|
||||||
&preset.textures,
|
&textures,
|
||||||
&mut uniform_semantics,
|
&mut uniform_semantics,
|
||||||
&mut texture_semantics,
|
&mut texture_semantics,
|
||||||
);
|
);
|
||||||
|
@ -476,12 +502,12 @@ impl FilterChain {
|
||||||
viewport,
|
viewport,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
RenderTarget::new(target.as_output_framebuffer().unwrap(), None),
|
RenderTarget::new(target.as_output_framebuffer()?, None),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
source = Texture {
|
source = Texture {
|
||||||
view: DxImageView {
|
view: DxImageView {
|
||||||
handle: target.create_shader_resource_view().unwrap(),
|
handle: target.create_shader_resource_view()?,
|
||||||
size,
|
size,
|
||||||
},
|
},
|
||||||
filter,
|
filter,
|
||||||
|
|
|
@ -20,6 +20,7 @@ use windows::Win32::Graphics::Direct3D11::{
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
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,
|
||||||
|
@ -310,13 +311,7 @@ impl FilterPass {
|
||||||
.map(|f| f.initial)
|
.map(|f| f.initial)
|
||||||
.unwrap_or(0f32);
|
.unwrap_or(0f32);
|
||||||
|
|
||||||
let value = parent
|
let value = *parent.config.parameters.get(id).unwrap_or(&default);
|
||||||
.preset
|
|
||||||
.parameters
|
|
||||||
.iter()
|
|
||||||
.find(|&p| p.name == id)
|
|
||||||
.map(|p| p.value)
|
|
||||||
.unwrap_or(default);
|
|
||||||
|
|
||||||
self.uniform_storage.bind_scalar(*offset, value, None);
|
self.uniform_storage.bind_scalar(*offset, value, None);
|
||||||
}
|
}
|
||||||
|
@ -360,7 +355,7 @@ impl FilterPass {
|
||||||
original: &Texture,
|
original: &Texture,
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
output: RenderTarget,
|
output: RenderTarget,
|
||||||
) -> std::result::Result<(), Box<dyn Error>> {
|
) -> util::Result<()> {
|
||||||
let _device = &parent.d3d11.device;
|
let _device = &parent.d3d11.device;
|
||||||
let context = &parent.d3d11.device_context;
|
let context = &parent.d3d11.device_context;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -155,9 +155,10 @@ impl OwnedFramebuffer {
|
||||||
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);
|
||||||
|
let Some(resource) = resource else {
|
||||||
// todo: make panic-free
|
return Ok(())
|
||||||
resource.unwrap().cast()?
|
};
|
||||||
|
resource.cast()?
|
||||||
};
|
};
|
||||||
|
|
||||||
let format = unsafe {
|
let format = unsafe {
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
|
|
||||||
mod filter_chain;
|
|
||||||
|
|
||||||
mod filter_pass;
|
|
||||||
mod framebuffer;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
|
|
||||||
|
mod filter_chain;
|
||||||
|
mod filter_pass;
|
||||||
|
mod framebuffer;
|
||||||
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;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -1,48 +1,40 @@
|
||||||
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::{
|
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};
|
||||||
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,
|
|
||||||
};
|
|
||||||
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::util::Result;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DxImageView {
|
pub struct DxImageView {
|
||||||
pub handle: ID3D11ShaderResourceView,
|
pub handle: ID3D11ShaderResourceView,
|
||||||
pub size: Size<u32>, // pub image: GlImage,
|
pub size: Size<u32>,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
pub view: DxImageView,
|
pub view: DxImageView,
|
||||||
pub filter: FilterMode,
|
pub filter: FilterMode,
|
||||||
pub wrap_mode: WrapMode,
|
pub wrap_mode: WrapMode,
|
||||||
// pub mip_filter: FilterMode,
|
|
||||||
// pub wrap_mode: WrapMode,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OwnedTexture {
|
pub struct LutTexture {
|
||||||
pub handle: ID3D11Texture2D,
|
pub handle: ID3D11Texture2D,
|
||||||
// pub staging: ID3D11Texture2D,
|
|
||||||
pub desc: D3D11_TEXTURE2D_DESC,
|
pub desc: D3D11_TEXTURE2D_DESC,
|
||||||
pub image: Texture,
|
pub image: Texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedTexture {
|
impl LutTexture {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
|
context: &ID3D11DeviceContext,
|
||||||
source: &Image,
|
source: &Image,
|
||||||
desc: D3D11_TEXTURE2D_DESC,
|
desc: D3D11_TEXTURE2D_DESC,
|
||||||
filter: FilterMode,
|
filter: FilterMode,
|
||||||
wrap_mode: WrapMode,
|
wrap_mode: WrapMode,
|
||||||
) -> Result<OwnedTexture> {
|
) -> Result<LutTexture> {
|
||||||
let mut desc = D3D11_TEXTURE2D_DESC {
|
let mut desc = D3D11_TEXTURE2D_DESC {
|
||||||
Width: source.size.width,
|
Width: source.size.width,
|
||||||
Height: source.size.height,
|
Height: source.size.height,
|
||||||
|
@ -107,12 +99,6 @@ impl OwnedTexture {
|
||||||
}),
|
}),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut context = None;
|
|
||||||
device.GetImmediateContext(&mut context);
|
|
||||||
|
|
||||||
// todo: make this fallible
|
|
||||||
let context = context.unwrap();
|
|
||||||
|
|
||||||
// need a staging texture to defer mipmap generation
|
// need a staging texture to defer mipmap generation
|
||||||
let staging = device.CreateTexture2D(
|
let staging = device.CreateTexture2D(
|
||||||
&D3D11_TEXTURE2D_DESC {
|
&D3D11_TEXTURE2D_DESC {
|
||||||
|
@ -158,7 +144,7 @@ impl OwnedTexture {
|
||||||
// let mut subresource = context.Map(staging, 0, D3D11_MAP_WRITE, 0)?;
|
// let mut subresource = context.Map(staging, 0, D3D11_MAP_WRITE, 0)?;
|
||||||
// staging.Upd
|
// staging.Upd
|
||||||
|
|
||||||
Ok(OwnedTexture {
|
Ok(LutTexture {
|
||||||
handle,
|
handle,
|
||||||
// staging,
|
// staging,
|
||||||
desc,
|
desc,
|
||||||
|
|
|
@ -167,4 +167,4 @@ pub fn d3d11_create_input_layout(
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: d3d11.c 2097
|
// todo: d3d11.c 2097
|
||||||
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
pub type Result<T> = std::result::Result<T, crate::error::FilterChainError>;
|
||||||
|
|
|
@ -32,7 +32,6 @@ pub struct FilterPass<T: GLInterface> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GLInterface> FilterPass<T> {
|
impl<T: GLInterface> FilterPass<T> {
|
||||||
// todo: fix rendertargets (i.e. non-final pass is internal, final pass is user provided fbo)
|
|
||||||
pub(crate) fn draw(
|
pub(crate) fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_index: usize,
|
pass_index: usize,
|
||||||
|
|
|
@ -89,6 +89,11 @@ impl FramebufferInterface for Gl46Framebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn copy_from(fb: &mut Framebuffer, image: &GLImage) -> Result<()> {
|
fn copy_from(fb: &mut Framebuffer, image: &GLImage) -> Result<()> {
|
||||||
|
// todo: confirm this behaviour for unbound image.
|
||||||
|
if image.handle == 0 {
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// todo: may want to use a shader and draw a quad to be faster.
|
// todo: may want to use a shader and draw a quad to be faster.
|
||||||
if image.size != fb.size || image.format != fb.format {
|
if image.size != fb.size || image.format != fb.format {
|
||||||
Self::init(
|
Self::init(
|
||||||
|
|
Loading…
Reference in a new issue