From f0d73bd7412437133a244d557a46c8341b26ad55 Mon Sep 17 00:00:00 2001 From: Jinlei Li Date: Sun, 21 Aug 2022 15:59:45 +0800 Subject: [PATCH] metal: fix `max_buffer` `max_texture` and `max_vertex_buffers` limits --- wgpu-hal/src/metal/adapter.rs | 45 ++++++++++++++++++----------------- wgpu-hal/src/metal/command.rs | 2 +- wgpu-hal/src/metal/device.rs | 4 ++-- wgpu-hal/src/metal/mod.rs | 1 + 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 2b530695972..9be6aece22f 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -501,6 +501,19 @@ impl super::PrivateCapabilities { MTLReadWriteTextureTier::TierNone }; + let (max_buffers_per_stage, max_textures_per_stage, max_samplers_per_stage) = if (os_is_mac + && rw_texture_tier == MTLReadWriteTextureTier::Tier2) + || (family_check && device.supports_family(MTLGPUFamily::Apple6)) + { + (500000 / 2, 500000 / 2, 1024) + } else if os_is_mac && rw_texture_tier == MTLReadWriteTextureTier::Tier1 { + (64, 128, 16) + } else if family_check && device.supports_family(MTLGPUFamily::Apple4) { + (96, 96, 16) + } else { + (31, 31, 16) + }; + Self { family_check, msl_version: if version.at_least((12, 0), (15, 0)) { @@ -615,22 +628,10 @@ impl super::PrivateCapabilities { format_depth32float_none: !os_is_mac, format_bgr10a2_all: Self::supports_any(device, BGR10A2_ALL), format_bgr10a2_no_write: !Self::supports_any(device, BGR10A2_ALL), - max_buffers_per_stage: 31, - max_textures_per_stage: if os_is_mac { - 128 // On macOS, minimun value is 128 - } else if device.supports_feature_set(MTLFeatureSet::iOS_GPUFamily4_v1) { - 96 - } else { - 31 - }, - max_samplers_per_stage: if (family_check - && device.supports_family(MTLGPUFamily::Apple6)) - || (os_is_mac && rw_texture_tier == MTLReadWriteTextureTier::Tier2) - { - 1024 - } else { - 16 - }, + max_buffers_per_stage, + max_vertex_buffers: 31, + max_textures_per_stage, + max_samplers_per_stage, buffer_alignment: if os_is_mac { 256 } else { 64 }, max_buffer_size: if version.at_least((10, 14), (12, 0)) { // maxBufferLength available on macOS 10.14+ and iOS 12.0+ @@ -833,15 +834,15 @@ impl super::PrivateCapabilities { .max_dynamic_uniform_buffers_per_pipeline_layout, max_dynamic_storage_buffers_per_pipeline_layout: base .max_dynamic_storage_buffers_per_pipeline_layout, - max_sampled_textures_per_shader_stage: base.max_sampled_textures_per_shader_stage, + max_sampled_textures_per_shader_stage: self.max_textures_per_stage, max_samplers_per_shader_stage: self.max_samplers_per_stage, - max_storage_buffers_per_shader_stage: base.max_storage_buffers_per_shader_stage, - max_storage_textures_per_shader_stage: base.max_storage_textures_per_shader_stage, - max_uniform_buffers_per_shader_stage: 12, + max_storage_buffers_per_shader_stage: self.max_buffers_per_stage, + max_storage_textures_per_shader_stage: self.max_textures_per_stage, + max_uniform_buffers_per_shader_stage: self.max_buffers_per_stage, max_uniform_buffer_binding_size: self.max_buffer_size.min(!0u32 as u64) as u32, max_storage_buffer_binding_size: self.max_buffer_size.min(!0u32 as u64) as u32, - max_vertex_buffers: base.max_vertex_buffers, - max_vertex_attributes: base.max_vertex_attributes, + max_vertex_buffers: self.max_vertex_buffers, + max_vertex_attributes: 31, max_vertex_buffer_array_stride: base.max_vertex_buffer_array_stride, max_push_constant_size: 0x1000, min_uniform_buffer_offset_alignment: self.buffer_alignment as u32, diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 9231df93039..49337ee7ead 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -724,7 +724,7 @@ impl crate::CommandEncoder for super::CommandEncoder { index: u32, binding: crate::BufferBinding<'a, super::Api>, ) { - let buffer_index = self.shared.private_caps.max_buffers_per_stage as u64 - 1 - index as u64; + let buffer_index = self.shared.private_caps.max_vertex_buffers as u64 - 1 - index as u64; let encoder = self.state.render.as_ref().unwrap(); encoder.set_vertex_buffer(buffer_index, Some(&binding.buffer.raw), binding.offset); } diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 8d3301554e0..81b9461f875 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -890,7 +890,7 @@ impl crate::Device for super::Device { }; if desc.layout.total_counters.vs.buffers + (desc.vertex_buffers.len() as u32) - > self.shared.private_caps.max_buffers_per_stage + > self.shared.private_caps.max_vertex_buffers { let msg = format!( "pipeline needs too many buffers in the vertex stage: {} vertex and {} layout", @@ -907,7 +907,7 @@ impl crate::Device for super::Device { let vertex_descriptor = mtl::VertexDescriptor::new(); for (i, vb) in desc.vertex_buffers.iter().enumerate() { let buffer_index = - self.shared.private_caps.max_buffers_per_stage as u64 - 1 - i as u64; + self.shared.private_caps.max_vertex_buffers as u64 - 1 - i as u64; let buffer_desc = vertex_descriptor.layouts().object_at(buffer_index).unwrap(); buffer_desc.set_stride(vb.array_stride); diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 1ea8312b9f7..9daa6385fc9 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -204,6 +204,7 @@ struct PrivateCapabilities { format_bgr10a2_all: bool, format_bgr10a2_no_write: bool, max_buffers_per_stage: ResourceIndex, + max_vertex_buffers: ResourceIndex, max_textures_per_stage: ResourceIndex, max_samplers_per_stage: ResourceIndex, buffer_alignment: u64,