reflect: remove rspirv

When naga is more mature (i.e. with support for COMBINED_IMAGE_SAMPLER), `naga::Module` handles everything we need with a more ergonomic API
This commit is contained in:
chyyran 2023-01-15 18:36:38 -05:00
parent c059e7c566
commit aea440f194
10 changed files with 116 additions and 124 deletions

31
Cargo.lock generated
View file

@ -434,15 +434,6 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]]
name = "gfx-maths"
version = "0.2.8"
@ -694,8 +685,6 @@ dependencies = [
"librashader-common",
"librashader-preprocess",
"naga",
"rspirv",
"rspirv-reflect",
"rustc-hash",
"shaderc",
"spirv_cross",
@ -1233,26 +1222,6 @@ dependencies = [
"xmlparser",
]
[[package]]
name = "rspirv"
version = "0.11.0+1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1503993b59ca9ae4127365c3293517576d7ce56be9f3d8abb1625c85ddc583ba"
dependencies = [
"fxhash",
"num-traits",
"spirv",
]
[[package]]
name = "rspirv-reflect"
version = "0.7.0"
source = "git+https://github.com/Traverse-Research/rspirv-reflect#8894d3570cd738c61e26b08349f55277092b9e3c"
dependencies = [
"rspirv",
"thiserror",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"

View file

@ -15,7 +15,6 @@ description = "RetroArch shaders for all."
shaderc = { version = "0.8.1", features = [] }
spirv_cross = { version = "0.23.1", features = [ "glsl", "hlsl" ] }
thiserror = "1.0.37"
bitflags = "1.3.2"
rustc-hash = "1.1.0"
@ -24,12 +23,10 @@ librashader-common = { path = "../librashader-common", version = "0.1.0-beta.6"
librashader-preprocess = { path = "../librashader-preprocess", version = "0.1.0-beta.6" }
naga = { version = "0.10.0", features = ["glsl-in", "spv-in", "spv-out", "glsl-out", "wgsl-out"], optional = true }
rspirv = { version = "0.11.0+1.5.4", optional = true }
rspirv-reflect = { git = "https://github.com/Traverse-Research/rspirv-reflect", optional = true, version = "0.7.0" }
[features]
default = []
unstable-rust-pipeline = [ "naga", "rspirv", "rspirv-reflect" ]
unstable-naga = [ "naga" ]
standalone = ["shaderc/build-from-source"]
[dev-dependencies]

View file

@ -6,7 +6,7 @@ use thiserror::Error;
#[derive(Error, Debug)]
pub enum ShaderCompileError {
/// Compile error from naga.
#[cfg(feature = "unstable-rust-pipeline")]
#[cfg(feature = "unstable-naga")]
#[error("shader")]
NagaCompileError(Vec<naga::front::glsl::Error>),
@ -55,15 +55,10 @@ pub enum SemanticsErrorKind {
#[derive(Error, Debug)]
pub enum ShaderReflectError {
/// Compile error from naga.
#[cfg(feature = "unstable-rust-pipeline")]
#[cfg(feature = "unstable-naga")]
#[error("shader")]
NagaCompileError(#[from] naga::front::spv::Error),
/// Parse error from rspirv.
#[cfg(feature = "unstable-rust-pipeline")]
#[error("rspirv")]
RspirvParseError(#[from] rspirv::binary::ParseState),
/// Reflection error from spirv-cross.
#[error("spirv")]
SpirvCrossError(#[from] spirv_cross::ErrorCode),
@ -99,7 +94,7 @@ pub enum ShaderReflectError {
BindingInUse(u32),
}
#[cfg(feature = "unstable-rust-pipeline")]
#[cfg(feature = "unstable-naga")]
impl From<Vec<naga::front::glsl::Error>> for ShaderCompileError {
fn from(err: Vec<naga::front::glsl::Error>) -> Self {
ShaderCompileError::NagaCompileError(err)

View file

@ -1,4 +1,4 @@
#[cfg(feature = "unstable-rust-pipeline")]
#[cfg(feature = "unstable-naga")]
pub mod naga;
pub mod shaderc;

View file

@ -116,7 +116,9 @@ fn get_shaderc_options() -> Result<CompileOptions<'static>, ShaderCompileError>
Ok(options)
}
fn compile_spirv(source: &ShaderSource) -> Result<GlslangCompilation, ShaderCompileError> {
pub(crate) fn compile_spirv(
source: &ShaderSource,
) -> Result<GlslangCompilation, ShaderCompileError> {
let compiler = shaderc::Compiler::new().ok_or(ShaderCompileError::ShaderCInitError)?;
let name = source.name.as_deref().unwrap_or("shader.slang");
let options = get_shaderc_options()?;

View file

@ -16,6 +16,7 @@ use spirv_cross::{glsl, hlsl, ErrorCode};
use crate::back::cross::{CrossGlslContext, CrossHlslContext};
use crate::back::targets::{GLSL, HLSL};
use crate::back::{CompileShader, ShaderCompilerOutput};
use crate::reflect::helper::{SemanticErrorBlame, TextureData, UboData};
pub struct CrossReflect<T>
where
@ -223,37 +224,6 @@ where
}
}
struct UboData {
// id: u32,
// descriptor_set: u32,
binding: u32,
size: u32,
}
struct TextureData<'a> {
// id: u32,
// descriptor_set: u32,
name: &'a str,
binding: u32,
}
// todo: might want to take these crate helpers out.
#[derive(Copy, Clone)]
enum SemanticErrorBlame {
Vertex,
Fragment,
}
impl SemanticErrorBlame {
fn error(self, kind: SemanticsErrorKind) -> ShaderReflectError {
match self {
SemanticErrorBlame::Vertex => ShaderReflectError::VertexSemanticError(kind),
SemanticErrorBlame::Fragment => ShaderReflectError::FragmentSemanticError(kind),
}
}
}
impl<T> CrossReflect<T>
where
T: spirv_cross::spirv::Target,
@ -879,7 +849,7 @@ mod test {
for (_index, param) in result.parameters.iter().enumerate() {
uniform_semantics.insert(
param.id.clone(),
param.1.id.clone(),
UniformSemantic::Unique(Semantic {
semantics: UniqueSemantics::FloatParameter,
index: (),

View file

@ -0,0 +1,32 @@
use crate::error::{SemanticsErrorKind, ShaderReflectError};
pub struct UboData {
// id: u32,
// descriptor_set: u32,
pub binding: u32,
pub size: u32,
}
pub struct TextureData<'a> {
// id: u32,
// descriptor_set: u32,
pub name: &'a str,
pub binding: u32,
}
// todo: might want to take these crate helpers out.
#[derive(Copy, Clone)]
pub enum SemanticErrorBlame {
Vertex,
Fragment,
}
impl SemanticErrorBlame {
pub fn error(self, kind: SemanticsErrorKind) -> ShaderReflectError {
match self {
SemanticErrorBlame::Vertex => ShaderReflectError::VertexSemanticError(kind),
SemanticErrorBlame::Fragment => ShaderReflectError::FragmentSemanticError(kind),
}
}
}

View file

@ -7,10 +7,10 @@ pub mod cross;
/// Shader semantics and reflection information.
pub mod semantics;
#[cfg(feature = "unstable-rust-pipeline")]
mod helper;
#[cfg(feature = "unstable-naga")]
mod naga;
#[cfg(feature = "unstable-rust-pipeline")]
mod rspirv;
/// A trait for compilation outputs that can provide reflection information.
pub trait ReflectShader {

View file

@ -1,8 +1,11 @@
use crate::error::ShaderReflectError;
use crate::error::{SemanticsErrorKind, ShaderReflectError};
use crate::front::naga::NagaCompilation;
use crate::front::shaderc::GlslangCompilation;
use crate::reflect::helper::SemanticErrorBlame;
use crate::reflect::semantics::MAX_BINDINGS_COUNT;
use naga::front::spv::Options;
use naga::Module;
use naga::{Arena, GlobalVariable, Handle, Module, ResourceBinding, StructMember, Type, TypeInner};
use std::convert::Infallible;
#[derive(Debug)]
pub struct NagaReflect {
@ -36,12 +39,77 @@ impl TryFrom<GlslangCompilation> for NagaReflect {
}
}
struct UboData {
// id: u32,
// descriptor_set: u32,
binding: u32,
size: u32,
}
struct Ubo {
members: Vec<StructMember>,
span: u32,
}
impl TryFrom<naga::Type> for Ubo {
type Error = Infallible;
fn try_from(value: Type) -> Result<Self, Infallible> {
match value.inner {
TypeInner::Struct { members, span } => Ok(Ubo { members, span }),
// todo: make this programmer error
_ => panic!(),
}
}
}
impl NagaReflect {
// pub fn get_ubo_data(arena: Arena, variable: GlobalVariable, blame: SemanticErrorBlame) -> Result<UboData, ShaderReflectError> {
// let binding = match variable.binding {
// Some(ResourceBinding { group: 0, binding }) => binding,
// Some(ResourceBinding { group, .. }) => return Err(blame.error(SemanticsErrorKind::InvalidDescriptorSet(group))),
// None => return Err(blame.error(SemanticsErrorKind::InvalidDescriptorSet(u32::MAX))),
// };
//
// if binding >= MAX_BINDINGS_COUNT {
// return Err(blame.error(SemanticsErrorKind::InvalidBinding(binding)));
// }
//
// match variable.ty.as {
// Handle { .. } => {}
// }
// Ok(UboData {
// binding,
//
// })
// }
pub fn reflect_ubos(
vertex: GlobalVariable,
fragment: GlobalVariable,
) -> Result<(), ShaderReflectError> {
match (vertex.binding, fragment.binding) {
// todo: should emit for both but whatever
(None, None) | (Some(_), None) | (None, Some(_)) => {
ShaderReflectError::VertexSemanticError(SemanticsErrorKind::InvalidDescriptorSet(
u32::MAX,
))
}
(Some(vert), Some(frag)) => {
todo!();
}
};
todo!();
Ok(())
}
}
#[cfg(test)]
mod test {
use librashader_preprocess::ShaderSource;
#[test]
pub fn test_into() {
let result = librashader_preprocess::load_shader_source("../test/basic.slang").unwrap();
let result = ShaderSource::load("../test/basic.slang").unwrap();
let _spirv = crate::front::shaderc::compile_spirv(&result).unwrap();
}
}

View file

@ -1,41 +0,0 @@
use crate::error::ShaderReflectError;
use crate::front::shaderc::GlslangCompilation;
use rspirv_reflect::Reflection;
use shaderc::CompilationArtifact;
pub struct RspirvReflect {
vertex: Reflection,
fragment: Reflection,
}
fn parse_reflection(artifact: CompilationArtifact) -> Result<Reflection, ShaderReflectError> {
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(artifact.as_binary(), &mut loader)?;
Ok(Reflection::new(loader.module()))
}
impl TryFrom<GlslangCompilation> for RspirvReflect {
type Error = ShaderReflectError;
fn try_from(value: GlslangCompilation) -> Result<Self, Self::Error> {
let vertex = parse_reflection(value.vertex)?;
let fragment = parse_reflection(value.fragment)?;
Ok(RspirvReflect { vertex, fragment })
}
}
#[cfg(test)]
mod test {
use crate::reflect::rspirv::RspirvReflect;
#[test]
pub fn test_into() {
let result = librashader_preprocess::load_shader_source("../test/basic.slang").unwrap();
let spirv = crate::front::shaderc::compile_spirv(&result).unwrap();
let reflect = RspirvReflect::try_from(spirv).unwrap();
// let pcr = reflect.fragment.get_push_constant_range().unwrap()
// .unwrap();
println!("{:?}", reflect.fragment.get_descriptor_sets());
// println!("PushConstantInfo size: {}, off: {}", pcr.size, pcr.offset);
}
}