From b618cbb5e9c2733eebb88f32e85a275d0bccfc1f Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Sun, 10 May 2026 17:06:00 +0200 Subject: [PATCH] rusticl/kernel: handle nir shader compilation failures gracefully Part-of: --- src/gallium/frontends/rusticl/core/kernel.rs | 14 ++++++++++---- src/gallium/frontends/rusticl/core/program.rs | 18 ++++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/gallium/frontends/rusticl/core/kernel.rs b/src/gallium/frontends/rusticl/core/kernel.rs index edc4441e868..f3b0fd8cdb9 100644 --- a/src/gallium/frontends/rusticl/core/kernel.rs +++ b/src/gallium/frontends/rusticl/core/kernel.rs @@ -1227,7 +1227,7 @@ pub(super) fn convert_spirv_to_nir( args: &[spirv::SPIRVKernelArg], spec_constants: &mut HashMap>, dev: &'static Device, -) -> SPIRVToNirResult { +) -> Option { let cache = dev.screen().shader_cache(); let key = build.hash_key(cache.as_ref(), name, spec_constants); let spirv_info = build.kernel_info(name).unwrap(); @@ -1236,8 +1236,8 @@ pub(super) fn convert_spirv_to_nir( .as_ref() .and_then(|cache| cache.get(&mut key?)) .and_then(|entry| SPIRVToNirResult::deserialize(&entry, dev, spirv_info)) - .unwrap_or_else(|| { - let nir = build.to_nir(name, dev, spec_constants); + .or_else(|| { + let nir = build.to_nir(name, dev, spec_constants)?; if Platform::dbg().nir { eprintln!("=== Printing nir for '{name}' after spirv_to_nir"); @@ -1270,7 +1270,13 @@ pub(super) fn convert_spirv_to_nir( } } - SPIRVToNirResult::new(dev, spirv_info, args, default_build, optimized) + Some(SPIRVToNirResult::new( + dev, + spirv_info, + args, + default_build, + optimized, + )) }) } diff --git a/src/gallium/frontends/rusticl/core/program.rs b/src/gallium/frontends/rusticl/core/program.rs index b0f96f9e463..2a13a0f6523 100644 --- a/src/gallium/frontends/rusticl/core/program.rs +++ b/src/gallium/frontends/rusticl/core/program.rs @@ -137,8 +137,13 @@ impl ProgramBuild { continue; } - let build_result = - convert_spirv_to_nir(build, kernel_name, &args, &mut self.spec_constants, dev); + let Some(build_result) = + convert_spirv_to_nir(build, kernel_name, &args, &mut self.spec_constants, dev) + else { + build.status = CL_BUILD_ERROR; + build.log = "Internal compilation error".to_owned(); + return; + }; kernel_info_set.insert(build_result.kernel_info); self.builds_by_device.get_mut(dev).unwrap().kernels.insert( @@ -147,6 +152,11 @@ impl ProgramBuild { ); } + // If all devices failed to rebuilt their kernels we simply return here. + if kernel_info_set.is_empty() { + return; + } + // we want the same (internal) args for every compiled kernel, for now assert_eq!(kernel_info_set.len(), 1); let mut kernel_info = kernel_info_set.into_iter().next().unwrap(); @@ -223,7 +233,7 @@ impl DeviceProgramBuild { kernel: &str, device: &Device, spec_constants: &mut HashMap>, - ) -> NirShader { + ) -> Option { assert_eq!(self.status, CL_BUILD_SUCCESS as cl_build_status); let mut spec_constants: Vec<_> = spec_constants @@ -260,7 +270,7 @@ impl DeviceProgramBuild { } }; - nir.unwrap() + nir } fn is_success(&self) -> bool {