Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wgpu.image] Workaround WGPU OpenGL heuristics #2259

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Alpha mode misconfiguration in `iced_wgpu`. [#2231](https://github.com/iced-rs/iced/pull/2231)
- Outdated documentation leading to a dead link. [#2232](https://github.com/iced-rs/iced/pull/2232)

## Patched
- Black images when using OpenGL backend in `iced_wgpu`. [#2259](https://github.com/iced-rs/iced/pull/2259)

Many thanks to...

- @akshayr-mecha
Expand Down Expand Up @@ -156,6 +159,7 @@ Many thanks to...
- @nicksenger
- @Nisatru
- @nyurik
- @PolyMeilex
- @Remmirad
- @ripytide
- @snaggen
Expand Down
32 changes: 18 additions & 14 deletions examples/integration/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
});
let surface = instance.create_surface(window.clone())?;

let (format, (device, queue)) =
let (format, adapter, device, queue) =
futures::futures::executor::block_on(async {
let adapter = wgpu::util::initialize_adapter_from_env_or_default(
&instance,
Expand All @@ -107,6 +107,19 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {

let capabilities = surface.get_capabilities(&adapter);

let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
label: None,
required_features: adapter_features
& wgpu::Features::default(),
required_limits: needed_limits,
},
None,
)
.await
.expect("Request device");

(
capabilities
.formats
Expand All @@ -115,18 +128,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
.find(wgpu::TextureFormat::is_srgb)
.or_else(|| capabilities.formats.first().copied())
.expect("Get preferred format"),
adapter
.request_device(
&wgpu::DeviceDescriptor {
label: None,
required_features: adapter_features
& wgpu::Features::default(),
required_limits: needed_limits,
},
None,
)
.await
.expect("Request device"),
adapter,
device,
queue,
)
});

Expand All @@ -153,7 +157,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize iced
let mut debug = Debug::new();
let mut renderer = Renderer::new(
Backend::new(&device, &queue, Settings::default(), format),
Backend::new(&adapter, &device, &queue, Settings::default(), format),
Font::default(),
Pixels(16.0),
);
Expand Down
8 changes: 6 additions & 2 deletions wgpu/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ pub struct Backend {
text_pipeline: text::Pipeline,
triangle_pipeline: triangle::Pipeline,
pipeline_storage: pipeline::Storage,

#[cfg(any(feature = "image", feature = "svg"))]
image_pipeline: image::Pipeline,
}

impl Backend {
/// Creates a new [`Backend`].
pub fn new(
_adapter: &wgpu::Adapter,
device: &wgpu::Device,
queue: &wgpu::Queue,
settings: Settings,
Expand All @@ -46,7 +46,11 @@ impl Backend {
triangle::Pipeline::new(device, format, settings.antialiasing);

#[cfg(any(feature = "image", feature = "svg"))]
let image_pipeline = image::Pipeline::new(device, format);
let image_pipeline = {
let backend = _adapter.get_info().backend;

image::Pipeline::new(device, format, backend)
};

Self {
quad_pipeline,
Expand Down
8 changes: 6 additions & 2 deletions wgpu/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,11 @@ impl Data {
}

impl Pipeline {
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self {
pub fn new(
device: &wgpu::Device,
format: wgpu::TextureFormat,
backend: wgpu::Backend,
) -> Self {
let nearest_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
Expand Down Expand Up @@ -318,7 +322,7 @@ impl Pipeline {
multiview: None,
});

let texture_atlas = Atlas::new(device);
let texture_atlas = Atlas::new(device, backend);

let texture = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("iced_wgpu::image texture atlas bind group"),
Expand Down
14 changes: 11 additions & 3 deletions wgpu/src/image/atlas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,19 @@ pub struct Atlas {
}

impl Atlas {
pub fn new(device: &wgpu::Device) -> Self {
pub fn new(device: &wgpu::Device, backend: wgpu::Backend) -> Self {
let layers = match backend {
// On the GL backend we start with 2 layers, to help wgpu figure
// out that this texture is `GL_TEXTURE_2D_ARRAY` rather than `GL_TEXTURE_2D`
// https://github.com/gfx-rs/wgpu/blob/004e3efe84a320d9331371ed31fa50baa2414911/wgpu-hal/src/gles/mod.rs#L371
wgpu::Backend::Gl => vec![Layer::Empty, Layer::Empty],
_ => vec![Layer::Empty],
};
Comment on lines +26 to +33
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made it so that the additional memory is only allocated when using OpenGL.


let extent = wgpu::Extent3d {
width: SIZE,
height: SIZE,
depth_or_array_layers: 1,
depth_or_array_layers: layers.len() as u32,
};

let texture = device.create_texture(&wgpu::TextureDescriptor {
Expand Down Expand Up @@ -55,7 +63,7 @@ impl Atlas {
Atlas {
texture,
texture_view,
layers: vec![Layer::Empty],
layers,
}
}

Expand Down
8 changes: 7 additions & 1 deletion wgpu/src/window/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,13 @@ impl Compositor {

/// Creates a new rendering [`Backend`] for this [`Compositor`].
pub fn create_backend(&self) -> Backend {
Backend::new(&self.device, &self.queue, self.settings, self.format)
Backend::new(
&self.adapter,
&self.device,
&self.queue,
self.settings,
self.format,
)
}
}

Expand Down
Loading