@@ -52,7 +52,8 @@ impl WgpuContext {
adapter.get_info().backend
);
- let (device, queue, dual_source_blending) = Self::create_device(&adapter)?;
+ let (device, queue, dual_source_blending) =
+ pollster::block_on(Self::create_device(&adapter))?;
Ok(Self {
instance,
@@ -80,29 +81,36 @@ impl WgpuContext {
})
.await
.map_err(|e| anyhow::anyhow!("Failed to request GPU adapter: {e}"))?;
- Self::create_context(instance, adapter).await
- }
- #[cfg(target_family = "wasm")]
- async fn create_context(
- instance: wgpu::Instance,
- adapter: wgpu::Adapter,
- ) -> anyhow::Result<Self> {
log::info!(
"Selected GPU adapter: {:?} ({:?})",
adapter.get_info().name,
adapter.get_info().backend
);
- let dual_source_blending_available = adapter
+ let (device, queue, dual_source_blending) = Self::create_device(&adapter).await?;
+
+ Ok(Self {
+ instance,
+ adapter,
+ device: Arc::new(device),
+ queue: Arc::new(queue),
+ dual_source_blending,
+ })
+ }
+
+ async fn create_device(
+ adapter: &wgpu::Adapter,
+ ) -> anyhow::Result<(wgpu::Device, wgpu::Queue, bool)> {
+ let dual_source_blending = adapter
.features()
.contains(wgpu::Features::DUAL_SOURCE_BLENDING);
let mut required_features = wgpu::Features::empty();
- if dual_source_blending_available {
+ if dual_source_blending {
required_features |= wgpu::Features::DUAL_SOURCE_BLENDING;
} else {
- log::info!(
+ log::warn!(
"Dual-source blending not available on this GPU. \
Subpixel text antialiasing will be disabled."
);
@@ -112,7 +120,7 @@ impl WgpuContext {
.request_device(&wgpu::DeviceDescriptor {
label: Some("gpui_device"),
required_features,
- required_limits: wgpu::Limits::default(),
+ required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
trace: wgpu::Trace::Off,
experimental_features: wgpu::ExperimentalFeatures::disabled(),
@@ -120,13 +128,7 @@ impl WgpuContext {
.await
.map_err(|e| anyhow::anyhow!("Failed to create wgpu device: {e}"))?;
- Ok(Self {
- instance,
- adapter,
- device: Arc::new(device),
- queue: Arc::new(queue),
- dual_source_blending: dual_source_blending_available,
- })
+ Ok((device, queue, dual_source_blending))
}
#[cfg(not(target_family = "wasm"))]
@@ -154,35 +156,6 @@ impl WgpuContext {
Ok(())
}
- #[cfg(not(target_family = "wasm"))]
- fn create_device(adapter: &wgpu::Adapter) -> anyhow::Result<(wgpu::Device, wgpu::Queue, bool)> {
- let dual_source_blending_available = adapter
- .features()
- .contains(wgpu::Features::DUAL_SOURCE_BLENDING);
-
- let mut required_features = wgpu::Features::empty();
- if dual_source_blending_available {
- required_features |= wgpu::Features::DUAL_SOURCE_BLENDING;
- } else {
- log::warn!(
- "Dual-source blending not available on this GPU. \
- Subpixel text antialiasing will be disabled."
- );
- }
-
- let (device, queue) = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor {
- label: Some("gpui_device"),
- required_features,
- required_limits: wgpu::Limits::default(),
- memory_hints: wgpu::MemoryHints::MemoryUsage,
- trace: wgpu::Trace::Off,
- experimental_features: wgpu::ExperimentalFeatures::disabled(),
- }))
- .map_err(|e| anyhow::anyhow!("Failed to create wgpu device: {e}"))?;
-
- Ok((device, queue, dual_source_blending_available))
- }
-
#[cfg(not(target_family = "wasm"))]
async fn select_adapter(
instance: &wgpu::Instance,
@@ -106,6 +106,7 @@ pub struct WgpuRenderer {
path_globals_bind_group: wgpu::BindGroup,
instance_buffer: wgpu::Buffer,
instance_buffer_capacity: u64,
+ max_buffer_size: u64,
storage_buffer_alignment: u64,
path_intermediate_texture: wgpu::Texture,
path_intermediate_view: wgpu::TextureView,
@@ -285,6 +286,7 @@ impl WgpuRenderer {
mapped_at_creation: false,
});
+ let max_buffer_size = device.limits().max_buffer_size;
let storage_buffer_alignment = device.limits().min_storage_buffer_offset_alignment as u64;
let initial_instance_buffer_capacity = 2 * 1024 * 1024;
let instance_buffer = device.create_buffer(&wgpu::BufferDescriptor {
@@ -375,6 +377,7 @@ impl WgpuRenderer {
path_globals_bind_group,
instance_buffer,
instance_buffer_capacity: initial_instance_buffer_capacity,
+ max_buffer_size,
storage_buffer_alignment,
path_intermediate_texture,
path_intermediate_view,
@@ -1070,7 +1073,7 @@ impl WgpuRenderer {
if overflow {
drop(encoder);
- if self.instance_buffer_capacity >= 256 * 1024 * 1024 {
+ if self.instance_buffer_capacity >= self.max_buffer_size {
log::error!(
"instance buffer size grew too large: {}",
self.instance_buffer_capacity
@@ -1379,7 +1382,7 @@ impl WgpuRenderer {
}
fn grow_instance_buffer(&mut self) {
- let new_capacity = self.instance_buffer_capacity * 2;
+ let new_capacity = (self.instance_buffer_capacity * 2).min(self.max_buffer_size);
log::info!("increased instance buffer size to {}", new_capacity);
self.instance_buffer = self.device.create_buffer(&wgpu::BufferDescriptor {
label: Some("instance_buffer"),
@@ -38,8 +38,6 @@ const DEFAULT_FILTERS: &[(&str, log::LevelFilter)] = &[
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
("zbus", log::LevelFilter::Warn),
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "windows"))]
- ("wgpu", log::LevelFilter::Warn),
- #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "windows"))]
("naga::back::spv::writer", log::LevelFilter::Warn),
// usvg prints a lot of warnings on rendering an SVG with partial errors, which
// can happen a lot with the SVG preview