Error with Textures Using OpenGL Backend on Ubuntu 20.04
Pattakak opened this issue · 3 comments
I didn't have Vulkan drivers installed correctly, so I set the environment variable WGPU_BACKEND=gl to try to render the scene in OpenGL. What happened was that the program crashed on the glTexImage2D command. Here is the stacktrace.
Using Mesa Intel(R) UHD Graphics 620 (KBL GT2) (Gl)
[0.097388 ERROR]()(no module): [API/Error] ID 1 : GL_INVALID_OPERATION in glTexImage2D(format = GL_BGRA, type = GL_UNSIGNED_BYTE, internalformat = GL_SRGB8_ALPHA8)
thread 'main' panicked at 'Error creating image: InvalidOperation for kind D2(800, 600, 1, 1) of Bgra8Srgb', /home/patrick/.cargo/git/checkouts/gfx-e86e7f3ebdbc4218/0a201d1/src/backend/gl/src/device.rs:1586:13
stack backtrace:
0: rust_begin_unwind
at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:483
1: std::panicking::begin_panic_fmt
at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:437
2: <gfx_backend_gl::device::Device as gfx_hal::device::Device<gfx_backend_gl::Backend>>::create_image
at /home/patrick/.cargo/git/checkouts/gfx-e86e7f3ebdbc4218/0a201d1/src/backend/gl/src/device.rs:1586
3: wgpu_core::device::Device<B>::create_texture
at /home/patrick/.cargo/git/checkouts/wgpu-53e70f8674b08dd4/8a5668e/wgpu-core/src/device/mod.rs:675
4: wgpu_core::device::<impl wgpu_core::hub::Global<G>>::device_create_texture
at /home/patrick/.cargo/git/checkouts/wgpu-53e70f8674b08dd4/8a5668e/wgpu-core/src/device/mod.rs:2982
5: <wgpu::backend::direct::Context as wgpu::Context>::device_create_texture
at ./src/backend/direct.rs:1122
6: wgpu::Device::create_texture
at ./src/lib.rs:1595
7: water::Example::initialize_resources
at ./examples/water/main.rs:193
8: <water::Example as water::framework::Example>::init
at ./examples/water/main.rs:461
9: water::framework::start
at ./examples/water/../framework.rs:213
10: water::framework::run
at ./examples/water/../framework.rs:339
11: water::main
at ./examples/water/main.rs:790
12: core::ops::function::FnOnce::call_once
at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/ops/function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[0.181532 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181591 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181631 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181670 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181711 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181805 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181852 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181892 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181935 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
[0.181968 ERROR]()(gpu_alloc::block): Memory block wasn't deallocated
This specific error was generated with cargo run --example water, but similar issues come from different examples.
Yes, this is what we have today. GL backend needs more work, and it's clear how to see the improvement!
A problem here in Bgra8Srgb
texture format, that used in some examples.
Rgba8Srgb => FormatDescription::new(
glow::SRGB8_ALPHA8, // internalFormat
glow::RGBA, // format
glow::UNSIGNED_BYTE, // type
4,
Float,
),
@kvark Any ideas on how we should handle Bgra8Srgb
? There is no such combination of internal and external formats in texture table.
The examples don't use this directly. Instead, they rely on the get_swap_chain_preferred_format
, which essentially goes here:
// Check the four formats mentioned in the WebGPU spec:
// Bgra8UnormSrgb, Rgba8UnormSrgb, Bgra8Unorm, Rgba8Unorm
// Also, prefer sRGB over linear as it is better in
// representing perceived colors.
if formats.contains(&hal::format::Format::Bgra8Srgb) {
return Ok(wgt::TextureFormat::Bgra8UnormSrgb);
}
if formats.contains(&hal::format::Format::Rgba8Srgb) {
return Ok(wgt::TextureFormat::Rgba8UnormSrgb);
}
if formats.contains(&hal::format::Format::Bgra8Unorm) {
return Ok(wgt::TextureFormat::Bgra8Unorm);
}
if formats.contains(&hal::format::Format::Rgba8Unorm) {
return Ok(wgt::TextureFormat::Rgba8Unorm);
}
The GL backend currently reports Bgra8srgb to be available:
fn supported_formats(
&self,
_physical_device: &PhysicalDevice,
) -> Option<Vec<hal::format::Format>> {
use hal::format::Format;
Some(vec![Format::Rgba8Srgb, Format::Bgra8Srgb])
}
And it's not wrong here. If all you do is rendering into the swapchain, then Bgra8srgb
is indistinguishable from Rgba8srgb
.
A quick fix would be to just change supported_formats
there to not return Bgra8Srgb
.
Another thing that we should do is, like I said, let GL backend treat Bgra8srgb
the same way as Rgba8srgb
. It should also not advertise this format to be copyable, so that we don't have to deal with the swizzling.