gfx-rs/wgpu-rs

failed to create graphics pipeline: Implementation specific error occurred (Mac OS)

bonsairobo opened this issue · 22 comments

The Failure

When running a bevy (rev d9fb61d4) app, I hit the following error on startup:

thread 'main' panicked at 'failed to create graphics pipeline: Implementation specific error occurred'

Reproducing the Failure

This is reliably reproduced by running this on Mac OS 10.14.6:

git lfs install
git clone https://github.com/bonsairobo/building-blocks
cd building-blocks
cargo run --example array_texture_materials

This does not fail on Windows 10. I suspect it is a compatibility issue with the metal shading language or API.

Materials

Source

The shader code of interest for this example is here: https://github.com/bonsairobo/building-blocks/blob/main/examples/array_texture_materials/array_texture_materials.rs

Stack trace

thread 'main' panicked at 'failed to create graphics pipeline: Implementation specific error occurred', /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-core-0.7.1/src/device/mod.rs:2251:26
stack backtrace:
   0: rust_begin_unwind
             at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
   1: std::panicking::begin_panic_fmt
             at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:435:5
   2: wgpu_core::device::Device<B>::create_render_pipeline::{{closure}}
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-core-0.7.1/src/device/mod.rs:2251:26
   3: core::result::Result<T,E>::map_err
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:595:27
   4: wgpu_core::device::Device<B>::create_render_pipeline
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-core-0.7.1/src/device/mod.rs:2247:13
   5: wgpu_core::device::<impl wgpu_core::hub::Global<G>>::device_create_render_pipeline
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-core-0.7.1/src/device/mod.rs:3856:73
   6: <wgpu::backend::direct::Context as wgpu::Context>::device_create_render_pipeline
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.0/src/backend/direct.rs:1034:30
   7: wgpu::Device::create_render_pipeline
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.0/src/lib.rs:1559:17
   8: <bevy_wgpu::renderer::wgpu_render_resource_context::WgpuRenderResourceContext as bevy_render::renderer::render_resource_context::RenderResourceContext>::create_render_pipeline
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs:510:31
   9: bevy_render::pipeline::pipeline_compiler::PipelineCompiler::compile_pipeline
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_render/src/pipeline/pipeline_compiler.rs:249:9
  10: bevy_render::draw::DrawContext::set_pipeline
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_render/src/draw.rs:186:13
  11: bevy_render::pipeline::render_pipelines::draw_render_pipelines_system
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_render/src/pipeline/render_pipelines.rs:139:13
  12: core::ops::function::Fn::call
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:70:5
  13: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:247:13
  14: <Func as bevy_ecs::system::into_system::IntoSystem<(A,B,C,D,E),bevy_ecs::system::into_system::FuncSystem<Out>>>::system::{{closure}}
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_ecs/src/system/into_system.rs:259:38
  15: bevy_ecs::schedule::executor_parallel::ParallelExecutor::prepare_systems::{{closure}}
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_ecs/src/schedule/executor_parallel.rs:244:30
  16: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  17: async_executor::Executor::spawn::{{closure}}
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.0/src/lib.rs:138:13
  18: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  19: async_task::raw::RawTask<F,T,S>::run
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/raw.rs:489:20
  20: async_executor::Executor::try_tick
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.0/src/lib.rs:175:17
  21: bevy_tasks::task_pool::TaskPool::scope::{{closure}}
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_tasks/src/task_pool.rs:221:21
  22: std::thread::local::LocalKey<T>::try_with
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:272:16
  23: std::thread::local::LocalKey<T>::with
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:248:9
  24: bevy_tasks::task_pool::TaskPool::scope
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_tasks/src/task_pool.rs:169:9
  25: <bevy_ecs::schedule::executor_parallel::ParallelExecutor as bevy_ecs::schedule::executor::ParallelSystemExecutor>::run_systems
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_ecs/src/schedule/executor_parallel.rs:169:9
  26: <bevy_ecs::schedule::stage::SystemStage as bevy_ecs::schedule::stage::Stage>::run
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_ecs/src/schedule/stage.rs:592:13
  27: bevy_ecs::schedule::Schedule::run_once
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_ecs/src/schedule/mod.rs:198:13
  28: <bevy_ecs::schedule::Schedule as bevy_ecs::schedule::stage::Stage>::run
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_ecs/src/schedule/mod.rs:209:21
  29: bevy_winit::winit_runner_with::{{closure}}
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_winit/src/lib.rs:486:17
  30: <alloc::boxed::Box<F,A> as core::ops::function::FnMut<Args>>::call_mut
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1335:9
  31: <winit::platform_impl::platform::app_state::EventLoopHandler<T> as winit::platform_impl::platform::app_state::EventHandler>::handle_nonuser_event
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/app_state.rs:71:9
  32: winit::platform_impl::platform::app_state::Handler::handle_nonuser_event
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/app_state.rs:173:21
  33: winit::platform_impl::platform::app_state::AppState::cleared
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/app_state.rs:331:13
  34: ____CFXPCCreateCFObjectFromXPCObject_block_invoke
  35: ___CFRunLoopObserverCancel
  36: ___CFRunLoopRun
  37: ___CFTSRToDispatchTime
  38: _RunCurrentEventLoopInMode
  39: _ReceiveNextEventCommon
  40: __BlockUntilNextEventMatchingListInModeWithFilter
  41: __DPSNextEvent
  42: -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]
  43: -[NSApplication run]
  44: <() as objc::message::MessageArguments>::invoke
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:128:17
  45: objc::message::platform::send_unverified
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/objc-0.2.7/src/message/apple/mod.rs:27:9
  46: objc::message::send_message
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:178:5
  47: winit::platform_impl::platform::event_loop::EventLoop<T>::run_return
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/event_loop.rs:106:25
  48: winit::platform_impl::platform::event_loop::EventLoop<T>::run
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/event_loop.rs:93:9
  49: winit::event_loop::EventLoop<T>::run
             at /Users/duncan/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/event_loop.rs:154:9
  50: bevy_winit::run
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_winit/src/lib.rs:170:5
  51: bevy_winit::winit_runner_with
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_winit/src/lib.rs:494:9
  52: bevy_winit::winit_runner
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_winit/src/lib.rs:210:5
  53: core::ops::function::Fn::call
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:70:5
  54: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1342:9
  55: bevy_app::app::App::run
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_app/src/app.rs:66:9
  56: bevy_app::app_builder::AppBuilder::run
             at /Users/duncan/.cargo/git/checkouts/bevy-f7ffde730c324c74/d9fb61d/crates/bevy_app/src/app_builder.rs:50:9
  57: array_texture_materials::main
             at ./examples/array_texture_materials/array_texture_materials.rs:33:5
  58: core::ops::function::FnOnce::call_once
             at /Users/duncan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
kvark commented

Thank you for filing!
This error will be much better with gfx-rs/wgpu#1273
Do you see anything in Rust log?

Yea this seems relevant:

WARN Device::create_shader_module: wgpu_core::device: Failed to parse shader SPIR-V code: UnsupportedInstruction(Function, LogicalAnd)
WARN Device::create_shader_module: wgpu_core::device: Shader module will not be validated or reflected

The only spot in the shader code where I see a "LocalAnd" is here:

for (int i=0; i<int(NumLights.x) && i<MAX_LIGHTS; ++i) {

Hmm I tried changing it to just:

for (int i=0; i<int(NumLights.x); ++i) {

but it's still crashing with the same error.

kvark commented

This warning just says that Naga validation has failed. It shouldn't panic, since wgpu-rs enables SPIRV-Cross by default, which we are falling back to. So I'm not sure why it's all panicking yet, trying to reproduce.
Note that we have infrastructure to record API traces - https://github.com/gfx-rs/wgpu/wiki/Debugging-wgpu-Applications#tracing-infrastructure
It's better than a repro case, since we don't need to clone/build anything in this case.
I don't have access to a macOS right now, testing on Linux

Should I just post the trace-level logs?

kvark commented

That wouldn't hurt.
Also note that this situation is already fixed on some level:

  • LogicalAnd is implemented now
  • we are not panicking like this as of gfx-rs/wgpu#1251

Still need to find out why exactly the pipeline creation failed

kvark commented

Mar 21 23:35:59.061 WARN bevy_asset::asset_server: encountered an error while loading an asset: Error reading image file materials.png: failed to load an image, this is an error in bevy_render.

Looks like an API trace would still be useful.

repro_trace.log

weird, why am I not able to grep LogicalAnd there?

weird, why am I not able to grep LogicalAnd there?

Oh I must have taken that trace after I removed the &&.

kvark commented

Actually, an API trace wouldn't directly help here either, since in wgpu-0.7 the crash would happen before the trace is recorded :/
How do I run it? Looks like your repro steps are missing something ("materials.png" and others).

Failing to load the image is unexpected... the image seems fine to me. It should be in the assets directory after cloning.

It's tracked by git LFS. Maybe there is an extra step for that to clone properly? It just happens automatically for me.

kvark commented

Not sure what "properly" would imply here. I'm on linux, and I just did git clone as described in the steps.

You probably just need to run git lfs install before cloning.

kvark commented

ok, this works fine on Linux. I'll see if somebody can reproduce.

I was able to reproduce under MacOS. The offending line is in the vertex shader: v_Uv = vec3(Vertex_Uv, Vertex_Layer);
If I comment it out, the example runs.

This is the entire vertex shader:

const VERTEX_SHADER: &str = r#"
#version 450

layout(location = 0) in vec3 Vertex_Position;
layout(location = 1) in vec3 Vertex_Normal;
layout(location = 2) in vec2 Vertex_Uv;
layout(location = 3) in int Vertex_Layer; // New thing

layout(location = 0) out vec3 v_Position;
layout(location = 1) out vec3 v_Normal;
layout(location = 2) out vec3 v_Uv;

layout(set = 0, binding = 0) uniform Camera {
    mat4 ViewProj;
};

layout(set = 2, binding = 0) uniform Transform {
    mat4 Model;
};

void main() {
    v_Normal = mat3(Model) * Vertex_Normal;
    v_Position = (Model * vec4(Vertex_Position, 1.0)).xyz;

    // Gets used here and passed to the fragment shader.
    //v_Uv = vec3(Vertex_Uv, Vertex_Layer); // UNCOMMENT THIS LINE TO PANIC

    gl_Position = ViewProj * vec4(v_Position, 1.0);
}
"#;

In fact, any attempt I made at using the Vertex_Layer ends up with a panic.

Found the root: the vertex attribute gets passed in as Uint by bevy, but the shader defines it as signed int:
layout(location = 3) in int Vertex_Layer; // New thing
I have no clue why, but signed-ness make a difference here: changing the shader to
layout(location = 3) in uint Vertex_Layer; fixes it.

kvark commented

@bonsairobo what's the relevant wgpu::Atrribute for this? Does it have an unsigned format?

A very relevant part of the code is at line 90 of array_texture_material.rs:

struct MeshBuf {
    pub positions: Vec<[f32; 3]>,
    pub normals: Vec<[f32; 3]>,
    pub tex_coords: Vec<[f32; 2]>,
    pub layer: Vec<u32>,
    pub indices: Vec<u32>,
}

and then that layer gets used at line 171:

    render_mesh.set_attribute("Vertex_Layer", layer);

Bevy sees that the variable type is Vec<u32> and therefore internally uses a VertexAttributeValues::Uint, which maps to VertexFormat::Uint

kvark commented

We certainly have this kind of pipeline interface validation in place. I tried modifying the cube example to do the same, and it throws this error:

wgpu error: Validation Error
Caused by:
In Device::create_render_pipeline
error in stage VERTEX
error matching the stage input at 2 against the previous stage outputs: input type is not compatible with the provided

So in your case, Naga wasn't able to parse the SPIR-V for some reason, and therefore the wgpu wasn't able to do the pipeline interface validation for it. Here comes a bit of an unknown. Originally, we know that the SPIR-V frontend failed to parse LogicalAnd. But the trace-level log you provided was a run with this operation commented out, and it doesn't have any of the naga warnings, so I'm not sure what it didn't like in the code.

kvark commented

Ok, I looked at it more, and it appears to be gfx-rs/naga#359
TL;DR: Bevy's code was not correct with regards to this int/uint attribute. wgpu wasn't able to validate it because of this ^ issue (but the validation code is otherwise in place).