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::error::{assume_d3d11_init, FilterChainError};
|
||||||
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
||||||
use crate::framebuffer::OwnedFramebuffer;
|
use crate::framebuffer::OwnedFramebuffer;
|
||||||
|
use crate::graphics_pipeline::D3D11State;
|
||||||
use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
|
use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
|
@ -45,10 +46,11 @@ type ShaderPassMeta =
|
||||||
/// A Direct3D 11 filter chain.
|
/// A Direct3D 11 filter chain.
|
||||||
pub struct FilterChainD3D11 {
|
pub struct FilterChainD3D11 {
|
||||||
pub(crate) common: FilterCommon,
|
pub(crate) common: FilterCommon,
|
||||||
pub(crate) passes: Vec<FilterPass>,
|
passes: Vec<FilterPass>,
|
||||||
pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>,
|
output_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
pub(crate) feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
||||||
pub(crate) history_framebuffers: VecDeque<OwnedFramebuffer>,
|
history_framebuffers: VecDeque<OwnedFramebuffer>,
|
||||||
|
state: D3D11State,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct Direct3D11 {
|
pub(crate) struct Direct3D11 {
|
||||||
|
@ -162,8 +164,7 @@ impl FilterChainD3D11 {
|
||||||
FilterChainD3D11::init_history(device, ¤t_context, &filters)?;
|
FilterChainD3D11::init_history(device, ¤t_context, &filters)?;
|
||||||
|
|
||||||
let draw_quad = DrawQuad::new(device, ¤t_context)?;
|
let draw_quad = DrawQuad::new(device, ¤t_context)?;
|
||||||
|
let state = D3D11State::new(device)?;
|
||||||
// todo: make vbo: d3d11.c 1376
|
|
||||||
Ok(FilterChainD3D11 {
|
Ok(FilterChainD3D11 {
|
||||||
passes: filters,
|
passes: filters,
|
||||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||||
|
@ -192,6 +193,7 @@ impl FilterChainD3D11 {
|
||||||
history_textures,
|
history_textures,
|
||||||
draw_quad,
|
draw_quad,
|
||||||
},
|
},
|
||||||
|
state,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -474,6 +476,9 @@ impl FilterChainD3D11 {
|
||||||
let passes_len = passes.len();
|
let passes_len = passes.len();
|
||||||
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
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();
|
self.common.draw_quad.bind_vbo_for_frame();
|
||||||
|
|
||||||
for (index, pass) in pass.iter_mut().enumerate() {
|
for (index, pass) in pass.iter_mut().enumerate() {
|
||||||
|
@ -535,6 +540,7 @@ impl FilterChainD3D11 {
|
||||||
&mut self.feedback_framebuffers,
|
&mut self.feedback_framebuffers,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
drop(state_guard);
|
||||||
self.push_history(&input)?;
|
self.push_history(&input)?;
|
||||||
|
|
||||||
if self.common.d3d11.context_is_deferred {
|
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::{
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView,
|
ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView,
|
||||||
ID3D11Texture2D, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX,
|
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_FORMAT_SUPPORT_TEXTURE2D, D3D11_RENDER_TARGET_VIEW_DESC, D3D11_RENDER_TARGET_VIEW_DESC_0,
|
||||||
D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_RTV_DIMENSION_TEXTURE2D,
|
D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_RTV,
|
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_chain;
|
||||||
mod filter_pass;
|
mod filter_pass;
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
|
mod graphics_pipeline;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
mod parameters;
|
mod parameters;
|
||||||
mod render_target;
|
mod render_target;
|
||||||
|
@ -35,11 +36,11 @@ mod tests {
|
||||||
// "../test/slang-shaders/scalefx/scalefx-9x.slangp",
|
// "../test/slang-shaders/scalefx/scalefx-9x.slangp",
|
||||||
// "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp",
|
// "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp",
|
||||||
// "../test/slang-shaders/presets/crt-geom-ntsc-upscale-sharp.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",
|
// "../test/null.slangp",
|
||||||
// const FILTER_PATH: &str = "../test/slang-shaders/scalefx/scalefx-9x.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";
|
const IMAGE_PATH: &str = "../test/finalfightlong.png";
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn triangle_d3d11_args() {
|
// fn triangle_d3d11_args() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue