gfx-rs / wgpu

A cross-platform, safe, pure-Rust graphics API.
https://wgpu.rs
Apache License 2.0
12.47k stars 914 forks source link

Rendering to texture no longer works with RGBA texture format, but used to work in v.0.12 #2878

Closed FrankenApps closed 2 years ago

FrankenApps commented 2 years ago

Description I have a small section of code that can be used to render the current scene to a texture and export it as an image. This used to work fine with the wgpu::TextureFormat::Rgba8UnormSrgb in version 0.12. However after I recently updated to 0.13 it does not work anymore and I am getting a validation error:

[<date> ERROR wgpu::backend::direct] Handling wgpu errors as fatal by default
thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 2, Metal)>`
    In a pass parameter
      note: command buffer = `<CommandBuffer-(0, 2, Metal)>`
    resource source format (Bgra8UnormSrgb) must match the resolve destination format (Rgba8UnormSrgb)

', /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.13.1/src/backend/direct.rs:2391:5
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/core/src/panicking.rs:142:14
   2: wgpu::backend::direct::default_error_handler
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.13.1/src/backend/direct.rs:2391:5
   3: core::ops::function::Fn::call
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/core/src/ops/function.rs:77:5
   4: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/alloc/src/boxed.rs:1886:9
   5: wgpu::backend::direct::ErrorSinkRaw::handle_error
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.13.1/src/backend/direct.rs:2377:17
   6: wgpu::backend::direct::Context::handle_error
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.13.1/src/backend/direct.rs:261:9
   7: <wgpu::backend::direct::Context as wgpu::Context>::command_encoder_end_render_pass
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.13.1/src/backend/direct.rs:2087:13
   8: <wgpu::RenderPass as core::ops::drop::Drop>::drop
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.13.1/src/lib.rs:3143:13
   9: core::ptr::drop_in_place<wgpu::RenderPass>
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/core/src/ptr/mod.rs:486:1
  10: format_repro::State::render_image::{{closure}}
             at ./src/main.rs:213:9
  11: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/core/src/future/mod.rs:91:19
  12: pollster::block_on
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/pollster-0.2.5/src/lib.rs:125:15
  13: format_repro::main::{{closure}}
             at ./src/main.rs:359:36
  14: <winit::platform_impl::platform::app_state::EventLoopHandler<T> as winit::platform_impl::platform::app_state::EventHandler>::handle_nonuser_event::{{closure}}
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/app_state.rs:101:13
  15: winit::platform_impl::platform::app_state::EventLoopHandler<T>::with_callback
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/app_state.rs:79:13
  16: <winit::platform_impl::platform::app_state::EventLoopHandler<T> as winit::platform_impl::platform::app_state::EventHandler>::handle_nonuser_event
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/app_state.rs:100:9
  17: winit::platform_impl::platform::app_state::Handler::handle_nonuser_event
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/app_state.rs:206:21
  18: winit::platform_impl::platform::app_state::AppState::cleared
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/app_state.rs:385:13
  19: winit::platform_impl::platform::observer::control_flow_end_handler::{{closure}}
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/observer.rs:180:21
  20: winit::platform_impl::platform::observer::control_flow_handler::{{closure}}
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/observer.rs:142:57
  21: std::panicking::try::do_call
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/std/src/panicking.rs:492:40
  22: ___rust_try
  23: std::panicking::try
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/std/src/panicking.rs:456:19
  24: std::panic::catch_unwind
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/std/src/panic.rs:137:14
  25: winit::platform_impl::platform::event_loop::stop_app_on_panic
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/event_loop.rs:229:11
  26: winit::platform_impl::platform::observer::control_flow_handler
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/observer.rs:142:5
  27: winit::platform_impl::platform::observer::control_flow_end_handler
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/observer.rs:175:9
  28: <unknown>
  29: <unknown>
  30: <unknown>
  31: <unknown>
  32: <unknown>
  33: <unknown>
  34: <unknown>
  35: <unknown>
  36: <unknown>
  37: <unknown>
  38: <() as objc::message::MessageArguments>::invoke
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:128:17
  39: objc::message::platform::send_unverified
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/objc-0.2.7/src/message/apple/mod.rs:27:9
  40: objc::message::send_message
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:178:5
  41: winit::platform_impl::platform::event_loop::EventLoop<T>::run_return::{{closure}}
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/event_loop.rs:188:22
  42: objc::rc::autorelease::autoreleasepool
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/objc-0.2.7/src/rc/autorelease.rs:29:5
  43: winit::platform_impl::platform::event_loop::EventLoop<T>::run_return
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/event_loop.rs:178:9
  44: winit::platform_impl::platform::event_loop::EventLoop<T>::run
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/platform_impl/macos/event_loop.rs:157:9
  45: winit::event_loop::EventLoop<T>::run
             at /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.1/src/event_loop.rs:154:9
  46: format_repro::main
             at ./src/main.rs:345:5
  47: core::ops::function::FnOnce::call_once
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Repro steps I made a separate repro for this. As you can see, if you checkout the 0.12 branch and press SPACE a picture is taken in RGBA format and after checking out the 0.13 branch the same operation results in the error from above.

Expected vs observed behavior Since the format worked with version 0.12 I am under the impression, that the metal backend on my machine does in fact support this and would therefore expect that it is still available in the latest version.

Additional information I think this might be related to the new feature detection in v 0.13, but it still occurs on the latest master even after https://github.com/gfx-rs/wgpu/pull/2856 was merged.

Platform MacOS 12.3.1, wgpu 0.13 and current master

cwfitzgerald commented 2 years ago

Thanks for filing!

This seems to be because we changed how exactly we pull which surface formats so we're now returning Bgra first. The source of the error is https://github.com/FrankenApps/wgpu_formats_repro/blob/v0.13/src/main.rs#L180 which mismatches with the surface format (used for all the other texture formats). You would need to adapt the cpu side code to swizzle the bytes back into rgba if the swapchain format is Bgra.

kpreid commented 2 years ago

You would need to adapt the cpu side code to swizzle the bytes back into rgba if the swapchain format is Bgra.

Two other options an application could implement:

FrankenApps commented 2 years ago

prefer a Rgba format if the supported formats contain one

Sadly these are all the supported formats I am getting: [Bgra8UnormSrgb, Bgra8Unorm, Rgba16Float, Rgb10a2Unorm]. Can I count on Bgra8UnormSrgb beeing supported on most platforms? In that case I will just swizzle the bytes as suggested by @cwfitzgerald

cwfitzgerald commented 2 years ago

Unfortunately you can't - I know that at least android can't do bgra surfaces.

kpreid commented 2 years ago

I see something suspicious here: if the platform doesn't support Rgba8UnormSrgb, then why did the original code work under 0.12? Is wgpu 0.13 accidentally hiding the Rgba format now? (Or was there a missing validation and the Rgba only worked as some driver make-it-work-anyway-at-a-cost fallback?)

cwfitzgerald commented 2 years ago

I suspect so, RGBA isn't a valid format for CAMetalLayer - https://developer.apple.com/documentation/quartzcore/cametallayer/1478155-pixelformat