From 4cc3c875bf324c068cb24f0dfd4a59c52880cb2e Mon Sep 17 00:00:00 2001 From: chyyran Date: Sun, 15 Sep 2024 01:16:32 -0400 Subject: [PATCH] reflect: allow compilation of boxed trait objects Add a hidden `compile_boxed` function to CompileShader to support this. This is to allow Box to work. --- librashader-reflect/src/back/mod.rs | 50 +++++++++++++++++++ librashader-reflect/src/back/msl.rs | 5 +- librashader-reflect/src/back/spirv.rs | 10 ++-- librashader-reflect/src/reflect/cross/glsl.rs | 7 +++ librashader-reflect/src/reflect/cross/hlsl.rs | 7 +++ librashader-reflect/src/reflect/naga/msl.rs | 7 +++ librashader-reflect/src/reflect/naga/spirv.rs | 7 +++ librashader-reflect/src/reflect/naga/wgsl.rs | 7 +++ 8 files changed, 92 insertions(+), 8 deletions(-) diff --git a/librashader-reflect/src/back/mod.rs b/librashader-reflect/src/back/mod.rs index 01ae71c..f41604d 100644 --- a/librashader-reflect/src/back/mod.rs +++ b/librashader-reflect/src/back/mod.rs @@ -36,6 +36,16 @@ pub trait CompileShader { self, options: Self::Options, ) -> Result, ShaderCompileError>; + + /// Consume the object and return the compiled output of the shader. + /// + /// This is an internal implementation detail for stable building without TAIT, + /// to allow delegation when Self is unsized (i.e. dyn CompileReflectShader). + #[doc(hidden)] + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, ShaderCompileError>; } /// Marker trait for combinations of targets and compilations that can be reflected and compiled @@ -81,6 +91,13 @@ where ) -> Result, ShaderCompileError> { self.backend.compile(options) } + + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, ShaderCompileError> { + self.backend.compile(options) + } } /// A trait for reflectable compilations that can be transformed @@ -124,6 +141,39 @@ where } } +impl ReflectShader for Box { + fn reflect( + &mut self, + pass_number: usize, + semantics: &ShaderSemantics, + ) -> Result { + (**self).reflect(pass_number, semantics) + } +} + +impl CompileShader for Box +where + O: CompileShader + ?Sized, + T: OutputTarget, +{ + type Options = O::Options; + type Context = O::Context; + + fn compile( + self, + options: Self::Options, + ) -> Result, ShaderCompileError> { + O::compile_boxed(self, options) + } + + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, ShaderCompileError> { + self.compile(options) + } +} + #[cfg(test)] mod test { use crate::front::{Glslang, ShaderInputCompiler}; diff --git a/librashader-reflect/src/back/msl.rs b/librashader-reflect/src/back/msl.rs index 6fed3b7..fb5f983 100644 --- a/librashader-reflect/src/back/msl.rs +++ b/librashader-reflect/src/back/msl.rs @@ -1,5 +1,5 @@ use crate::back::targets::MSL; -use crate::back::{CompileReflectShader, CompileShader, CompilerBackend, FromCompilation}; +use crate::back::{CompileReflectShader, CompilerBackend, FromCompilation}; use crate::error::ShaderReflectError; use crate::front::SpirvCompilation; use crate::reflect::cross::msl::MslReflect; @@ -29,8 +29,7 @@ impl FromCompilation for MSL { type Target = MSL; type Options = Option; type Context = CrossMslContext; - type Output = impl CompileShader - + ReflectShader; + type Output = impl CompileReflectShader; fn from_compilation( compile: SpirvCompilation, diff --git a/librashader-reflect/src/back/spirv.rs b/librashader-reflect/src/back/spirv.rs index 5ed8fe3..3628886 100644 --- a/librashader-reflect/src/back/spirv.rs +++ b/librashader-reflect/src/back/spirv.rs @@ -1,5 +1,7 @@ use crate::back::targets::SPIRV; -use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput}; +use crate::back::{ + CompileReflectShader, CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput, +}; use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::front::SpirvCompilation; use crate::reflect::cross::glsl::GlslReflect; @@ -20,8 +22,7 @@ impl FromCompilation for SPIRV { type Target = SPIRV; type Options = Option<()>; type Context = (); - type Output = impl CompileShader - + ReflectShader; + type Output = impl CompileReflectShader; fn from_compilation( compile: SpirvCompilation, @@ -86,8 +87,7 @@ impl FromCompilation for SPIRV { type Target = SPIRV; type Options = NagaSpirvOptions; type Context = NagaSpirvContext; - type Output = impl CompileShader - + ReflectShader; + type Output = impl CompileReflectShader; fn from_compilation( compile: SpirvCompilation, diff --git a/librashader-reflect/src/reflect/cross/glsl.rs b/librashader-reflect/src/reflect/cross/glsl.rs index e42e914..4234a46 100644 --- a/librashader-reflect/src/reflect/cross/glsl.rs +++ b/librashader-reflect/src/reflect/cross/glsl.rs @@ -165,4 +165,11 @@ impl CompileShader for CrossReflect { }, }) } + + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, ShaderCompileError> { + as CompileShader>::compile(*self, options) + } } diff --git a/librashader-reflect/src/reflect/cross/hlsl.rs b/librashader-reflect/src/reflect/cross/hlsl.rs index 9fddec9..ffacb74 100644 --- a/librashader-reflect/src/reflect/cross/hlsl.rs +++ b/librashader-reflect/src/reflect/cross/hlsl.rs @@ -128,4 +128,11 @@ impl CompileShader for CrossReflect { }, }) } + + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, ShaderCompileError> { + as CompileShader>::compile(*self, options) + } } diff --git a/librashader-reflect/src/reflect/naga/msl.rs b/librashader-reflect/src/reflect/naga/msl.rs index dfc110c..381a0ad 100644 --- a/librashader-reflect/src/reflect/naga/msl.rs +++ b/librashader-reflect/src/reflect/naga/msl.rs @@ -146,6 +146,13 @@ impl CompileShader for NagaReflect { }, }) } + + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, ShaderCompileError> { + >::compile(*self, options) + } } #[cfg(test)] diff --git a/librashader-reflect/src/reflect/naga/spirv.rs b/librashader-reflect/src/reflect/naga/spirv.rs index 7d95041..b092792 100644 --- a/librashader-reflect/src/reflect/naga/spirv.rs +++ b/librashader-reflect/src/reflect/naga/spirv.rs @@ -51,4 +51,11 @@ impl CompileShader for NagaReflect { }, }) } + + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, Self::Context>, ShaderCompileError> { + >::compile(*self, options) + } } diff --git a/librashader-reflect/src/reflect/naga/wgsl.rs b/librashader-reflect/src/reflect/naga/wgsl.rs index 388ba3f..f7cc834 100644 --- a/librashader-reflect/src/reflect/naga/wgsl.rs +++ b/librashader-reflect/src/reflect/naga/wgsl.rs @@ -38,4 +38,11 @@ impl CompileShader for NagaReflect { }, }) } + + fn compile_boxed( + self: Box, + options: Self::Options, + ) -> Result, ShaderCompileError> { + >::compile(*self, options) + } }