Skip to content

Commit

Permalink
rt: fix history framebuffer requirements and unify framebuffer initia…
Browse files Browse the repository at this point in the history
…lization logic
  • Loading branch information
chyyran committed Feb 11, 2023
1 parent 115382d commit 3c15a3a
Show file tree
Hide file tree
Showing 25 changed files with 342 additions and 369 deletions.
129 changes: 45 additions & 84 deletions librashader-runtime-d3d11/src/filter_chain.rs
Expand Up @@ -5,7 +5,7 @@ use librashader_presets::{ShaderPreset, TextureConfig};
use librashader_reflect::back::targets::HLSL;
use librashader_reflect::back::{CompileReflectShader, CompileShader};
use librashader_reflect::front::GlslangCompilation;
use librashader_reflect::reflect::semantics::{BindingMeta, ShaderSemantics};
use librashader_reflect::reflect::semantics::ShaderSemantics;
use librashader_reflect::reflect::ReflectShader;
use librashader_runtime::image::{Image, UVDirection};
use rustc_hash::FxHashMap;
Expand All @@ -16,14 +16,15 @@ use std::path::Path;
use crate::draw_quad::DrawQuad;
use crate::error::{assume_d3d11_init, FilterChainError};
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
use crate::framebuffer::OwnedFramebuffer;
use crate::framebuffer::OwnedImage;
use crate::graphics_pipeline::D3D11State;
use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
use crate::samplers::SamplerSet;
use crate::util::d3d11_compile_bound_shader;
use crate::{error, util, D3D11OutputView};
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
use librashader_runtime::binding::{BindingUtil, TextureInput};
use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::quad::QuadType;
use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::scaling::ScaleFramebuffer;
Expand All @@ -49,9 +50,9 @@ type ShaderPassMeta =
pub struct FilterChainD3D11 {
pub(crate) common: FilterCommon,
passes: Vec<FilterPass>,
output_framebuffers: Box<[OwnedFramebuffer]>,
feedback_framebuffers: Box<[OwnedFramebuffer]>,
history_framebuffers: VecDeque<OwnedFramebuffer>,
output_framebuffers: Box<[OwnedImage]>,
feedback_framebuffers: Box<[OwnedImage]>,
history_framebuffers: VecDeque<OwnedImage>,
state: D3D11State,
}

Expand Down Expand Up @@ -102,45 +103,34 @@ impl FilterChainD3D11 {

let immediate_context = unsafe { device.GetImmediateContext()? };

// initialize output framebuffers
let mut output_framebuffers = Vec::new();
output_framebuffers.resize_with(filters.len(), || {
OwnedFramebuffer::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false)
});

// 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, false)
});
// 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 = FilterChainD3D11::load_luts(device, &immediate_context, &preset.textures)?;

let (history_framebuffers, history_textures) =
FilterChainD3D11::init_history(device, &filters)?;
let framebuffer_gen =
|| OwnedImage::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false);
let input_gen = || None;
let framebuffer_init = FramebufferInit::new(
filters.iter().map(|f| &f.reflection.meta),
&framebuffer_gen,
&input_gen,
);

// initialize output framebuffers
let (output_framebuffers, output_textures) = framebuffer_init.init_output_framebuffers()?;

// initialize feedback framebuffers
let (feedback_framebuffers, feedback_textures) =
framebuffer_init.init_output_framebuffers()?;

// initialize history
let (history_framebuffers, history_textures) = framebuffer_init.init_history()?;

let draw_quad = DrawQuad::new(device)?;
let state = D3D11State::new(device)?;
Ok(FilterChainD3D11 {
passes: filters,
output_framebuffers: output_framebuffers.into_boxed_slice(),
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
output_framebuffers,
feedback_framebuffers,
history_framebuffers,
common: FilterCommon {
d3d11: Direct3D11 {
Expand All @@ -158,8 +148,8 @@ impl FilterChainD3D11 {
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
luts,
samplers,
output_textures: output_textures.into_boxed_slice(),
feedback_textures: feedback_textures.into_boxed_slice(),
output_textures,
feedback_textures,
history_textures,
draw_quad,
},
Expand Down Expand Up @@ -283,37 +273,6 @@ impl FilterChainD3D11 {
Ok(filters)
}

fn init_history(
device: &ID3D11Device,
filters: &Vec<FilterPass>,
) -> error::Result<(VecDeque<OwnedFramebuffer>, Box<[Option<InputTexture>]>)> {
let required_images =
BindingMeta::calculate_required_history(filters.iter().map(|f| &f.reflection.meta));

// not using frame history;
if required_images <= 1 {
// println!("[history] not using frame history");
return Ok((VecDeque::new(), Box::new([])));
}

// history0 is aliased with the original

// 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, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false)
});

let framebuffers = framebuffers
.into_iter()
.collect::<error::Result<VecDeque<OwnedFramebuffer>>>()?;

let mut history_textures = Vec::new();
history_textures.resize_with(required_images, || None);

Ok((framebuffers, history_textures.into_boxed_slice()))
}

fn push_history(
&mut self,
ctx: &ID3D11DeviceContext,
Expand Down Expand Up @@ -394,20 +353,6 @@ impl FilterChainD3D11 {
let filter = passes[0].config.filter;
let wrap_mode = passes[0].config.wrap_mode;

for ((texture, fbo), pass) in self
.common
.feedback_textures
.iter_mut()
.zip(self.feedback_framebuffers.iter())
.zip(passes.iter())
{
*texture = Some(InputTexture::from_framebuffer(
fbo,
pass.config.wrap_mode,
pass.config.filter,
)?);
}

for (texture, fbo) in self
.common
.history_textures
Expand All @@ -426,7 +371,7 @@ impl FilterChainD3D11 {
let mut source = original.clone();

// rescale render buffers to ensure all bindings are valid.
OwnedFramebuffer::scale_framebuffers(
OwnedImage::scale_framebuffers(
source.size(),
viewport.output.size,
&mut self.output_framebuffers,
Expand All @@ -435,6 +380,22 @@ impl FilterChainD3D11 {
None,
)?;

// Refresh inputs for feedback textures.
// Don't need to do this for outputs because they are yet to be bound.
for ((texture, fbo), pass) in self
.common
.feedback_textures
.iter_mut()
.zip(self.feedback_framebuffers.iter())
.zip(passes.iter())
{
*texture = Some(InputTexture::from_framebuffer(
fbo,
pass.config.wrap_mode,
pass.config.filter,
)?);
}

let passes_len = passes.len();
let (pass, last) = passes.split_at_mut(passes_len - 1);

Expand Down
10 changes: 5 additions & 5 deletions librashader-runtime-d3d11/src/framebuffer.rs
Expand Up @@ -21,21 +21,21 @@ use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
static CLEAR: &[f32; 4] = &[0.0f32, 0.0, 0.0, 0.0];

#[derive(Debug, Clone)]
pub(crate) struct OwnedFramebuffer {
pub(crate) struct OwnedImage {
render: ID3D11Texture2D,
pub(crate) size: Size<u32>,
format: DXGI_FORMAT,
device: ID3D11Device,
max_mipmap: u32,
}

impl OwnedFramebuffer {
impl OwnedImage {
pub fn new(
device: &ID3D11Device,
size: Size<u32>,
format: ImageFormat,
mipmap: bool,
) -> error::Result<OwnedFramebuffer> {
) -> error::Result<OwnedImage> {
unsafe {
let format = d3d11_get_closest_format(
device,
Expand All @@ -49,7 +49,7 @@ impl OwnedFramebuffer {
device.CreateTexture2D(&desc, None, Some(&mut render))?;
assume_d3d11_init!(render, "CreateTexture2D");

Ok(OwnedFramebuffer {
Ok(OwnedImage {
render,
size,
format,
Expand Down Expand Up @@ -245,7 +245,7 @@ fn default_desc(size: Size<u32>, format: DXGI_FORMAT, mip_levels: u32) -> D3D11_
}
}

impl ScaleFramebuffer for OwnedFramebuffer {
impl ScaleFramebuffer for OwnedImage {
type Error = FilterChainError;
type Context = ();

Expand Down
14 changes: 7 additions & 7 deletions librashader-runtime-d3d11/src/hello_triangle.rs
Expand Up @@ -568,7 +568,7 @@ pub mod d3d11_hello_triangle {
// eprintln!("w: {} h: {}", backbuffer_desc.Width, backbuffer_desc.Height);
self.filter
.frame(
Some(&resources.deferred_context),
None,
D3D11InputView {
handle: srv,
size: Size {
Expand All @@ -593,12 +593,12 @@ pub mod d3d11_hello_triangle {
)
.unwrap();

let mut command_list = None;
resources
.deferred_context
.FinishCommandList(false, Some(&mut command_list))?;
let command_list = command_list.unwrap();
self.context.ExecuteCommandList(&command_list, false);
// let mut command_list = None;
// resources
// .deferred_context
// .FinishCommandList(false, Some(&mut command_list))?;
// let command_list = command_list.unwrap();
// self.context.ExecuteCommandList(&command_list, false);
// self.context.CopyResource(&resources.backbuffer, &backup);
}

Expand Down
6 changes: 4 additions & 2 deletions librashader-runtime-d3d11/src/lib.rs
Expand Up @@ -38,8 +38,10 @@ mod tests {
// const FILTER_PATH: &str =
// "../test/slang-shaders/handheld/console-border/gbc-lcd-grid-v2.slangp";
// "../test/null.slangp",
const FILTER_PATH: &str =
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV-GLASS.slangp";
// const FILTER_PATH: &str = "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV-GLASS.slangp";

// const FILTER_PATH: &str = "../test/slang-shaders/test/history.slangp";
const FILTER_PATH: &str = "../test/slang-shaders/test/feedback.slangp";

// const FILTER_PATH: &str = "../test/slang-shaders/crt/crt-royale.slangp";
const IMAGE_PATH: &str = "../triangle.png";
Expand Down
4 changes: 2 additions & 2 deletions librashader-runtime-d3d11/src/texture.rs
Expand Up @@ -13,7 +13,7 @@ use windows::Win32::Graphics::Direct3D11::{
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;

use crate::error::{assume_d3d11_init, Result};
use crate::framebuffer::OwnedFramebuffer;
use crate::framebuffer::OwnedImage;

/// An image view for use as a shader resource.
///
Expand Down Expand Up @@ -46,7 +46,7 @@ pub struct InputTexture {

impl InputTexture {
pub(crate) fn from_framebuffer(
fbo: &OwnedFramebuffer,
fbo: &OwnedImage,
wrap_mode: WrapMode,
filter: FilterMode,
) -> Result<Self> {
Expand Down

0 comments on commit 3c15a3a

Please sign in to comment.