reflect(msl): implement spirv-cross msl
This commit is contained in:
parent
c67e9f4801
commit
a495b693a6
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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:#?}");
|
||||
}
|
||||
}
|
|
@ -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!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue