Skip to content

Commit

Permalink
d3d11: set and restore blend state between passes and disable unneede…
Browse files Browse the repository at this point in the history
…d CPU access write
  • Loading branch information
chyyran committed Feb 7, 2023
1 parent c5b2b50 commit 5ffcf00
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 9 deletions.
18 changes: 12 additions & 6 deletions librashader-runtime-d3d11/src/filter_chain.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -162,8 +164,7 @@ impl FilterChainD3D11 {
FilterChainD3D11::init_history(device, &current_context, &filters)?;

let draw_quad = DrawQuad::new(device, &current_context)?;

// todo: make vbo: d3d11.c 1376
let state = D3D11State::new(device)?;
Ok(FilterChainD3D11 {
passes: filters,
output_framebuffers: output_framebuffers.into_boxed_slice(),
Expand Down Expand Up @@ -192,6 +193,7 @@ impl FilterChainD3D11 {
history_textures,
draw_quad,
},
state,
})
}
}
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -535,6 +540,7 @@ impl FilterChainD3D11 {
&mut self.feedback_framebuffers,
);

drop(state_guard);
self.push_history(&input)?;

if self.common.d3d11.context_is_deferred {
Expand Down
2 changes: 1 addition & 1 deletion librashader-runtime-d3d11/src/framebuffer.rs
Expand Up @@ -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,
Expand Down
121 changes: 121 additions & 0 deletions librashader-runtime-d3d11/src/graphics_pipeline.rs
@@ -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,
);
}
}
}
5 changes: 3 additions & 2 deletions librashader-runtime-d3d11/src/lib.rs
Expand Up @@ -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;
Expand All @@ -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() {
Expand Down

0 comments on commit 5ffcf00

Please sign in to comment.