Skip to content

Commit

Permalink
naga/wgpu/wgpu-core: improve spirv parse error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
waynr committed Jan 17, 2024
1 parent 3ea0ec8 commit 0061d54
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions naga/src/front/spv/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use super::ModuleState;
use crate::arena::Handle;
use codespan_reporting::diagnostic::Diagnostic;
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term;
use termcolor::{NoColor, WriteColor};

#[derive(Debug, thiserror::Error)]
pub enum Error {
Expand Down Expand Up @@ -127,3 +131,24 @@ pub enum Error {
)]
NonBindingArrayOfImageOrSamplers,
}

impl Error {
pub fn emit_to_writer(&self, writer: &mut impl WriteColor, source: &str) {
self.emit_to_writer_with_path(writer, source, "glsl");
}

pub fn emit_to_writer_with_path(&self, writer: &mut impl WriteColor, source: &str, path: &str) {
let path = path.to_string();
let files = SimpleFile::new(path, source);
let config = codespan_reporting::term::Config::default();
let diagnostic = Diagnostic::error().with_message(format!("{self:?}"));

term::emit(writer, &config, &files, &diagnostic).expect("cannot write error");
}

pub fn emit_to_string(&self, source: &str) -> String {
let mut writer = NoColor::new(Vec::new());
self.emit_to_writer(&mut writer, source);
String::from_utf8(writer.into_inner()).unwrap()
}
}
4 changes: 4 additions & 0 deletions wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ wgsl = ["naga/wgsl-in"]
## Enable `ShaderModuleSource::Glsl`
glsl = ["naga/glsl-in"]

## Enable `ShaderModuleSource::SpirV`
spirv = ["naga/spv-in", "dep:zerocopy"]

## Implement `Send` and `Sync` on Wasm, but only if atomics are not enabled.
##
## WebGL/WebGPU objects can not be shared between threads.
Expand Down Expand Up @@ -109,6 +112,7 @@ rustc-hash = "1.1"
serde = { version = "1", features = ["serde_derive"], optional = true }
smallvec = "1"
thiserror = "1"
zerocopy = { version = "0.7", optional = true }

[dependencies.naga]
path = "../naga"
Expand Down
6 changes: 6 additions & 0 deletions wgpu-core/src/device/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ use crate::{
use arrayvec::ArrayVec;
use hal::Device as _;
use parking_lot::RwLock;
#[cfg(feature = "spirv")]
use zerocopy::AsBytes;

use wgt::{BufferAddress, TextureFormat};

Expand Down Expand Up @@ -1193,6 +1195,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pipeline::ShaderModuleSource::Glsl(ref code, _) => {
trace.make_binary("glsl", code.as_bytes())
}
#[cfg(feature = "spirv")]
pipeline::ShaderModuleSource::SpirV(ref code, _) => {
trace.make_binary("spirv", code.as_bytes())
}
pipeline::ShaderModuleSource::Naga(ref module) => {
let string =
ron::ser::to_string_pretty(module, ron::ser::PrettyConfig::default())
Expand Down
13 changes: 13 additions & 0 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,19 @@ impl<A: HalApi> Device<A> {
})?;
(Cow::Owned(module), code.into_owned())
}
#[cfg(feature = "spirv")]
pipeline::ShaderModuleSource::SpirV(spv, options) => {
let parser = naga::front::spv::Frontend::new(spv.iter().cloned(), &options);
profiling::scope!("naga::front::spv::Frontend");
let module = parser.parse().map_err(|inner| {
pipeline::CreateShaderModuleError::ParsingSpirV(pipeline::ShaderError {
source: String::new(),
label: desc.label.as_ref().map(|l| l.to_string()),
inner: Box::new(inner),
})
})?;
(Cow::Owned(module), String::new())
}
#[cfg(feature = "glsl")]
pipeline::ShaderModuleSource::Glsl(code, options) => {
let mut parser = naga::front::glsl::Frontend::default();
Expand Down
12 changes: 12 additions & 0 deletions wgpu-core/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum ShaderModuleSource<'a> {
Wgsl(Cow<'a, str>),
#[cfg(feature = "glsl")]
Glsl(Cow<'a, str>, naga::front::glsl::Options),
#[cfg(feature = "spirv")]
SpirV(Cow<'a, [u32]>, naga::front::spv::Options),
Naga(Cow<'static, naga::Module>),
/// Dummy variant because `Naga` doesn't have a lifetime and without enough active features it
/// could be the last one active.
Expand Down Expand Up @@ -112,6 +114,13 @@ impl fmt::Display for ShaderError<naga::front::glsl::ParseError> {
write!(f, "\nShader '{label}' parsing {string}")
}
}
impl fmt::Display for ShaderError<naga::front::spv::Error> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = self.label.as_deref().unwrap_or_default();
let string = self.inner.emit_to_string(&self.source);
write!(f, "\nShader '{label}' parsing {string}")
}
}
impl fmt::Display for ShaderError<naga::WithSpan<naga::valid::ValidationError>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use codespan_reporting::{
Expand Down Expand Up @@ -163,6 +172,9 @@ pub enum CreateShaderModuleError {
#[cfg(feature = "glsl")]
#[error(transparent)]
ParsingGlsl(#[from] ShaderError<naga::front::glsl::ParseError>),
#[cfg(feature = "spirv")]
#[error(transparent)]
ParsingSpirV(#[from] ShaderError<naga::front::spv::Error>),
#[error("Failed to generate the backend-specific code")]
Generation,
#[error(transparent)]
Expand Down
4 changes: 1 addition & 3 deletions wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,9 +844,7 @@ impl crate::Context for ContextWgpuCore {
strict_capabilities: true,
block_ctx_dump_prefix: None,
};
let parser = naga::front::spv::Frontend::new(spv.iter().cloned(), &options);
let module = parser.parse().unwrap();
wgc::pipeline::ShaderModuleSource::Naga(Owned(module))
wgc::pipeline::ShaderModuleSource::SpirV(Borrowed(spv), options)
}
#[cfg(feature = "glsl")]
ShaderSource::Glsl {
Expand Down

0 comments on commit 0061d54

Please sign in to comment.