reflect(msl): implement spirv-cross msl

This commit is contained in:
chyyran 2024-02-11 02:54:22 -05:00 committed by Ronny Chan
parent c67e9f4801
commit a495b693a6
7 changed files with 145 additions and 12 deletions

View file

@ -9,8 +9,6 @@ use crate::reflect::ReflectShader;
pub use spirv_cross::glsl::Version as GlslVersion;
use crate::reflect::cross::glsl::GlslReflect;
/// The HLSL shader model version to target.
pub use spirv_cross::hlsl::ShaderModel as HlslShaderModel;
/// The context for a GLSL compilation via spirv-cross.
pub struct CrossGlslContext {

View file

@ -5,7 +5,9 @@ use crate::front::SpirvCompilation;
use crate::reflect::cross::hlsl::HlslReflect;
use crate::reflect::cross::{CompiledProgram, SpirvCross};
use crate::reflect::ReflectShader;
use spirv_cross::hlsl::ShaderModel as HlslShaderModel;
/// The HLSL shader model version to target.
pub use spirv_cross::hlsl::ShaderModel as HlslShaderModel;
/// The context for a HLSL compilation via spirv-cross.
pub struct CrossHlslContext {

View file

@ -7,6 +7,9 @@ use crate::reflect::cross::{CompiledProgram, SpirvCross};
use crate::reflect::naga::{Naga, NagaReflect};
use crate::reflect::ReflectShader;
/// The HLSL shader model version to target.
pub use spirv_cross::msl::Version as MslVersion;
/// Compiler options for MSL
#[derive(Debug, Default, Clone)]
pub struct MslNagaCompileOptions {

View file

@ -1,9 +1,13 @@
use std::collections::BTreeMap;
use naga::{Module};
use crate::back::msl::CrossMslContext;
use crate::back::targets::MSL;
use crate::back::{CompileShader, ShaderCompilerOutput};
use crate::error::ShaderCompileError;
use crate::reflect::cross::{CompiledAst, CompiledProgram, CrossReflect};
use spirv_cross::msl;
use spirv_cross::msl::{ResourceBinding, ResourceBindingLocation};
use spirv_cross::spirv::{Ast, Decoration, ExecutionModel};
pub(crate) type MslReflect = CrossReflect<spirv_cross::msl::Target>;
@ -16,14 +20,65 @@ impl CompileShader<MSL> for CrossReflect<spirv_cross::msl::Target> {
options: Self::Options,
) -> Result<ShaderCompilerOutput<String, CrossMslContext>, ShaderCompileError> {
let version = options.unwrap_or(msl::Version::V2_0);
let mut options = spirv_cross::msl::CompilerOptions::default();
options.version = version;
let mut vert_options = spirv_cross::msl::CompilerOptions::default();
let mut frag_options = spirv_cross::msl::CompilerOptions::default();
// This is actually all sorts of broken because there's no way to change bindings
// with the current version of spirv_cross.
vert_options.version = version;
frag_options.version = version;
self.vertex.set_compiler_options(&options)?;
self.fragment.set_compiler_options(&options)?;
fn get_binding(ast: &Ast<msl::Target>, stage: ExecutionModel, binding_map: &mut BTreeMap<ResourceBindingLocation, ResourceBinding>) -> Result<(), ShaderCompileError>{
let resources = ast.get_shader_resources()?;
for resource in &resources.push_constant_buffers {
let location = ResourceBindingLocation {
stage,
desc_set: u32::MAX, // ResourceBindingPushConstantDescriptorSet
binding: 0,
};
let overridden = ResourceBinding {
buffer_id: ast.get_decoration(resource.id, Decoration::Binding)?,
texture_id: 0,
sampler_id: 0,
count: 0,
};
binding_map.insert(location, overridden);
}
for resource in resources.uniform_buffers.iter().chain(resources.sampled_images.iter()) {
let binding = ast.get_decoration(resource.id, Decoration::Binding)?;
let location = ResourceBindingLocation {
stage,
desc_set: ast.get_decoration(resource.id, Decoration::DescriptorSet)?,
binding,
};
let overridden = ResourceBinding {
buffer_id: binding,
texture_id: binding,
sampler_id: binding,
count: 0,
};
binding_map.insert(location, overridden);
}
Ok(())
}
get_binding(
&self.vertex,
ExecutionModel::Vertex,
&mut vert_options.resource_binding_overrides
)?;
get_binding(
&self.fragment,
ExecutionModel::Fragment,
&mut frag_options.resource_binding_overrides
)?;
self.vertex.set_compiler_options(&vert_options)?;
self.fragment.set_compiler_options(&frag_options)?;
Ok(ShaderCompilerOutput {
vertex: self.vertex.compile()?,
@ -37,3 +92,68 @@ impl CompileShader<MSL> for CrossReflect<spirv_cross::msl::Target> {
})
}
}
#[cfg(test)]
mod test {
use crate::back::targets::{MSL, WGSL};
use crate::back::{CompileShader, FromCompilation};
use crate::reflect::naga::{Naga, NagaLoweringOptions};
use crate::reflect::semantics::{Semantic, ShaderSemantics, UniformSemantic, UniqueSemantics};
use crate::reflect::ReflectShader;
use librashader_preprocess::ShaderSource;
use rustc_hash::FxHashMap;
use bitflags::Flags;
use spirv_cross::msl;
use crate::reflect::cross::SpirvCross;
#[test]
pub fn test_into() {
// let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
// let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
let result = ShaderSource::load("../test/basic.slang").unwrap();
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
for (_index, param) in result.parameters.iter().enumerate() {
uniform_semantics.insert(
param.1.id.clone(),
UniformSemantic::Unique(Semantic {
semantics: UniqueSemantics::FloatParameter,
index: (),
}),
);
}
let compilation = crate::front::SpirvCompilation::try_from(&result).unwrap();
let mut msl = <MSL as FromCompilation<_, SpirvCross>>::from_compilation(compilation).unwrap();
msl.reflect(
0,
&ShaderSemantics {
uniform_semantics,
texture_semantics: Default::default(),
},
)
.expect("");
let compiled = msl
.compile(Some(msl::Version::V2_0))
.unwrap();
println!("{}", compiled.fragment);
// println!("{}", compiled.fragment);
// let mut loader = rspirv::dr::Loader::new();
// rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap();
// let module = loader.module();
//
// let outputs: Vec<&Instruction> = module
// .types_global_values
// .iter()
// .filter(|i| i.class.opcode == Op::Variable)
// .collect();
//
// println!("{outputs:#?}");
}
}

View file

@ -1,3 +1,4 @@
use naga::{Module, ResourceBinding};
use crate::back::targets::MSL;
use crate::back::{CompileShader, ShaderCompilerOutput};
use crate::error::ShaderCompileError;
@ -11,6 +12,7 @@ impl CompileShader<MSL> for NagaReflect {
self,
options: Self::Options,
) -> Result<ShaderCompilerOutput<String, Self::Context>, ShaderCompileError> {
// https://github.com/libretro/RetroArch/blob/434e94c782af2e4d4277a24b7ed8e5fc54870088/gfx/drivers_shader/slang_process.cpp#L524
todo!()
}
}

View file

@ -20,7 +20,6 @@ use std::sync::Arc;
use crate::buffer::WgpuStagedBuffer;
use crate::draw_quad::DrawQuad;
use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode};
use librashader_reflect::back::wgsl::WgslCompileOptions;
use librashader_reflect::reflect::naga::{Naga, NagaLoweringOptions};
use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::render_target::RenderTarget;

View file

@ -156,18 +156,26 @@ pub mod reflect {
#[cfg(feature = "reflect-cross")]
#[doc(cfg(feature = "reflect-cross"))]
pub mod cross {
pub use librashader_reflect::reflect::cross::SpirvCross;
/// The version of GLSL to target.
///
pub use librashader_reflect::back::glsl::GlslVersion;
/// The HLSL Shader Model to target.
///
pub use librashader_reflect::back::glsl::HlslShaderModel;
pub use librashader_reflect::back::hlsl::HlslShaderModel;
/// The MSL version to target.
///
pub use librashader_reflect::back::msl::MslVersion;
pub use librashader_reflect::back::glsl::CrossGlslContext;
pub use librashader_reflect::back::hlsl::CrossHlslContext;
pub use librashader_reflect::back::msl::CrossMslContext;
pub use librashader_reflect::reflect::cross::CompiledAst;
pub use librashader_reflect::reflect::cross::CompiledProgram;
@ -188,8 +196,9 @@ pub mod reflect {
#[cfg(feature = "reflect-naga")]
#[doc(cfg(feature = "reflect-naga"))]
pub mod naga {
pub use librashader_reflect::reflect::naga::Naga;
pub use librashader_reflect::back::wgsl::NagaWgslContext;
pub use librashader_reflect::back::wgsl::WgslCompileOptions;
pub use librashader_reflect::reflect::naga::NagaLoweringOptions;
}
pub use librashader_reflect::reflect::semantics::BindingMeta;