rt: add Rotation, TotalSubFrames, CurrentSubFrame uniform semantics

This commit is contained in:
chyyran 2024-02-12 01:56:39 -05:00 committed by Ronny Chan
parent 3c3f024ef8
commit daf30c83c0
24 changed files with 280 additions and 128 deletions

View file

@ -73,11 +73,18 @@ pub struct frame_d3d11_opt_t {
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
/// The rotation of the output. 0 = 0deg, 1 = 90deg, 2 = 180deg, 4 = 270deg.
pub rotation: u32,
/// The total number of subframes ran. Default is 1.
pub total_subframes: u32,
// The current sub frame. Default is 1.
pub current_subframe: u32,
}
config_struct! {
impl FrameOptions => frame_d3d11_opt_t {
0 => [clear_history, frame_direction];
1 => [rotation, total_subframes, current_subframe]
}
}

View file

@ -54,11 +54,18 @@ pub struct frame_d3d12_opt_t {
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
/// The rotation of the output. 0 = 0deg, 1 = 90deg, 2 = 180deg, 4 = 270deg.
pub rotation: u32,
/// The total number of subframes ran. Default is 1.
pub total_subframes: u32,
// The current sub frame. Default is 1.
pub current_subframe: u32,
}
config_struct! {
impl FrameOptions => frame_d3d12_opt_t {
0 => [clear_history, frame_direction];
1 => [rotation, total_subframes, current_subframe]
}
}

View file

@ -64,11 +64,18 @@ pub struct frame_gl_opt_t {
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
/// The rotation of the output. 0 = 0deg, 1 = 90deg, 2 = 180deg, 4 = 270deg.
pub rotation: u32,
/// The total number of subframes ran. Default is 1.
pub total_subframes: u32,
// The current sub frame. Default is 1.
pub current_subframe: u32,
}
config_struct! {
impl FrameOptions => frame_gl_opt_t {
0 => [clear_history, frame_direction];
1 => [rotation, total_subframes, current_subframe]
}
}

View file

@ -17,6 +17,7 @@ use librashader::runtime::{Size, Viewport};
use ash::vk;
use crate::LIBRASHADER_API_VERSION;
pub use ash::vk::PFN_vkGetInstanceProcAddr;
/// A Vulkan instance function loader that the Vulkan filter chain needs to be initialized with.
@ -87,17 +88,24 @@ impl From<libra_device_vk_t> for VulkanInstance {
#[derive(Default, Debug, Clone)]
pub struct frame_vk_opt_t {
/// The librashader API version.
pub version: usize,
pub version: LIBRASHADER_API_VERSION,
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
/// The rotation of the output. 0 = 0deg, 1 = 90deg, 2 = 180deg, 4 = 270deg.
pub rotation: u32,
/// The total number of subframes ran. Default is 1.
pub total_subframes: u32,
// The current sub frame. Default is 1.
pub current_subframe: u32,
}
config_struct! {
impl FrameOptions => frame_vk_opt_t {
0 => [clear_history, frame_direction];
1 => [rotation, total_subframes, current_subframe]
}
}

View file

@ -13,7 +13,11 @@ pub type LIBRASHADER_ABI_VERSION = usize;
/// versions must remain backwards compatible.
/// ## API Versions
/// - API version 0: 0.1.0
pub const LIBRASHADER_CURRENT_VERSION: LIBRASHADER_API_VERSION = 0;
/// - API version 1: 0.2.0
/// - Added rotation, total_subframes, current_subframes to frame options
/// - Added preset context API
/// - Added Metal runtime API
pub const LIBRASHADER_CURRENT_VERSION: LIBRASHADER_API_VERSION = 1;
/// The current version of the librashader ABI.
/// Used by the loader to check ABI compatibility.

View file

@ -92,7 +92,10 @@ impl ValidateTypeSemantics<Type> for UniqueSemantics {
UniqueSemantics::MVP => {
matches!(ty, Type::Float { .. }) && vecsize == 4 && columns == 4
}
UniqueSemantics::FrameCount => {
UniqueSemantics::FrameCount
| UniqueSemantics::Rotation
| UniqueSemantics::TotalSubFrames
| UniqueSemantics::CurrentSubFrame => {
matches!(ty, Type::UInt { .. }) && vecsize == 1 && columns == 1
}
UniqueSemantics::FrameDirection => {

View file

@ -163,7 +163,10 @@ impl ValidateTypeSemantics<&TypeInner> for UniqueSemantics {
});
}
}
UniqueSemantics::FrameCount => {
UniqueSemantics::FrameCount
| UniqueSemantics::Rotation
| UniqueSemantics::CurrentSubFrame
| UniqueSemantics::TotalSubFrames => {
// Uint32 == width 4
if matches!(ty, TypeInner::Scalar( Scalar { kind, width }) if *kind == ScalarKind::Uint && *width == 4)
{
@ -174,7 +177,7 @@ impl ValidateTypeSemantics<&TypeInner> for UniqueSemantics {
}
}
UniqueSemantics::FrameDirection => {
// Uint32 == width 4
// iint32 == width 4
if matches!(ty, TypeInner::Scalar( Scalar { kind, width }) if *kind == ScalarKind::Sint && *width == 4)
{
return Some(TypeInfo {

View file

@ -40,11 +40,18 @@ pub enum UniqueSemantics {
/// The frame count, possibly with shader-defined modulo.
FrameCount = 3,
// int, frame direction
/// The frame direction.
/// The direction in time where frames are rendered
FrameDirection = 4,
//int, rotation (glUniform1i(uni->rotation, retroarch_get_rotation());)
/// The rotation index (0 = 0deg, 1 = 90deg, 2 = 180deg, 3 = 270deg)
Rotation = 5,
/// Total number of subframes.
TotalSubFrames = 6,
/// The current subframe (default 1)
CurrentSubFrame = 7,
/// A user defined float parameter.
// float, user defined parameter, array
FloatParameter = 5,
FloatParameter = 8,
}
impl UniqueSemantics {
@ -64,6 +71,9 @@ impl UniqueSemantics {
UniqueSemantics::FinalViewport => UniformType::Vec4,
UniqueSemantics::FrameCount => UniformType::Unsigned,
UniqueSemantics::FrameDirection => UniformType::Signed,
UniqueSemantics::Rotation => UniformType::Unsigned,
UniqueSemantics::TotalSubFrames => UniformType::Unsigned,
UniqueSemantics::CurrentSubFrame => UniformType::Unsigned,
UniqueSemantics::FloatParameter => UniformType::Float,
}
}
@ -405,6 +415,18 @@ impl UniqueSemanticMap for FxHashMap<String, UniformSemantic> {
semantics: UniqueSemantics::FrameDirection,
index: (),
}),
"Rotation" => Some(Semantic {
semantics: UniqueSemantics::Rotation,
index: (),
}),
"TotalSubFrames" => Some(Semantic {
semantics: UniqueSemantics::TotalSubFrames,
index: (),
}),
"CurrentSubFrame" => Some(Semantic {
semantics: UniqueSemantics::TotalSubFrames,
index: (),
}),
_ => None,
},
Some(UniformSemantic::Unique(variable)) => Some(*variable),

View file

@ -55,6 +55,7 @@ pub struct FilterChainD3D11 {
feedback_framebuffers: Box<[OwnedImage]>,
history_framebuffers: VecDeque<OwnedImage>,
state: D3D11State,
default_options: FrameOptionsD3D11,
}
pub(crate) struct Direct3D11 {
@ -203,6 +204,7 @@ impl FilterChainD3D11 {
draw_quad,
},
state,
default_options: Default::default(),
})
}
}
@ -416,7 +418,7 @@ impl FilterChainD3D11 {
return Ok(());
}
let frame_direction = options.map_or(1, |f| f.frame_direction);
let options = options.unwrap_or(&self.default_options);
let filter = passes[0].config.filter;
let wrap_mode = passes[0].config.wrap_mode;
@ -480,7 +482,7 @@ impl FilterChainD3D11 {
index,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,
@ -509,7 +511,7 @@ impl FilterChainD3D11 {
passes_len - 1,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,

View file

@ -1,5 +1,7 @@
use crate::filter_chain::FilterCommon;
use crate::options::FrameOptionsD3D11;
use crate::texture::InputTexture;
use librashader_common::{ImageFormat, Size, Viewport};
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
@ -9,7 +11,7 @@ use librashader_reflect::reflect::semantics::{
use librashader_reflect::reflect::ShaderReflection;
use rustc_hash::FxHashMap;
use librashader_runtime::binding::{BindSemantics, TextureInput};
use librashader_runtime::binding::{BindSemantics, TextureInput, UniformInputs};
use librashader_runtime::filter_pass::FilterPassMeta;
use librashader_runtime::quad::QuadType;
use librashader_runtime::render_target::RenderTarget;
@ -100,7 +102,7 @@ impl FilterPass {
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsD3D11,
fb_size: Size<u32>,
viewport_size: Size<u32>,
mut descriptors: (
@ -115,11 +117,16 @@ impl FilterPass {
&parent.samplers,
&mut self.uniform_storage,
&mut descriptors,
mvp,
frame_count,
frame_direction,
fb_size,
viewport_size,
UniformInputs {
mvp,
frame_count,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
frame_direction: options.frame_direction,
framebuffer_size: fb_size,
viewport_size,
},
original,
source,
&self.uniform_bindings,
@ -141,7 +148,7 @@ impl FilterPass {
pass_index: usize,
parent: &FilterCommon,
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsD3D11,
viewport: &Viewport<D3D11OutputView>,
original: &InputTexture,
source: &InputTexture,
@ -168,7 +175,7 @@ impl FilterPass {
parent,
output.mvp,
frame_count,
frame_direction,
options,
output.output.size,
viewport.output.size,
descriptors,

View file

@ -1,15 +1,7 @@
//! Direct3D 11 shader runtime options.
/// Options for each Direct3D 11 shader frame.
#[repr(C)]
#[derive(Default, Debug, Clone)]
pub struct FrameOptionsD3D11 {
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
}
use librashader_runtime::impl_default_frame_options;
impl_default_frame_options!(FrameOptionsD3D11);
/// Options for Direct3D 11 filter chain creation.
#[repr(C)]

View file

@ -77,6 +77,8 @@ pub struct FilterChainD3D12 {
mipmap_heap: D3D12DescriptorHeap<ResourceWorkHeap>,
disable_mipmaps: bool,
default_options: FrameOptionsD3D12,
}
pub(crate) struct FilterCommon {
@ -360,6 +362,7 @@ impl FilterChainD3D12 {
mipmap_heap,
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
residuals,
default_options: Default::default(),
})
}
@ -620,7 +623,7 @@ impl FilterChainD3D12 {
return Ok(());
}
let frame_direction = options.map_or(1, |f| f.frame_direction);
let options = options.unwrap_or(&self.default_options);
let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled);
let passes = &mut self.passes[0..max];
@ -734,7 +737,7 @@ impl FilterChainD3D12 {
index,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,
@ -796,7 +799,7 @@ impl FilterChainD3D12 {
passes_len - 1,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,

View file

@ -3,6 +3,7 @@ use crate::descriptor_heap::{D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerW
use crate::error;
use crate::filter_chain::FilterCommon;
use crate::graphics_pipeline::D3D12GraphicsPipeline;
use crate::options::FrameOptionsD3D12;
use crate::samplers::SamplerSet;
use crate::texture::{D3D12OutputView, InputTexture};
use librashader_common::{ImageFormat, Size, Viewport};
@ -10,7 +11,7 @@ use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, UniformBinding};
use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::binding::{BindSemantics, TextureInput};
use librashader_runtime::binding::{BindSemantics, TextureInput, UniformInputs};
use librashader_runtime::filter_pass::FilterPassMeta;
use librashader_runtime::quad::QuadType;
use librashader_runtime::render_target::RenderTarget;
@ -93,7 +94,7 @@ impl FilterPass {
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsD3D12,
fb_size: Size<u32>,
viewport_size: Size<u32>,
original: &InputTexture,
@ -104,11 +105,16 @@ impl FilterPass {
&parent.samplers,
&mut self.uniform_storage,
&mut (&mut self.texture_heap, &mut self.sampler_heap),
mvp,
frame_count,
frame_direction,
fb_size,
viewport_size,
UniformInputs {
mvp,
frame_count,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
frame_direction: options.frame_direction,
framebuffer_size: fb_size,
viewport_size,
},
original,
source,
&self.uniform_bindings,
@ -135,7 +141,7 @@ impl FilterPass {
pass_index: usize,
parent: &FilterCommon,
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsD3D12,
viewport: &Viewport<D3D12OutputView>,
original: &InputTexture,
source: &InputTexture,
@ -151,7 +157,7 @@ impl FilterPass {
parent,
output.mvp,
frame_count,
frame_direction,
options,
output.output.size,
viewport.output.size,
original,

View file

@ -1,15 +1,7 @@
//! Direct3D 12 shader runtime options.
/// Options for each Direct3D12 shader frame.
#[repr(C)]
#[derive(Default, Debug, Clone)]
pub struct FrameOptionsD3D12 {
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
}
use librashader_runtime::impl_default_frame_options;
impl_default_frame_options!(FrameOptionsD3D12);
/// Options for Direct3D 12 filter chain creation.
#[repr(C)]

View file

@ -45,6 +45,7 @@ pub(crate) struct FilterChainImpl<T: GLInterface> {
output_framebuffers: Box<[GLFramebuffer]>,
feedback_framebuffers: Box<[GLFramebuffer]>,
history_framebuffers: VecDeque<GLFramebuffer>,
default_options: FrameOptionsGL,
}
pub(crate) struct FilterCommon {
@ -194,6 +195,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
feedback_textures,
history_textures,
},
default_options: Default::default(),
})
}
@ -288,7 +290,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
if passes.is_empty() {
return Ok(());
}
let frame_direction = options.map_or(1, |f| f.frame_direction);
let options = options.unwrap_or(&self.default_options);
// do not need to rebind FBO 0 here since first `draw` will
// bind automatically.
@ -355,7 +357,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
index,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,
@ -378,7 +380,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
passes_len - 1,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,

View file

@ -5,7 +5,7 @@ use librashader_common::{ImageFormat, Size, Viewport};
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, UniformBinding};
use librashader_runtime::binding::{BindSemantics, ContextOffset, TextureInput};
use librashader_runtime::binding::{BindSemantics, ContextOffset, TextureInput, UniformInputs};
use librashader_runtime::filter_pass::FilterPassMeta;
use librashader_runtime::render_target::RenderTarget;
use rustc_hash::FxHashMap;
@ -13,6 +13,7 @@ use rustc_hash::FxHashMap;
use crate::binding::{GlUniformBinder, GlUniformStorage, UniformLocation, VariableLocation};
use crate::filter_chain::FilterCommon;
use crate::gl::{BindTexture, GLInterface, UboRing};
use crate::options::FrameOptionsGL;
use crate::samplers::SamplerSet;
use crate::GLFramebuffer;
@ -80,7 +81,7 @@ impl<T: GLInterface> FilterPass<T> {
pass_index: usize,
parent: &FilterCommon,
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsGL,
viewport: &Viewport<&GLFramebuffer>,
original: &InputTexture,
source: &InputTexture,
@ -102,7 +103,7 @@ impl<T: GLInterface> FilterPass<T> {
parent,
output.mvp,
frame_count,
frame_direction,
options,
framebuffer.size,
viewport,
original,
@ -163,7 +164,7 @@ impl<T: GLInterface> FilterPass<T> {
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsGL,
fb_size: Size<u32>,
viewport: &Viewport<&GLFramebuffer>,
original: &InputTexture,
@ -174,11 +175,16 @@ impl<T: GLInterface> FilterPass<T> {
&parent.samplers,
&mut self.uniform_storage,
&mut (),
mvp,
frame_count,
frame_direction,
fb_size,
viewport.output.size,
UniformInputs {
mvp,
frame_count,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
frame_direction: options.frame_direction,
framebuffer_size: fb_size,
viewport_size: viewport.output.size,
},
original,
source,
&self.uniform_bindings,

View file

@ -1,15 +1,7 @@
//! OpenGL shader runtime options.
/// Options for each OpenGL shader frame.
#[repr(C)]
#[derive(Default, Debug, Clone)]
pub struct FrameOptionsGL {
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
}
use librashader_runtime::impl_default_frame_options;
impl_default_frame_options!(FrameOptionsGL);
/// Options for filter chain creation.
#[repr(C)]

View file

@ -125,6 +125,7 @@ pub struct FilterChainVulkan {
history_framebuffers: VecDeque<OwnedImage>,
disable_mipmaps: bool,
residuals: Box<[FrameResiduals]>,
default_options: FrameOptionsVulkan,
}
pub struct FilterMutable {
@ -402,6 +403,7 @@ impl FilterChainVulkan {
history_framebuffers,
residuals: intermediates.into_boxed_slice(),
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
default_options: Default::default(),
})
}
@ -667,7 +669,7 @@ impl FilterChainVulkan {
let passes_len = passes.len();
let (pass, last) = passes.split_at_mut(passes_len - 1);
let frame_direction = options.map_or(1, |f| f.frame_direction);
let options = options.unwrap_or(&self.default_options);
self.common.draw_quad.bind_vbo_for_frame(cmd);
for (index, pass) in pass.iter_mut().enumerate() {
@ -684,7 +686,7 @@ impl FilterChainVulkan {
index,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,
@ -729,7 +731,7 @@ impl FilterChainVulkan {
passes_len - 1,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,

View file

@ -2,6 +2,7 @@ use crate::filter_chain::FilterCommon;
use crate::framebuffer::OutputImage;
use crate::graphics_pipeline::VulkanGraphicsPipeline;
use crate::memory::RawVulkanBuffer;
use crate::options::FrameOptionsVulkan;
use crate::samplers::SamplerSet;
use crate::texture::InputImage;
use crate::{error, VulkanImage};
@ -13,7 +14,7 @@ use librashader_reflect::reflect::semantics::{
BindingStage, MemberOffset, TextureBinding, UniformBinding,
};
use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::binding::{BindSemantics, TextureInput};
use librashader_runtime::binding::{BindSemantics, TextureInput, UniformInputs};
use librashader_runtime::filter_pass::FilterPassMeta;
use librashader_runtime::quad::QuadType;
use librashader_runtime::render_target::RenderTarget;
@ -91,7 +92,7 @@ impl FilterPass {
pass_index: usize,
parent: &FilterCommon,
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsVulkan,
viewport: &Viewport<VulkanImage>,
original: &InputImage,
source: &InputImage,
@ -106,7 +107,7 @@ impl FilterPass {
parent,
output.mvp,
frame_count,
frame_direction,
options,
output.output.size,
viewport.output.size,
&mut descriptor,
@ -187,7 +188,7 @@ impl FilterPass {
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsVulkan,
fb_size: Size<u32>,
viewport_size: Size<u32>,
descriptor_set: &mut vk::DescriptorSet,
@ -199,11 +200,16 @@ impl FilterPass {
&parent.samplers,
&mut self.uniform_storage,
descriptor_set,
mvp,
frame_count,
frame_direction,
fb_size,
viewport_size,
UniformInputs {
mvp,
frame_count,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
frame_direction: options.frame_direction,
framebuffer_size: fb_size,
viewport_size,
},
original,
source,
&self.uniform_bindings,

View file

@ -1,15 +1,7 @@
//! Vulkan shader runtime options.
/// Options for each Vulkan shader frame.
#[repr(C)]
#[derive(Default, Debug, Clone)]
pub struct FrameOptionsVulkan {
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
}
use librashader_runtime::impl_default_frame_options;
impl_default_frame_options!(FrameOptionsVulkan);
/// Options for filter chain creation.
#[repr(C)]

View file

@ -59,6 +59,7 @@ pub struct FilterChainWgpu {
history_framebuffers: VecDeque<OwnedImage>,
disable_mipmaps: bool,
mipmapper: MipmapGen,
default_frame_options: FrameOptionsWgpu,
}
pub struct FilterMutable {
@ -204,6 +205,7 @@ impl FilterChainWgpu {
history_framebuffers,
disable_mipmaps: options.map(|f| f.force_no_mipmaps).unwrap_or(false),
mipmapper,
default_frame_options: Default::default(),
})
}
@ -408,7 +410,7 @@ impl FilterChainWgpu {
let passes_len = passes.len();
let (pass, last) = passes.split_at_mut(passes_len - 1);
let frame_direction = options.map_or(1, |f| f.frame_direction);
let options = options.unwrap_or(&self.default_frame_options);
for (index, pass) in pass.iter_mut().enumerate() {
let target = &self.output_framebuffers[index];
@ -424,7 +426,7 @@ impl FilterChainWgpu {
index,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,
@ -463,7 +465,7 @@ impl FilterChainWgpu {
passes_len - 1,
&self.common,
pass.config.get_frame_count(frame_count),
frame_direction,
options,
viewport,
&original,
&source,

View file

@ -3,6 +3,7 @@ use crate::error;
use crate::filter_chain::FilterCommon;
use crate::framebuffer::WgpuOutputView;
use crate::graphics_pipeline::WgpuGraphicsPipeline;
use crate::options::FrameOptionsWgpu;
use crate::samplers::SamplerSet;
use crate::texture::InputImage;
use librashader_common::{ImageFormat, Size, Viewport};
@ -12,7 +13,7 @@ use librashader_reflect::reflect::semantics::{
BindingStage, MemberOffset, TextureBinding, UniformBinding,
};
use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::binding::{BindSemantics, TextureInput};
use librashader_runtime::binding::{BindSemantics, TextureInput, UniformInputs};
use librashader_runtime::filter_pass::FilterPassMeta;
use librashader_runtime::quad::QuadType;
use librashader_runtime::render_target::RenderTarget;
@ -89,7 +90,7 @@ impl FilterPass {
pass_index: usize,
parent: &FilterCommon,
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsWgpu,
viewport: &Viewport<WgpuOutputView>,
original: &InputImage,
source: &InputImage,
@ -104,7 +105,7 @@ impl FilterPass {
parent,
output.mvp,
frame_count,
frame_direction,
options,
output.output.size,
viewport.output.size,
original,
@ -198,7 +199,7 @@ impl FilterPass {
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
frame_direction: i32,
options: &FrameOptionsWgpu,
fb_size: Size<u32>,
viewport_size: Size<u32>,
original: &InputImage,
@ -211,11 +212,16 @@ impl FilterPass {
&parent.samplers,
&mut self.uniform_storage,
&mut (main_heap, sampler_heap),
mvp,
frame_count,
frame_direction,
fb_size,
viewport_size,
UniformInputs {
mvp,
frame_count,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
frame_direction: options.frame_direction,
framebuffer_size: fb_size,
viewport_size,
},
original,
source,
&self.uniform_bindings,

View file

@ -1,15 +1,7 @@
//! wgpu shader runtime options.
/// Options for each wgpu shader frame.
#[repr(C)]
#[derive(Default, Debug, Clone)]
pub struct FrameOptionsWgpu {
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
}
use librashader_runtime::impl_default_frame_options;
impl_default_frame_options!(FrameOptionsWgpu);
/// Options for filter chain creation.
#[repr(C)]

View file

@ -49,6 +49,26 @@ where
}
}
/// Inputs to binding semantics
pub struct UniformInputs<'a> {
/// MVP
pub mvp: &'a [f32; 16],
/// FrameCount
pub frame_count: u32,
/// Rotation
pub rotation: u32,
/// TotalSubFrames
pub total_subframes: u32,
/// CurrentSubFrame
pub current_subframe: u32,
/// FrameDirection
pub frame_direction: i32,
/// OutputSize
pub framebuffer_size: Size<u32>,
/// FinalViewportSize
pub viewport_size: Size<u32>,
}
/// Trait that abstracts binding of semantics to shader uniforms.
pub trait BindSemantics<H = NoUniformBinder, C = Option<()>, U = Box<[u8]>, P = Box<[u8]>>
where
@ -92,11 +112,7 @@ where
sampler_set: &Self::SamplerSet,
uniform_storage: &mut UniformStorage<H, C, U, P>,
descriptor_set: &mut Self::DescriptorSet<'a>,
mvp: &[f32; 16],
frame_count: u32,
frame_direction: i32,
framebuffer_size: Size<u32>,
viewport_size: Size<u32>,
uniform_inputs: UniformInputs<'_>,
original: &Self::InputTexture,
source: &Self::InputTexture,
uniform_bindings: &HashMap<UniformBinding, Self::UniformOffset, impl BuildHasher>,
@ -110,27 +126,66 @@ where
) {
// Bind MVP
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::MVP.into()) {
uniform_storage.bind_mat4(offset.offset(), mvp, offset.context());
uniform_storage.bind_mat4(offset.offset(), uniform_inputs.mvp, offset.context());
}
// Bind OutputSize
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::Output.into()) {
uniform_storage.bind_vec4(offset.offset(), framebuffer_size, offset.context());
uniform_storage.bind_vec4(
offset.offset(),
uniform_inputs.framebuffer_size,
offset.context(),
);
}
// bind FinalViewportSize
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::FinalViewport.into()) {
uniform_storage.bind_vec4(offset.offset(), viewport_size, offset.context());
uniform_storage.bind_vec4(
offset.offset(),
uniform_inputs.viewport_size,
offset.context(),
);
}
// bind FrameCount
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::FrameCount.into()) {
uniform_storage.bind_scalar(offset.offset(), frame_count, offset.context());
uniform_storage.bind_scalar(
offset.offset(),
uniform_inputs.frame_count,
offset.context(),
);
}
// bind FrameDirection
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::FrameDirection.into()) {
uniform_storage.bind_scalar(offset.offset(), frame_direction, offset.context());
uniform_storage.bind_scalar(
offset.offset(),
uniform_inputs.frame_direction,
offset.context(),
);
}
// bind Rotation
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::Rotation.into()) {
uniform_storage.bind_scalar(offset.offset(), uniform_inputs.rotation, offset.context());
}
// bind TotalSubFrames
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::TotalSubFrames.into()) {
uniform_storage.bind_scalar(
offset.offset(),
uniform_inputs.total_subframes,
offset.context(),
);
}
// bind CurrentSubFrames
if let Some(offset) = uniform_bindings.get(&UniqueSemantics::CurrentSubFrame.into()) {
uniform_storage.bind_scalar(
offset.offset(),
uniform_inputs.current_subframe,
offset.context(),
);
}
// bind Original sampler
@ -149,7 +204,7 @@ where
Self::bind_texture(descriptor_set, sampler_set, binding, source, device);
}
// bind SourcelSize
// bind SourceSize
if let Some(offset) = uniform_bindings.get(&TextureSemantics::Source.semantics(0).into()) {
uniform_storage.bind_vec4(offset.offset(), source.size(), offset.context());
}
@ -330,3 +385,37 @@ impl BindingUtil for BindingMeta {
required_images
}
}
#[macro_export]
macro_rules! impl_default_frame_options {
($ty:ident) => {
/// Options for each frame.
#[repr(C)]
#[derive(Debug, Clone)]
pub struct $ty {
/// Whether or not to clear the history buffers.
pub clear_history: bool,
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
pub frame_direction: i32,
/// The rotation of the output. 0 = 0deg, 1 = 90deg, 2 = 180deg, 4 = 270deg.
pub rotation: u32,
/// The total number of subframes ran. Default is 1.
pub total_subframes: u32,
// The current sub frame. Default is 1.
pub current_subframe: u32,
}
impl Default for $ty {
fn default() -> Self {
Self {
clear_history: false,
frame_direction: 1,
rotation: 0,
total_subframes: 1,
current_subframe: 1,
}
}
}
};
}