From 1cffa3d25ccf124b5fd49b4ebf9e5bdb3264681f Mon Sep 17 00:00:00 2001 From: chyyran Date: Mon, 4 Mar 2024 02:10:08 -0500 Subject: [PATCH] rt: pass device context to uniform binder if needed --- librashader-runtime-gl/src/binding.rs | 10 ++-- librashader-runtime-vk/src/filter_pass.rs | 2 +- librashader-runtime-wgpu/src/filter_pass.rs | 2 +- librashader-runtime/src/binding.rs | 64 +++++++++++---------- librashader-runtime/src/uniforms.rs | 52 +++++++++-------- 5 files changed, 71 insertions(+), 59 deletions(-) diff --git a/librashader-runtime-gl/src/binding.rs b/librashader-runtime-gl/src/binding.rs index 00bcd047..3cb84f40 100644 --- a/librashader-runtime-gl/src/binding.rs +++ b/librashader-runtime-gl/src/binding.rs @@ -59,11 +59,11 @@ impl GlUniformScalar for u32 { } pub(crate) struct GlUniformBinder; -impl BindUniform for GlUniformBinder +impl BindUniform for GlUniformBinder where T: GlUniformScalar, { - fn bind_uniform(block: UniformMemberBlock, value: T, location: VariableLocation) -> Option<()> { + fn bind_uniform(block: UniformMemberBlock, value: T, location: VariableLocation, _: &()) -> Option<()> { if let Some(location) = location.location(block) && location.bindable() { @@ -84,11 +84,12 @@ where } } -impl BindUniform for GlUniformBinder { +impl BindUniform for GlUniformBinder { fn bind_uniform( block: UniformMemberBlock, vec4: &[f32; 4], location: VariableLocation, + _: &() ) -> Option<()> { if let Some(location) = location.location(block) && location.bindable() @@ -108,11 +109,12 @@ impl BindUniform for GlUniformBinder { } } -impl BindUniform for GlUniformBinder { +impl BindUniform for GlUniformBinder { fn bind_uniform( block: UniformMemberBlock, mat4: &[f32; 16], location: VariableLocation, + _: &() ) -> Option<()> { if let Some(location) = location.location(block) && location.bindable() diff --git a/librashader-runtime-vk/src/filter_pass.rs b/librashader-runtime-vk/src/filter_pass.rs index 465c818e..70079afc 100644 --- a/librashader-runtime-vk/src/filter_pass.rs +++ b/librashader-runtime-vk/src/filter_pass.rs @@ -24,7 +24,7 @@ use std::sync::Arc; pub struct FilterPass { pub reflection: ShaderReflection, - pub(crate) uniform_storage: UniformStorage, RawVulkanBuffer>, + pub(crate) uniform_storage: UniformStorage, RawVulkanBuffer, Box<[u8]>, Arc>, pub uniform_bindings: FastHashMap, pub source: ShaderSource, pub config: ShaderPassConfig, diff --git a/librashader-runtime-wgpu/src/filter_pass.rs b/librashader-runtime-wgpu/src/filter_pass.rs index 5481041f..bb7b855d 100644 --- a/librashader-runtime-wgpu/src/filter_pass.rs +++ b/librashader-runtime-wgpu/src/filter_pass.rs @@ -26,7 +26,7 @@ pub struct FilterPass { pub device: Arc, pub reflection: ShaderReflection, pub(crate) uniform_storage: - UniformStorage, WgpuStagedBuffer, WgpuStagedBuffer>, + UniformStorage, WgpuStagedBuffer, WgpuStagedBuffer, Arc>, pub uniform_bindings: FastHashMap, pub source: ShaderSource, pub config: ShaderPassConfig, diff --git a/librashader-runtime/src/binding.rs b/librashader-runtime/src/binding.rs index ff28cab0..d218c282 100644 --- a/librashader-runtime/src/binding.rs +++ b/librashader-runtime/src/binding.rs @@ -15,13 +15,13 @@ pub trait TextureInput { } /// A uniform member offset with context that needs to be resolved. -pub trait ContextOffset +pub trait ContextOffset where - H: BindUniform, - H: BindUniform, - H: BindUniform, - H: for<'a> BindUniform, - H: for<'a> BindUniform, + H: BindUniform, + H: BindUniform, + H: BindUniform, + H: for<'a> BindUniform, + H: for<'a> BindUniform, { /// Gets the `MemberOffset` part of the offset. fn offset(&self) -> MemberOffset; @@ -30,13 +30,13 @@ where fn context(&self) -> C; } -impl ContextOffset> for MemberOffset +impl ContextOffset, D> for MemberOffset where - H: BindUniform, f32>, - H: BindUniform, u32>, - H: BindUniform, i32>, - H: for<'a> BindUniform, &'a [f32; 4]>, - H: for<'a> BindUniform, &'a [f32; 16]>, + H: BindUniform, f32, D>, + H: BindUniform, u32, D>, + H: BindUniform, i32, D>, + H: for<'a> BindUniform, &'a [f32; 4], D>, + H: for<'a> BindUniform, &'a [f32; 16], D>, { fn offset(&self) -> MemberOffset { *self @@ -73,11 +73,11 @@ where C: Copy, U: Deref + DerefMut, P: Deref + DerefMut, - H: BindUniform, - H: BindUniform, - H: BindUniform, - H: for<'b> BindUniform, - H: for<'b> BindUniform, + H: BindUniform, + H: BindUniform, + H: BindUniform, + H: for<'b> BindUniform, + H: for<'b> BindUniform, { /// The type of the input texture used for semantic binding. type InputTexture: TextureInput; @@ -92,7 +92,7 @@ where type DeviceContext; /// The type of uniform offsets to use. - type UniformOffset: ContextOffset; + type UniformOffset: ContextOffset; /// Bind a texture to the input descriptor set fn bind_texture<'a>( @@ -108,7 +108,7 @@ where fn bind_semantics<'a>( device: &Self::DeviceContext, sampler_set: &Self::SamplerSet, - uniform_storage: &mut UniformStorage, + uniform_storage: &mut UniformStorage, descriptor_set: &mut Self::DescriptorSet<'a>, uniform_inputs: UniformInputs<'_>, original: &Self::InputTexture, @@ -124,7 +124,7 @@ where ) { // Bind MVP if let Some(offset) = uniform_bindings.get(&UniqueSemantics::MVP.into()) { - uniform_storage.bind_mat4(offset.offset(), uniform_inputs.mvp, offset.context()); + uniform_storage.bind_mat4(offset.offset(), uniform_inputs.mvp, offset.context(), device); } // Bind OutputSize @@ -133,6 +133,7 @@ where offset.offset(), uniform_inputs.framebuffer_size, offset.context(), + device ); } @@ -142,6 +143,7 @@ where offset.offset(), uniform_inputs.viewport_size, offset.context(), + device ); } @@ -151,6 +153,7 @@ where offset.offset(), uniform_inputs.frame_count, offset.context(), + device ); } @@ -160,12 +163,13 @@ where offset.offset(), uniform_inputs.frame_direction, offset.context(), + device ); } // bind Rotation if let Some(offset) = uniform_bindings.get(&UniqueSemantics::Rotation.into()) { - uniform_storage.bind_scalar(offset.offset(), uniform_inputs.rotation, offset.context()); + uniform_storage.bind_scalar(offset.offset(), uniform_inputs.rotation, offset.context(), device); } // bind TotalSubFrames @@ -174,6 +178,7 @@ where offset.offset(), uniform_inputs.total_subframes, offset.context(), + device ); } @@ -183,6 +188,7 @@ where offset.offset(), uniform_inputs.current_subframe, offset.context(), + device ); } @@ -194,7 +200,7 @@ where // bind OriginalSize if let Some(offset) = uniform_bindings.get(&TextureSemantics::Original.semantics(0).into()) { - uniform_storage.bind_vec4(offset.offset(), original.size(), offset.context()); + uniform_storage.bind_vec4(offset.offset(), original.size(), offset.context(), device); } // bind Source sampler @@ -204,7 +210,7 @@ where // bind SourceSize if let Some(offset) = uniform_bindings.get(&TextureSemantics::Source.semantics(0).into()) { - uniform_storage.bind_vec4(offset.offset(), source.size(), offset.context()); + uniform_storage.bind_vec4(offset.offset(), source.size(), offset.context(), device); } // OriginalHistory0 aliases OriginalHistory @@ -218,7 +224,7 @@ where if let Some(offset) = uniform_bindings.get(&TextureSemantics::OriginalHistory.semantics(0).into()) { - uniform_storage.bind_vec4(offset.offset(), original.size(), offset.context()); + uniform_storage.bind_vec4(offset.offset(), original.size(), offset.context(), device); } // bind OriginalHistory1-.. @@ -240,7 +246,7 @@ where .semantics(index + 1) .into(), ) { - uniform_storage.bind_vec4(offset.offset(), history.size(), offset.context()); + uniform_storage.bind_vec4(offset.offset(), history.size(), offset.context(), device); } } @@ -262,7 +268,7 @@ where if let Some(offset) = uniform_bindings.get(&TextureSemantics::PassOutput.semantics(index).into()) { - uniform_storage.bind_vec4(offset.offset(), output.size(), offset.context()); + uniform_storage.bind_vec4(offset.offset(), output.size(), offset.context(), device); } } @@ -283,7 +289,7 @@ where if let Some(offset) = uniform_bindings.get(&TextureSemantics::PassFeedback.semantics(index).into()) { - uniform_storage.bind_vec4(offset.offset(), feedback.size(), offset.context()); + uniform_storage.bind_vec4(offset.offset(), feedback.size(), offset.context(), device); } } @@ -301,7 +307,7 @@ where let value = *runtime_parameters.get(id).unwrap_or(&default); - uniform_storage.bind_scalar(offset.offset(), value, offset.context()); + uniform_storage.bind_scalar(offset.offset(), value, offset.context(), device); } // bind luts @@ -314,7 +320,7 @@ where if let Some(offset) = uniform_bindings.get(&TextureSemantics::User.semantics(index).into()) { - uniform_storage.bind_vec4(offset.offset(), lut.size(), offset.context()); + uniform_storage.bind_vec4(offset.offset(), lut.size(), offset.context(), device); } } } diff --git a/librashader-runtime/src/uniforms.rs b/librashader-runtime/src/uniforms.rs index 9d1a5f1c..95a3588a 100644 --- a/librashader-runtime/src/uniforms.rs +++ b/librashader-runtime/src/uniforms.rs @@ -9,13 +9,13 @@ impl UniformScalar for i32 {} impl UniformScalar for u32 {} /// A trait for a binder that binds the given value and context into the uniform for a shader pass. -pub trait BindUniform { +pub trait BindUniform { /// Bind the given value to the shader uniforms given the input context. /// /// A `BindUniform` implementation should not write to a backing buffer from a [`UniformStorage`](crate::uniforms::UniformStorage). /// If the binding is successful and no writes to a backing buffer is necessary, this function should return `Some(())`. /// If this function returns `None`, then the value will instead be written to the backing buffer. - fn bind_uniform(block: UniformMemberBlock, value: T, ctx: C) -> Option<()>; + fn bind_uniform(block: UniformMemberBlock, value: T, ctx: C, device: &D) -> Option<()>; } /// A trait to access the raw pointer to a backing uniform storage. @@ -37,7 +37,7 @@ pub trait UniformStorageAccess { fn push_slice(&self) -> &[u8]; } -impl UniformStorageAccess for UniformStorage +impl UniformStorageAccess for UniformStorage where U: Deref + DerefMut, P: Deref + DerefMut, @@ -62,14 +62,14 @@ where /// A uniform binder that always returns `None`, and does not do any binding of uniforms. /// All uniform data is thus written into the backing buffer storage. pub struct NoUniformBinder; -impl BindUniform, T> for NoUniformBinder { - fn bind_uniform(_: UniformMemberBlock, _: T, _: Option<()>) -> Option<()> { +impl BindUniform, T, D> for NoUniformBinder { + fn bind_uniform(_: UniformMemberBlock, _: T, _: Option<()>, _: &D) -> Option<()> { None } } /// A helper to bind uniform variables to UBO or Push Constant Buffers. -pub struct UniformStorage, U = Box<[u8]>, P = Box<[u8]>> +pub struct UniformStorage, U = Box<[u8]>, P = Box<[u8]>, D=()> where U: Deref + DerefMut, P: Deref + DerefMut, @@ -78,9 +78,10 @@ where push: P, _h: PhantomData, _c: PhantomData, + _d: PhantomData } -impl UniformStorage +impl UniformStorage where U: Deref + DerefMut, P: Deref + DerefMut, @@ -103,7 +104,7 @@ where } } -impl UniformStorage +impl UniformStorage where C: Copy, U: Deref + DerefMut, @@ -117,12 +118,12 @@ where /// Bind a scalar to the given offset. #[inline(always)] - pub fn bind_scalar(&mut self, offset: MemberOffset, value: T, ctx: C) + pub fn bind_scalar(&mut self, offset: MemberOffset, value: T, ctx: C, device: &D) where - H: BindUniform, + H: BindUniform, { for ty in UniformMemberBlock::TYPES { - if H::bind_uniform(ty, value, ctx).is_some() { + if H::bind_uniform(ty, value, ctx, device).is_some() { continue; } @@ -134,17 +135,18 @@ where } /// Create a new `UniformStorage` with the given backing storage - pub fn new_with_storage(ubo: U, push: P) -> UniformStorage { + pub fn new_with_storage(ubo: U, push: P) -> UniformStorage { UniformStorage { ubo, push, _h: Default::default(), _c: Default::default(), + _d: Default::default(), } } } -impl UniformStorage> +impl UniformStorage, D> where C: Copy, U: Deref + DerefMut, @@ -153,34 +155,36 @@ where pub fn new_with_ubo_storage( storage: U, push_size: usize, - ) -> UniformStorage> { + ) -> UniformStorage, D> { UniformStorage { ubo: storage, push: vec![0u8; push_size].into_boxed_slice(), _h: Default::default(), _c: Default::default(), + _d: Default::default(), } } } -impl UniformStorage, Box<[u8]>> { +impl UniformStorage, Box<[u8]>, D> { /// Create a new `UniformStorage` with the given size for UBO and Push Constant Buffer sizes. - pub fn new(ubo_size: usize, push_size: usize) -> UniformStorage> { + pub fn new(ubo_size: usize, push_size: usize) -> UniformStorage, Box<[u8]>, D> { UniformStorage { ubo: vec![0u8; ubo_size].into_boxed_slice(), push: vec![0u8; push_size].into_boxed_slice(), _h: Default::default(), _c: Default::default(), + _d: Default::default(), } } } -impl UniformStorage +impl UniformStorage where C: Copy, U: Deref + DerefMut, P: Deref + DerefMut, - H: for<'a> BindUniform, + H: for<'a> BindUniform, { #[inline(always)] fn write_vec4_inner(buffer: &mut [u8], vec4: &[f32; 4]) { @@ -189,11 +193,11 @@ where } /// Bind a `vec4` to the given offset. #[inline(always)] - pub fn bind_vec4(&mut self, offset: MemberOffset, value: impl Into<[f32; 4]>, ctx: C) { + pub fn bind_vec4(&mut self, offset: MemberOffset, value: impl Into<[f32; 4]>, ctx: C, device: &D) { let vec4 = value.into(); for ty in UniformMemberBlock::TYPES { - if H::bind_uniform(ty, &vec4, ctx).is_some() { + if H::bind_uniform(ty, &vec4, ctx, device).is_some() { continue; } if let Some(offset) = offset.offset(ty) { @@ -207,12 +211,12 @@ where } } -impl UniformStorage +impl UniformStorage where C: Copy, U: Deref + DerefMut, P: Deref + DerefMut, - H: for<'a> BindUniform, + H: for<'a> BindUniform, { #[inline(always)] fn write_mat4_inner(buffer: &mut [u8], mat4: &[f32; 16]) { @@ -222,9 +226,9 @@ where /// Bind a `mat4` to the given offset. #[inline(always)] - pub fn bind_mat4(&mut self, offset: MemberOffset, value: &[f32; 16], ctx: C) { + pub fn bind_mat4(&mut self, offset: MemberOffset, value: &[f32; 16], ctx: C, device: &D) { for ty in UniformMemberBlock::TYPES { - if H::bind_uniform(ty, value, ctx).is_some() { + if H::bind_uniform(ty, value, ctx, device).is_some() { continue; } if let Some(offset) = offset.offset(ty) {