reflect: use a marker trait to remove need for macro when spelling out compilation artifact opaque type

This commit is contained in:
chyyran 2023-01-19 18:44:08 -05:00
parent 8dd60e2a5c
commit ef8b72b220
7 changed files with 63 additions and 40 deletions

View file

@ -33,6 +33,35 @@ pub trait CompileShader<T: OutputTarget> {
) -> Result<ShaderCompilerOutput<T::Output, Self::Context>, ShaderCompileError>;
}
/// Marker trait for combinations of targets and compilations that can be reflected and compiled
/// successfully.
///
/// This trait is automatically implemented for reflected outputs that have [`FromCompilation`](crate::back::FromCompilation) implement
/// for a given target that also implement [`CompileShader`](crate::back::CompileShader) for that target.
pub trait CompileReflectShader<T: OutputTarget, C>:
CompileShader<
T,
Options = <T as FromCompilation<C>>::Options,
Context = <T as FromCompilation<C>>::Context,
> + ReflectShader
where
T: FromCompilation<C>,
{
}
impl<T, C, O> CompileReflectShader<T, C> for O
where
T: OutputTarget,
T: FromCompilation<C>,
O: ReflectShader,
O: CompileShader<
T,
Options = <T as FromCompilation<C>>::Options,
Context = <T as FromCompilation<C>>::Context,
>,
{
}
impl<T, E> CompileShader<E> for CompilerBackend<T>
where
T: CompileShader<E>,

View file

@ -11,13 +11,29 @@ use rustc_hash::FxHashMap;
use std::error::Error;
/// Artifacts of a reflected and compiled shader pass.
pub type ShaderPassMeta<T> = (ShaderPassConfig, ShaderSource, CompilerBackend<T>);
///
/// The [`CompileReflectShader`](crate::back::CompileReflectShader) trait allows you to name
/// the type of compiler artifact returned by a pair of output shader target and compilation
/// instance as a TAIT like so.
///
/// ```rust
/// #![feature(type_alias_impl_trait)]
/// use librashader_reflect::back::CompileReflectShader;
/// use librashader_reflect::back::targets::SPIRV;
/// use librashader_reflect::front::GlslangCompilation;
/// use librashader_reflect::reflect::presets::ShaderPassArtifact;
///
/// type VulkanPassMeta = ShaderPassArtifact<impl CompileReflectShader<SPIRV, GlslangCompilation>>;
/// ```
///
/// This allows a runtime to not name the backing type of the compiled artifact if not necessary.
pub type ShaderPassArtifact<T> = (ShaderPassConfig, ShaderSource, CompilerBackend<T>);
impl<T: OutputTarget> CompilePreset for T {}
impl<T: OutputTarget> CompilePresetTarget for T {}
/// Trait for target shading languages that can compile output with
/// shader preset metdata.
pub trait CompilePreset: OutputTarget {
pub trait CompilePresetTarget: OutputTarget {
/// Compile passes of a shader preset given the applicable
/// shader output target, compilation type, and resulting error.
fn compile_preset_passes<C, E>(
@ -25,7 +41,7 @@ pub trait CompilePreset: OutputTarget {
textures: &[TextureConfig],
) -> Result<
(
Vec<ShaderPassMeta<<Self as FromCompilation<C>>::Output>>,
Vec<ShaderPassArtifact<<Self as FromCompilation<C>>::Output>>,
ShaderSemantics,
),
E,
@ -45,12 +61,12 @@ pub trait CompilePreset: OutputTarget {
/// Compile passes of a shader preset given the applicable
/// shader output target, compilation type, and resulting error.
pub(crate) fn compile_preset_passes<T, C, E>(
fn compile_preset_passes<T, C, E>(
passes: Vec<ShaderPassConfig>,
textures: &[TextureConfig],
) -> Result<
(
Vec<ShaderPassMeta<<T as FromCompilation<C>>::Output>>,
Vec<ShaderPassArtifact<<T as FromCompilation<C>>::Output>>,
ShaderSemantics,
),
E,

View file

@ -3,7 +3,7 @@ use librashader_common::{ImageFormat, Size, Viewport};
use librashader_presets::{ShaderPreset, TextureConfig};
use librashader_reflect::back::targets::HLSL;
use librashader_reflect::back::CompileShader;
use librashader_reflect::back::{CompileReflectShader, CompileShader};
use librashader_reflect::front::GlslangCompilation;
use librashader_reflect::reflect::semantics::{ShaderSemantics, TextureSemantics, UniformBinding};
use librashader_reflect::reflect::ReflectShader;
@ -22,8 +22,7 @@ use crate::render_target::RenderTarget;
use crate::samplers::SamplerSet;
use crate::util::d3d11_compile_bound_shader;
use crate::{error, util, D3D11OutputView};
use librashader_reflect::reflect::presets::CompilePreset;
use librashader_runtime::decl_shader_pass_meta;
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
use librashader_runtime::uniforms::UniformStorage;
use windows::Win32::Graphics::Direct3D11::{
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC,
@ -37,7 +36,7 @@ pub struct FilterMutable {
pub(crate) parameters: FxHashMap<String, f32>,
}
decl_shader_pass_meta!(type ShaderPassMeta = <HLSL, GlslangCompilation>);
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
/// A Direct3D 11 filter chain.
pub struct FilterChainD3D11 {

View file

@ -14,15 +14,14 @@ use librashader_common::{FilterMode, Viewport, WrapMode};
use librashader_presets::ShaderPreset;
use librashader_reflect::back::cross::GlslVersion;
use librashader_reflect::back::targets::GLSL;
use librashader_reflect::back::CompileShader;
use librashader_reflect::back::{CompileReflectShader, CompileShader};
use librashader_reflect::front::GlslangCompilation;
use librashader_reflect::reflect::semantics::{
MemberOffset, ShaderSemantics, TextureSemantics, UniformBinding, UniformMeta,
};
use librashader_reflect::reflect::presets::CompilePreset;
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
use librashader_reflect::reflect::ReflectShader;
use librashader_runtime::decl_shader_pass_meta;
use rustc_hash::FxHashMap;
use spirv_cross::spirv::Decoration;
use std::collections::VecDeque;
@ -81,7 +80,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
}
}
decl_shader_pass_meta!(type ShaderPassMeta = <GLSL, GlslangCompilation>);
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<GLSL, GlslangCompilation>>;
impl<T: GLInterface> FilterChainImpl<T> {
/// Load a filter chain from a pre-parsed `ShaderPreset`.

View file

@ -17,12 +17,11 @@ use librashader_common::{ImageFormat, Size, Viewport};
use librashader_presets::{ShaderPreset, TextureConfig};
use librashader_reflect::back::targets::SPIRV;
use librashader_reflect::back::CompileShader;
use librashader_reflect::back::{CompileReflectShader, CompileShader};
use librashader_reflect::front::GlslangCompilation;
use librashader_reflect::reflect::presets::CompilePreset;
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
use librashader_reflect::reflect::semantics::{ShaderSemantics, TextureSemantics, UniformBinding};
use librashader_reflect::reflect::ReflectShader;
use librashader_runtime::decl_shader_pass_meta;
use librashader_runtime::image::{Image, UVDirection};
use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap;
@ -38,7 +37,7 @@ pub struct VulkanObjects {
pipeline_cache: vk::PipelineCache,
}
decl_shader_pass_meta!(type ShaderPassMeta = <SPIRV, GlslangCompilation>);
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<SPIRV, GlslangCompilation>>;
/// A collection of handles needed to access the Vulkan instance.
#[derive(Clone)]

View file

@ -25,22 +25,3 @@ pub mod ringbuffer;
/// Generic implementation of semantics binding.
pub mod binding;
/// Used to declare a `ShaderPassMeta` type for the given target shader language and compilation type.
#[macro_export]
macro_rules! decl_shader_pass_meta {
(type $ty_name:ident = <$target:ty, $compilation:ty>) => {
type $ty_name =
librashader_reflect::reflect::presets::ShaderPassMeta<
impl librashader_reflect::back::CompileShader<
$target,
Options = <$target as librashader_reflect::back::FromCompilation<
$compilation,
>>::Options,
Context = <$target as librashader_reflect::back::FromCompilation<
$compilation,
>>::Context,
> + librashader_reflect::reflect::ReflectShader,
>;
};
}

View file

@ -89,8 +89,8 @@ pub mod reflect {
pub use librashader_reflect::reflect::{semantics, ReflectShader, ShaderReflection};
pub use librashader_reflect::back::{
targets::OutputTarget, CompileShader, CompilerBackend, FromCompilation,
ShaderCompilerOutput,
targets::OutputTarget, CompileReflectShader, CompileShader, CompilerBackend,
FromCompilation, ShaderCompilerOutput,
};
/// Reflection via SPIRV-Cross.
@ -113,7 +113,7 @@ pub mod reflect {
}
pub use librashader_reflect::reflect::semantics::BindingMeta;
pub use librashader_reflect::reflect::presets;
pub use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
pub use librashader_reflect::front::ShaderCompilation;
#[doc(hidden)]