{"record":{"id":"a64f02e5ab4a0655","repo":"gfx-rs/wgpu","slug":"not-implemented-a64f02","errorCode":null,"errorMessage":"not implemented","messagePattern":"not implemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"naga/src/back/spv/writer.rs","lineNumber":2017,"sourceCode":"            }\n        }\n    }\n\n    fn request_type_capabilities(&mut self, inner: &crate::TypeInner) -> Result<(), Error> {\n        match *inner {\n            crate::TypeInner::Image {\n                dim,\n                arrayed,\n                class,\n            } => {\n                let sampled = match class {\n                    crate::ImageClass::Sampled { .. } => true,\n                    crate::ImageClass::Depth { .. } => true,\n                    crate::ImageClass::Storage { format, .. } => {\n                        self.request_image_format_capabilities(format.into())?;\n                        false\n                    }\n                    crate::ImageClass::External => unimplemented!(),\n                };\n\n                match dim {\n                    crate::ImageDimension::D1 => {\n                        if sampled {\n                            self.require_any(\"sampled 1D images\", &[spirv::Capability::Sampled1D])?;\n                        } else {\n                            self.require_any(\"1D storage images\", &[spirv::Capability::Image1D])?;\n                        }\n                    }\n                    crate::ImageDimension::Cube if arrayed => {\n                        if sampled {\n                            self.require_any(\n                                \"sampled cube array images\",\n                                &[spirv::Capability::SampledCubeArray],\n                            )?;\n                        } else {\n                            self.require_any(","sourceCodeStart":1999,"sourceCodeEnd":2035,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/naga/src/back/spv/writer.rs#L1999-L2035","documentation":"The SPIR-V backend of naga does not implement the `ImageClass::External` texture class (external images, e.g. VK_EXT_external_memory / GL_TEXTURE_EXTERNAL_OES style images). When write_type_declaration_arena processes a type whose inner type is an external image, request_type_capabilities hits an unimplemented!() and panics, aborting shader translation.","triggerScenarios":"Compiling a WGSL/GLSL/SPIR-V shader that declares a texture whose naga IR type has ImageClass::External, then translating it to SPIR-V via naga's spv backend.","commonSituations":"Frontends producing naga IR with external image types (e.g. Android/HAL camera or video surface textures, GL external textures) being fed into the SPIR-V writer; naga's SPIR-V export path simply lacks support for this feature.","solutions":["Replace the external image type with a standard Sampled or Storage image type in the shader/IR before SPIR-V export","Use a backend that supports external images (e.g. the GLSL backend, or handle the texture in the app via separate bind types)","Check naga releases/issues for external image SPIR-V support and upgrade when available","Pre-validate the module: walk crate::Module types and reject ImageClass::External before calling the spv backend"],"exampleFix":"// before: IR contains TypeInner::Image { class: ImageClass::External, .. }\n// after: rewrite to a sampled image\n// let inner = TypeInner::Image { dim, arrayed, class: crate::ImageClass::Sampled { kind: ScalarKind::Float, multi: false } };","handlingStrategy":"validation","validationCode":"fn uses_external_image(module: &naga::Module) -> bool {\n    module.types.iter().any(|(_, t)| matches!(t.inner, naga::TypeInner::Image { class: naga::ImageClass::External, .. }))\n}\n// if uses_external_image(&module) { fall back to another backend or rewrite the type }","typeGuard":"fn is_external_image(inner: &naga::TypeInner) -> bool {\n    matches!(inner, naga::TypeInner::Image { class: naga::ImageClass::External, .. })\n}","tryCatchPattern":"// naga returns Result for translation; the panic here aborts the process, so pre-validate instead of catching\nlet result = naga::back::spv::write_vec(&module, &header, &options, &pipeline);\nmatch result { Ok(spv) => ..., Err(e) => eprintln!(\"spv export failed: {e}\") }","preventionTips":["Pre-scan naga IR for ImageClass::External before SPIR-V export","Keep external textures out of shaders targeted at SPIR-V","Pin to naga versions matching your IR feature set and read backend limitation docs"],"tags":["naga","spirv","unimplemented","shader-translation"],"backgroundTag":"unimplemented-feature-panic","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}