rt: do reflection to see if the final pass is needed as feedback
This commit is contained in:
parent
eace595ebb
commit
0fe5bbd57b
|
@ -348,6 +348,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct BindingRequirements {
|
||||
pub(crate) required_history: usize,
|
||||
pub(crate) uses_final_pass_as_feedback: bool,
|
||||
}
|
||||
|
||||
/// Trait for objects that can be used to create a binding map.
|
||||
pub trait BindingUtil {
|
||||
/// Create the uniform binding map with the given reflection information.
|
||||
|
@ -357,7 +362,7 @@ pub trait BindingUtil {
|
|||
) -> FastHashMap<UniformBinding, T>;
|
||||
|
||||
/// Calculate the number of required images for history.
|
||||
fn calculate_required_history<'a>(pass_meta: impl Iterator<Item = &'a Self>) -> usize
|
||||
fn calculate_requirements<'a>(pass_meta: impl Iterator<Item = &'a Self>) -> BindingRequirements
|
||||
where
|
||||
Self: 'a;
|
||||
}
|
||||
|
@ -383,32 +388,65 @@ impl BindingUtil for BindingMeta {
|
|||
uniform_bindings
|
||||
}
|
||||
|
||||
fn calculate_required_history<'a>(pass_meta: impl Iterator<Item = &'a Self>) -> usize
|
||||
fn calculate_requirements<'a>(pass_meta: impl Iterator<Item = &'a Self>) -> BindingRequirements
|
||||
where
|
||||
Self: 'a,
|
||||
{
|
||||
let mut required_images = 0;
|
||||
|
||||
let mut len: i64 = 0;
|
||||
let mut latest_feedback_pass: i64 = -1;
|
||||
|
||||
for pass in pass_meta {
|
||||
len += 1;
|
||||
|
||||
// If a shader uses history size, but not history, we still need to keep the texture.
|
||||
let texture_max_index = pass
|
||||
let history_texture_max_index = pass
|
||||
.texture_meta
|
||||
.iter()
|
||||
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||
.map(|(semantic, _)| semantic.index)
|
||||
.fold(0, std::cmp::max);
|
||||
let texture_size_max_index = pass
|
||||
let history_texture_size_max_index = pass
|
||||
.texture_size_meta
|
||||
.iter()
|
||||
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||
.map(|(semantic, _)| semantic.index)
|
||||
.fold(0, std::cmp::max);
|
||||
|
||||
required_images = std::cmp::max(required_images, texture_max_index);
|
||||
required_images = std::cmp::max(required_images, texture_size_max_index);
|
||||
let feedback_max_index = pass
|
||||
.texture_meta
|
||||
.iter()
|
||||
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::PassFeedback)
|
||||
.map(|(semantic, _)| semantic.index as i64)
|
||||
.fold(-1, std::cmp::max);
|
||||
let feedback_max_size_index = pass
|
||||
.texture_size_meta
|
||||
.iter()
|
||||
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::PassFeedback)
|
||||
.map(|(semantic, _)| semantic.index as i64)
|
||||
.fold(-1, std::cmp::max);
|
||||
|
||||
latest_feedback_pass = std::cmp::max(latest_feedback_pass, feedback_max_index);
|
||||
latest_feedback_pass = std::cmp::max(latest_feedback_pass, feedback_max_size_index);
|
||||
|
||||
required_images = std::cmp::max(required_images, history_texture_max_index);
|
||||
required_images = std::cmp::max(required_images, history_texture_size_max_index);
|
||||
}
|
||||
|
||||
required_images
|
||||
let uses_feedback = if latest_feedback_pass.is_negative() {
|
||||
false
|
||||
} else {
|
||||
// Technically = but we can be permissive here
|
||||
|
||||
// account for off by 1
|
||||
latest_feedback_pass + 1 >= len
|
||||
};
|
||||
|
||||
BindingRequirements {
|
||||
required_history: required_images,
|
||||
uses_final_pass_as_feedback: uses_feedback,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::binding::BindingUtil;
|
||||
use crate::binding::{BindingRequirements, BindingUtil};
|
||||
use librashader_reflect::reflect::semantics::BindingMeta;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
|
@ -6,7 +6,7 @@ use std::collections::VecDeque;
|
|||
pub struct FramebufferInit<'a, F, I, E> {
|
||||
owned_generator: &'a dyn Fn() -> Result<F, E>,
|
||||
input_generator: &'a dyn Fn() -> I,
|
||||
required_history: usize,
|
||||
requirements: BindingRequirements,
|
||||
filters_count: usize,
|
||||
}
|
||||
|
||||
|
@ -19,19 +19,20 @@ impl<'a, F, I, E> FramebufferInit<'a, F, I, E> {
|
|||
input_generator: &'a dyn Fn() -> I,
|
||||
) -> Self {
|
||||
let filters_count = filters.len();
|
||||
let required_history = BindingMeta::calculate_required_history(filters);
|
||||
let requirements = BindingMeta::calculate_requirements(filters);
|
||||
|
||||
Self {
|
||||
owned_generator,
|
||||
input_generator,
|
||||
filters_count,
|
||||
required_history,
|
||||
requirements,
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize history framebuffers and views.
|
||||
pub fn init_history(&self) -> Result<(VecDeque<F>, Box<[I]>), E> {
|
||||
init_history(
|
||||
self.required_history,
|
||||
self.requirements.required_history,
|
||||
self.owned_generator,
|
||||
self.input_generator,
|
||||
)
|
||||
|
@ -45,6 +46,11 @@ impl<'a, F, I, E> FramebufferInit<'a, F, I, E> {
|
|||
self.input_generator,
|
||||
)
|
||||
}
|
||||
|
||||
/// Get if the final pass is used as feedback.
|
||||
pub const fn uses_final_pass_as_feedback(&self) -> bool {
|
||||
self.requirements.uses_final_pass_as_feedback
|
||||
}
|
||||
}
|
||||
|
||||
fn init_history<'a, F, I, E>(
|
||||
|
|
Loading…
Reference in a new issue