diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a0043c50..ebb4568de3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ the same every time it is rendered, we now warn if it is missing. #### Metal - Add the missing `msg_send![view, retain]` call within `from_view` by @jinleili in [#2976](https://github.com/gfx-rs/wgpu/pull/2976) +- Fix `max_buffer` `max_texture` and `max_vertex_buffers` limits by @jinleili in [#2978](https://github.com/gfx-rs/wgpu/pull/2978) #### Vulkan - Fix `astc_hdr` formats support by @jinleili in [#2971]](https://github.com/gfx-rs/wgpu/pull/2971) diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 2b53069597..cbe7486f5f 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -616,21 +616,17 @@ impl super::PrivateCapabilities { 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) { + max_vertex_buffers: 31, + max_textures_per_stage: if os_is_mac + || (family_check && device.supports_family(MTLGPUFamily::Apple6)) + { + 128 + } else if family_check && device.supports_family(MTLGPUFamily::Apple4) { 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_samplers_per_stage: 16, 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 +829,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 9231df9303..49337ee7ea 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 8d3301554e..81b9461f87 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 1ea8312b9f..9daa6385fc 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,