d3d11: set and restore blend state between passes and disable unneeded CPU access write
This commit is contained in:
parent
c5b2b50d16
commit
5ffcf005a0
4 changed files with 137 additions and 9 deletions
|
@ -17,6 +17,7 @@ use crate::draw_quad::DrawQuad;
|
|||
use crate::error::{assume_d3d11_init, FilterChainError};
|
||||
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
||||
use crate::framebuffer::OwnedFramebuffer;
|
||||
use crate::graphics_pipeline::D3D11State;
|
||||
use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::samplers::SamplerSet;
|
||||
|
@ -45,10 +46,11 @@ type ShaderPassMeta =
|
|||
/// A Direct3D 11 filter chain.
|
||||
pub struct FilterChainD3D11 {
|
||||
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>,
|
||||
passes: Vec<FilterPass>,
|
||||
output_framebuffers: Box<[OwnedFramebuffer]>,
|
||||
feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
||||
history_framebuffers: VecDeque<OwnedFramebuffer>,
|
||||
state: D3D11State,
|
||||
}
|
||||
|
||||
pub(crate) struct Direct3D11 {
|
||||
|
@ -162,8 +164,7 @@ impl FilterChainD3D11 {
|
|||
FilterChainD3D11::init_history(device, ¤t_context, &filters)?;
|
||||
|
||||
let draw_quad = DrawQuad::new(device, ¤t_context)?;
|
||||
|
||||
// todo: make vbo: d3d11.c 1376
|
||||
let state = D3D11State::new(device)?;
|
||||
Ok(FilterChainD3D11 {
|
||||
passes: filters,
|
||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
|
@ -192,6 +193,7 @@ impl FilterChainD3D11 {
|
|||
history_textures,
|
||||
draw_quad,
|
||||
},
|
||||
state,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -474,6 +476,9 @@ impl FilterChainD3D11 {
|
|||
let passes_len = passes.len();
|
||||
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
||||
|
||||
let state_guard = self
|
||||
.state
|
||||
.enter_filter_state(&self.common.d3d11.current_context);
|
||||
self.common.draw_quad.bind_vbo_for_frame();
|
||||
|
||||
for (index, pass) in pass.iter_mut().enumerate() {
|
||||
|
@ -535,6 +540,7 @@ impl FilterChainD3D11 {
|
|||
&mut self.feedback_framebuffers,
|
||||
);
|
||||
|
||||
drop(state_guard);
|
||||
self.push_history(&input)?;
|
||||
|
||||
if self.common.d3d11.context_is_deferred {
|
||||
|
|
|
@ -10,7 +10,7 @@ use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
|||
use windows::Win32::Graphics::Direct3D11::{
|
||||
ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView,
|
||||
ID3D11Texture2D, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX,
|
||||
D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE,
|
||||
D3D11_CPU_ACCESS_FLAG, 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_RESOURCE_MISC_GENERATE_MIPS, D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_RTV,
|
||||
|
|
121
librashader-runtime-d3d11/src/graphics_pipeline.rs
Normal file
121
librashader-runtime-d3d11/src/graphics_pipeline.rs
Normal file
|
@ -0,0 +1,121 @@
|
|||
use crate::error;
|
||||
use crate::error::assume_d3d11_init;
|
||||
use windows::Win32::Foundation::BOOL;
|
||||
use windows::Win32::Graphics::Direct3D11::{
|
||||
ID3D11BlendState, ID3D11Device, ID3D11DeviceContext, ID3D11RasterizerState, D3D11_BLEND_DESC,
|
||||
D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_ONE, D3D11_BLEND_OP_ADD, D3D11_BLEND_SRC_ALPHA,
|
||||
D3D11_COLOR_WRITE_ENABLE_ALL, D3D11_CULL_NONE, D3D11_DEFAULT_SAMPLE_MASK, D3D11_FILL_SOLID,
|
||||
D3D11_RASTERIZER_DESC, D3D11_RENDER_TARGET_BLEND_DESC,
|
||||
};
|
||||
|
||||
pub struct D3D11State {
|
||||
blend: ID3D11BlendState,
|
||||
rs: ID3D11RasterizerState,
|
||||
}
|
||||
|
||||
pub struct D3D11StateSaveGuard<'a> {
|
||||
ctx: &'a ID3D11DeviceContext,
|
||||
saved_blend: Option<ID3D11BlendState>,
|
||||
saved_blend_factor: [f32; 4],
|
||||
saved_blend_mask: u32,
|
||||
saved_rs: Option<ID3D11RasterizerState>,
|
||||
state: &'a D3D11State,
|
||||
}
|
||||
|
||||
impl D3D11State {
|
||||
pub fn new(device: &ID3D11Device) -> error::Result<D3D11State> {
|
||||
let blend = unsafe {
|
||||
let mut blend_desc = D3D11_BLEND_DESC {
|
||||
AlphaToCoverageEnable: BOOL::from(false),
|
||||
IndependentBlendEnable: BOOL::from(false),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let rtv_blend_desc = D3D11_RENDER_TARGET_BLEND_DESC {
|
||||
BlendEnable: BOOL::from(false),
|
||||
SrcBlend: D3D11_BLEND_ONE,
|
||||
DestBlend: D3D11_BLEND_ONE,
|
||||
BlendOp: D3D11_BLEND_OP_ADD,
|
||||
SrcBlendAlpha: D3D11_BLEND_SRC_ALPHA,
|
||||
DestBlendAlpha: D3D11_BLEND_INV_SRC_ALPHA,
|
||||
BlendOpAlpha: D3D11_BLEND_OP_ADD,
|
||||
RenderTargetWriteMask: D3D11_COLOR_WRITE_ENABLE_ALL.0 as u8,
|
||||
};
|
||||
|
||||
blend_desc.RenderTarget[0] = rtv_blend_desc;
|
||||
|
||||
let mut blend = None;
|
||||
device.CreateBlendState(&blend_desc, Some(&mut blend))?;
|
||||
assume_d3d11_init!(blend, "CreateBlendState");
|
||||
blend
|
||||
};
|
||||
|
||||
let rs = unsafe {
|
||||
let rs_desc = D3D11_RASTERIZER_DESC {
|
||||
FillMode: D3D11_FILL_SOLID,
|
||||
CullMode: D3D11_CULL_NONE,
|
||||
FrontCounterClockwise: BOOL::from(false),
|
||||
DepthBias: 0,
|
||||
DepthBiasClamp: 0.0,
|
||||
SlopeScaledDepthBias: 0.0,
|
||||
DepthClipEnable: BOOL::from(false),
|
||||
ScissorEnable: BOOL::from(false),
|
||||
MultisampleEnable: BOOL::from(false),
|
||||
AntialiasedLineEnable: BOOL::from(false),
|
||||
};
|
||||
let mut rs = None;
|
||||
device.CreateRasterizerState(&rs_desc, Some(&mut rs))?;
|
||||
assume_d3d11_init!(rs, "CreateRasterizerState");
|
||||
rs
|
||||
};
|
||||
|
||||
Ok(D3D11State { blend, rs })
|
||||
}
|
||||
|
||||
/// Enters the state necessary for rendering filter passes.
|
||||
pub fn enter_filter_state<'a>(
|
||||
&'a self,
|
||||
context: &'a ID3D11DeviceContext,
|
||||
) -> D3D11StateSaveGuard<'a> {
|
||||
// save previous state
|
||||
let guard = unsafe {
|
||||
let mut saved_blend = None;
|
||||
let mut saved_blend_factor = [0f32; 4];
|
||||
let mut saved_blend_mask = 0;
|
||||
context.OMGetBlendState(
|
||||
Some(&mut saved_blend),
|
||||
Some(saved_blend_factor.as_mut_ptr()),
|
||||
Some(&mut saved_blend_mask),
|
||||
);
|
||||
let saved_rs = context.RSGetState().ok();
|
||||
|
||||
D3D11StateSaveGuard {
|
||||
ctx: &context,
|
||||
saved_blend,
|
||||
saved_blend_factor,
|
||||
saved_blend_mask,
|
||||
saved_rs,
|
||||
state: &self,
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
context.RSSetState(&self.rs);
|
||||
context.OMSetBlendState(&self.blend, None, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
guard
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for D3D11StateSaveGuard<'_> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.ctx.RSSetState(self.saved_rs.as_ref());
|
||||
self.ctx.OMSetBlendState(
|
||||
self.saved_blend.as_ref(),
|
||||
Some(self.saved_blend_factor.as_ptr()),
|
||||
self.saved_blend_mask,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ pub mod error;
|
|||
mod filter_chain;
|
||||
mod filter_pass;
|
||||
mod framebuffer;
|
||||
mod graphics_pipeline;
|
||||
pub mod options;
|
||||
mod parameters;
|
||||
mod render_target;
|
||||
|
@ -35,11 +36,11 @@ mod tests {
|
|||
// "../test/slang-shaders/scalefx/scalefx-9x.slangp",
|
||||
// "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp",
|
||||
// "../test/slang-shaders/presets/crt-geom-ntsc-upscale-sharp.slangp",
|
||||
const FILTER_PATH: &str = "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
|
||||
// const FILTER_PATH: &str = "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
|
||||
// "../test/null.slangp",
|
||||
// const FILTER_PATH: &str = "../test/slang-shaders/scalefx/scalefx-9x.slangp";
|
||||
|
||||
// const FILTER_PATH: &str = "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
|
||||
const FILTER_PATH: &str = "../test/slang-shaders/crt/zfast-crt.slangp";
|
||||
const IMAGE_PATH: &str = "../test/finalfightlong.png";
|
||||
// #[test]
|
||||
// fn triangle_d3d11_args() {
|
||||
|
|
Loading…
Add table
Reference in a new issue