d3d11: cleanup error and api

This commit is contained in:
chyyran 2022-11-30 19:05:12 -05:00
parent 6519a78df2
commit 873814b03b
15 changed files with 316 additions and 240 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@
/target
*.rdc
*.cap
/.vs/

View file

@ -84,8 +84,6 @@ fn from_int(input: Span) -> Result<i32, ParsePresetError> {
col: input.get_column(),
kind: ParseErrorKind::Int,
})?;
eprintln!("falling back to float trunc {result}");
Ok(result)
})
}

View file

@ -23,3 +23,5 @@ pub enum FilterChainError {
#[error("lut loading error")]
LutLoadError(#[from] ImageError),
}
pub type Result<T> = std::result::Result<T, FilterChainError>;

View file

@ -14,24 +14,26 @@ use librashader_reflect::reflect::semantics::{
use librashader_reflect::reflect::ReflectShader;
use rustc_hash::FxHashMap;
use std::collections::VecDeque;
use std::error::Error;
use std::path::Path;
use crate::error::FilterChainError;
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::render_target::RenderTarget;
use crate::samplers::SamplerSet;
use crate::util;
use crate::util::d3d11_compile_bound_shader;
use crate::viewport::Viewport;
use crate::{error, util};
use librashader_runtime::uniforms::UniformStorage;
use windows::Win32::Graphics::Direct3D11::{
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC,
D3D11_CPU_ACCESS_WRITE, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS,
D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC,
};
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_R8G8B8A8_UNORM};
use crate::error::FilterChainError;
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R8G8B8A8_UNORM;
pub struct FilterMutable {
pub(crate) passes_enabled: usize,
@ -48,18 +50,19 @@ type ShaderPassMeta = (
);
pub struct FilterChain {
pub common: FilterCommon,
pub passes: Vec<FilterPass>,
pub output_framebuffers: Box<[OwnedFramebuffer]>,
pub feedback_framebuffers: Box<[OwnedFramebuffer]>,
pub history_framebuffers: VecDeque<OwnedFramebuffer>,
pub(crate) common: FilterCommon,
pub(crate) passes: Vec<FilterPass>,
pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>,
pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>,
pub(crate) history_framebuffers: VecDeque<OwnedFramebuffer>,
pub(crate) draw_quad: DrawQuad,
}
pub struct Direct3D11 {
pub(crate) struct Direct3D11 {
pub(crate) device: ID3D11Device,
pub(crate) device_context: ID3D11DeviceContext,
pub context_is_deferred: bool
pub(crate) current_context: ID3D11DeviceContext,
pub(crate) immediate_context: ID3D11DeviceContext,
pub context_is_deferred: bool,
}
pub struct FilterCommon {
@ -69,11 +72,128 @@ pub struct FilterCommon {
pub output_textures: Box<[Option<Texture>]>,
pub feedback_textures: Box<[Option<Texture>]>,
pub history_textures: Box<[Option<Texture>]>,
pub config: FilterMutable
pub config: FilterMutable,
}
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, &current_context, &preset.textures)?;
let (history_framebuffers, history_textures) =
FilterChain::init_history(device, &filters)?;
let draw_quad = DrawQuad::new(device, &current_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 {
let buffer = device.CreateBuffer(
&D3D11_BUFFER_DESC {
@ -95,7 +215,7 @@ impl FilterChain {
device: &ID3D11Device,
passes: Vec<ShaderPassMeta>,
semantics: &ReflectSemantics,
) -> util::Result<Vec<FilterPass>> {
) -> error::Result<Vec<FilterPass>> {
// let mut filters = Vec::new();
let mut filters = Vec::new();
@ -190,108 +310,11 @@ impl FilterChain {
}
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(
device: &ID3D11Device,
context: &ID3D11DeviceContext,
filters: &[FilterPass],
) -> util::Result<(VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>)> {
) -> error::Result<(VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>)> {
let mut required_images = 0;
for pass in filters {
@ -326,11 +349,12 @@ impl FilterChain {
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)
OwnedFramebuffer::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm)
});
let framebuffers = framebuffers
.into_iter().collect::<util::Result<VecDeque<OwnedFramebuffer>>>()?;
.into_iter()
.collect::<error::Result<VecDeque<OwnedFramebuffer>>>()?;
let mut history_textures = Vec::new();
history_textures.resize_with(required_images, || None);
@ -338,9 +362,9 @@ impl FilterChain {
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() {
back.copy_from(&input)?;
back.copy_from(input)?;
self.history_framebuffers.push_front(back)
}
@ -351,7 +375,7 @@ impl FilterChain {
device: &ID3D11Device,
context: &ID3D11DeviceContext,
textures: &[TextureConfig],
) -> util::Result<FxHashMap<usize, LutTexture>> {
) -> error::Result<FxHashMap<usize, LutTexture>> {
let mut luts = FxHashMap::default();
for (index, texture) in textures.iter().enumerate() {
@ -369,26 +393,23 @@ impl FilterChain {
..Default::default()
};
let texture =
LutTexture::new(device, context,&image, desc, texture.filter_mode, texture.wrap_mode)?;
let texture = LutTexture::new(
device,
context,
&image,
desc,
texture.filter_mode,
texture.wrap_mode,
)?;
luts.insert(index, texture);
}
Ok(luts)
}
/// Load the shader preset at the given path into a filter chain.
pub fn load_from_path(
device: &ID3D11Device,
path: impl AsRef<Path>,
) -> 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)> {
fn load_preset(
passes: Vec<ShaderPassConfig>,
textures: &[TextureConfig],
) -> error::Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
Default::default();
@ -414,7 +435,7 @@ impl FilterChain {
Ok::<_, FilterChainError>((shader, source, reflect))
})
.into_iter()
.collect::<util::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
)?;
for details in &passes {
@ -425,7 +446,7 @@ impl FilterChain {
)
}
librashader_runtime::semantics::insert_lut_semantics(
&textures,
textures,
&mut uniform_semantics,
&mut texture_semantics,
);
@ -440,12 +461,19 @@ impl FilterChain {
pub fn frame(
&mut self,
count: usize,
viewport: &Size<u32>,
input: DxImageView,
output: OutputFramebuffer,
) -> util::Result<()> {
let passes = &mut self.passes;
viewport: &Viewport,
frame_count: usize,
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() {
return Ok(());
@ -469,7 +497,7 @@ impl FilterChain {
self.output_framebuffers[index].scale(
pass.config.scaling.clone(),
pass.get_format(),
viewport,
&viewport.size,
&original,
&source,
)?;
@ -477,7 +505,7 @@ impl FilterChain {
self.feedback_framebuffers[index].scale(
pass.config.scaling.clone(),
pass.get_format(),
viewport,
&viewport.size,
&original,
&source,
)?;
@ -494,9 +522,9 @@ impl FilterChain {
index,
&self.common,
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 {
count
frame_count
} as u32,
1,
viewport,
@ -523,15 +551,15 @@ impl FilterChain {
passes_len - 1,
&self.common,
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 {
count
frame_count
} as u32,
1,
viewport,
&original,
&source,
RenderTarget::new(output, None),
viewport.into(),
)?;
// diverge so we don't need to clone output.
@ -549,12 +577,14 @@ impl FilterChain {
self.push_history(&input)?;
unsafe {
let list = self.common.d3d11.device_context.FinishCommandList(false)?;
let mut imm = None;
self.common.d3d11.device.GetImmediateContext(&mut imm);
let imm = imm.unwrap();
imm.ExecuteCommandList(&list, true);
if self.common.d3d11.context_is_deferred {
unsafe {
let command_list = self.common.d3d11.current_context.FinishCommandList(false)?;
self.common
.d3d11
.immediate_context
.ExecuteCommandList(&command_list, true);
}
}
Ok(())

View file

@ -10,17 +10,17 @@ use librashader_reflect::reflect::semantics::{
};
use librashader_reflect::reflect::ShaderReflection;
use rustc_hash::FxHashMap;
use std::error::Error;
use windows::Win32::Graphics::Direct3D11::{
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD,
};
use crate::error;
use crate::render_target::RenderTarget;
use crate::samplers::SamplerSet;
use crate::viewport::Viewport;
use librashader_runtime::uniforms::UniformStorage;
use crate::util;
pub struct ConstantBufferBinding {
pub binding: u32,
@ -301,8 +301,6 @@ impl FilterPass {
{
let id = id.as_str();
// todo: cache parameters.
// presets override params
let default = self
.source
.parameters
@ -345,19 +343,19 @@ impl FilterPass {
(textures, samplers)
}
pub fn draw(
pub(crate) fn draw(
&mut self,
pass_index: usize,
parent: &FilterCommon,
frame_count: u32,
frame_direction: i32,
viewport: &Size<u32>,
viewport: &Viewport,
original: &Texture,
source: &Texture,
output: RenderTarget,
) -> util::Result<()> {
) -> error::Result<()> {
let _device = &parent.d3d11.device;
let context = &parent.d3d11.device_context;
let context = &parent.d3d11.current_context;
unsafe {
context.IASetInputLayout(&self.vertex_layout);
context.VSSetShader(&self.vertex_shader, None);
@ -371,7 +369,7 @@ impl FilterPass {
frame_count,
frame_direction,
output.output.size,
*viewport,
viewport.size,
original,
source,
);

View file

@ -1,14 +1,13 @@
use windows::core::Interface;
use crate::error;
use crate::texture::{DxImageView, Texture};
use crate::util;
use crate::util::d3d11_get_closest_format;
use librashader_common::{ImageFormat, Size};
use librashader_presets::Scale2D;
use windows::core::Interface;
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
use windows::Win32::Graphics::Direct3D11::{
ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11Resource,
ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_RENDER_TARGET,
D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_WRITE,
ID3D11Device, ID3D11RenderTargetView, ID3D11ShaderResourceView,
ID3D11Texture2D, 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,
@ -18,22 +17,20 @@ use windows::Win32::Graphics::Direct3D11::{
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
#[derive(Debug, Clone)]
pub struct OwnedFramebuffer {
pub(crate) struct OwnedFramebuffer {
pub texture: ID3D11Texture2D,
pub size: Size<u32>,
pub format: DXGI_FORMAT,
device: ID3D11Device,
context: ID3D11DeviceContext,
is_raw: bool,
}
impl OwnedFramebuffer {
pub fn new(
device: &ID3D11Device,
context: &ID3D11DeviceContext,
size: Size<u32>,
format: ImageFormat,
) -> util::Result<OwnedFramebuffer> {
) -> error::Result<OwnedFramebuffer> {
unsafe {
let format = d3d11_get_closest_format(
device,
@ -50,7 +47,6 @@ impl OwnedFramebuffer {
size,
format,
device: device.clone(),
context: context.clone(),
is_raw: false,
})
}
@ -63,7 +59,7 @@ impl OwnedFramebuffer {
viewport_size: &Size<u32>,
_original: &Texture,
source: &Texture,
) -> util::Result<Size<u32>> {
) -> error::Result<Size<u32>> {
if self.is_raw {
return Ok(self.size);
}
@ -85,7 +81,7 @@ impl OwnedFramebuffer {
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 {
return Ok(());
}
@ -110,7 +106,7 @@ impl OwnedFramebuffer {
Ok(())
}
pub fn create_shader_resource_view(&self) -> util::Result<ID3D11ShaderResourceView> {
pub fn create_shader_resource_view(&self) -> error::Result<ID3D11ShaderResourceView> {
unsafe {
Ok(self.device.CreateShaderResourceView(
&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 {
Ok(self.device.CreateRenderTargetView(
&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 {
rtv: self.create_render_target_view()?,
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 mut resource = None;
image.handle.GetResource(&mut resource);
@ -172,12 +168,12 @@ impl OwnedFramebuffer {
self.init(image.size, ImageFormat::from(format))?;
}
self.texture = resource.clone();
self.texture = resource;
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct OutputFramebuffer {
pub(crate) struct OutputFramebuffer {
pub rtv: ID3D11RenderTargetView,
pub size: Size<u32>,
pub viewport: D3D11_VIEWPORT,

View file

@ -225,14 +225,14 @@ pub mod d3d11_hello_triangle {
use std::path::Path;
use crate::filter_chain::FilterChain;
use crate::framebuffer::OutputFramebuffer;
use crate::options::FilterChainOptions;
use crate::texture::DxImageView;
use crate::viewport::Viewport;
use librashader_common::Size;
use std::slice;
use std::time::Instant;
const FRAME_COUNT: u32 = 2;
pub struct Sample {
pub dxgi_factory: IDXGIFactory4,
pub device: ID3D11Device,
@ -263,9 +263,12 @@ pub mod d3d11_hello_triangle {
}
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 filter = FilterChain::load_from_path(&device, filter).unwrap();
let filter = FilterChain::load_from_path(&device, filter, filter_options).unwrap();
Ok(Sample {
filter,
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
.frame(
resources.frame_count,
&Size {
width: tex2d_desc.Width,
height: tex2d_desc.Height,
},
DxImageView {
handle: srv,
size: Size {
@ -484,22 +498,18 @@ pub mod d3d11_hello_triangle {
height: tex2d_desc.Height,
},
},
OutputFramebuffer {
rtv: resources.rtv.clone(),
// rtv,
&Viewport {
x: resources.viewport.TopLeftX,
y: resources.viewport.TopLeftY,
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,
// },
output: resources.rtv.clone(),
mvp: None,
},
resources.frame_count,
None,
)
.unwrap();
@ -705,13 +715,7 @@ pub mod d3d11_hello_triangle {
}
}
fn create_device() -> Result<(IDXGIFactory4, ID3D11Device, ID3D11DeviceContext)> {
let dxgi_factory_flags = if cfg!(debug_assertions) {
DXGI_CREATE_FACTORY_DEBUG
} else {
DXGI_CREATE_FACTORY_DEBUG
};
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(dxgi_factory_flags) }?;
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG) }?;
let feature_levels = vec![D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1];
let mut out_device = None;

View file

@ -4,15 +4,17 @@
#[cfg(test)]
mod hello_triangle;
pub mod error;
mod filter_chain;
mod filter_pass;
mod framebuffer;
pub mod options;
mod quad_render;
mod render_target;
mod samplers;
mod texture;
mod util;
pub mod error;
mod viewport;
#[cfg(test)]
mod tests {
@ -21,11 +23,18 @@ mod tests {
#[test]
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/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
"../test/slang-shaders/crt/crt-royale.slangp",
None,
)
.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();

View 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,
}

View file

@ -1,4 +1,4 @@
use crate::util;
use crate::error;
use bytemuck::offset_of;
use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
@ -50,7 +50,7 @@ pub(crate) struct DrawQuad {
}
impl DrawQuad {
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> util::Result<DrawQuad> {
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> error::Result<DrawQuad> {
unsafe {
let buffer = device.CreateBuffer(
&D3D11_BUFFER_DESC {

View file

@ -1,4 +1,6 @@
use crate::framebuffer::OutputFramebuffer;
use crate::viewport::Viewport;
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;
#[rustfmt::skip]
static DEFAULT_MVP: &[f32; 16] = &[
@ -9,7 +11,7 @@ static DEFAULT_MVP: &[f32; 16] = &[
];
#[derive(Debug, Clone)]
pub struct RenderTarget<'a> {
pub(crate) struct RenderTarget<'a> {
pub mvp: &'a [f32; 16],
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,
)
}
}

View file

@ -1,4 +1,4 @@
use crate::util::Result;
use crate::error::Result;
use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap;
use windows::Win32::Graphics::Direct3D11::{

View file

@ -1,11 +1,16 @@
use librashader_common::image::Image;
use librashader_common::{FilterMode, Size, WrapMode};
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 crate::filter_chain::Direct3D11;
use crate::util::Result;
use crate::error::Result;
#[derive(Debug, Clone)]
pub struct DxImageView {
@ -71,16 +76,8 @@ impl LutTexture {
}
}
// determine if format is supported.
// bruh why does D3D11_FORMAT_SUPPORT not implement bitor???
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);
// Don't need to determine format support because LUTs are always DXGI_FORMAT_R8G8B8A8_UNORM
// since we load them with the Image module.
unsafe {
let handle = device.CreateTexture2D(&desc, None).unwrap();

View file

@ -1,4 +1,4 @@
use std::error::Error;
use crate::error;
use std::slice;
use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::Fxc::{
@ -104,7 +104,7 @@ pub fn d3d11_get_closest_format(
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 {
let mut blob = None;
D3DCompile(
@ -115,7 +115,7 @@ pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result
None,
PCSTR(entry.as_ptr()),
PCSTR(version.as_ptr()),
if cfg!(debug_assertions) {
if cfg!(feature = "debug-shader") {
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
} else {
0
@ -137,7 +137,7 @@ pub fn d3d11_compile_bound_shader<'a, T, L>(
blob: &ID3DBlob,
linkage: L,
factory: ShaderFactory<'a, L, T>,
) -> Result<T>
) -> error::Result<T>
where
L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>,
{
@ -155,7 +155,7 @@ pub fn d3d11_create_input_layout(
device: &ID3D11Device,
desc: &[D3D11_INPUT_ELEMENT_DESC],
blob: &ID3DBlob,
) -> Result<ID3D11InputLayout> {
) -> error::Result<ID3D11InputLayout> {
unsafe {
// SAFETY: slice as valid for as long as vs_blob is alive.
let dxil =
@ -165,6 +165,3 @@ pub fn d3d11_create_input_layout(
Ok(compiled)
}
}
// todo: d3d11.c 2097
pub type Result<T> = std::result::Result<T, crate::error::FilterChainError>;

View 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]>,
}