diff --git a/wgpu-hal/src/dx11/adapter.rs b/wgpu-hal/src/dx11/adapter.rs index 34ce34238..290a9ade2 100644 --- a/wgpu-hal/src/dx11/adapter.rs +++ b/wgpu-hal/src/dx11/adapter.rs @@ -237,6 +237,7 @@ impl super::Adapter { max_compute_workgroups_per_dimension, // D3D11_BUFFER_DESC represents the buffer size as a 32 bit int. max_buffer_size: u32::MAX as u64, + max_non_sampler_bindings: u32::MAX, }; // diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 18873b9d6..02cde913c 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -361,6 +361,7 @@ impl super::Adapter { // This limit is chosen to avoid potential issues with drivers should they internally // store buffer sizes using 32 bit ints (a situation we have already encountered with vulkan). max_buffer_size: i32::MAX as u64, + max_non_sampler_bindings: 1_000_000, }, alignments: crate::Alignments { buffer_copy_offset: wgt::BufferSize::new( @@ -382,7 +383,7 @@ impl crate::Adapter for super::Adapter { unsafe fn open( &self, _features: wgt::Features, - _limits: &wgt::Limits, + limits: &wgt::Limits, ) -> Result, crate::DeviceError> { let queue = { profiling::scope!("ID3D12Device::CreateCommandQueue"); @@ -399,6 +400,7 @@ impl crate::Adapter for super::Adapter { let device = super::Device::new( self.device.clone(), queue.clone(), + limits, self.private_caps, &self.library, self.dx12_shader_compiler.clone(), diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 1471db3b3..1a44d98f0 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -16,6 +16,7 @@ impl super::Device { pub(super) fn new( raw: d3d12::Device, present_queue: d3d12::CommandQueue, + limits: &wgt::Limits, private_caps: super::PrivateCapabilities, library: &Arc, dx12_shader_compiler: wgt::Dx12Compiler, @@ -92,7 +93,7 @@ impl super::Device { }; // maximum number of CBV/SRV/UAV descriptors in heap for Tier 1 - let capacity_views = 1_000_000; + let capacity_views = limits.max_non_sampler_bindings as u64; let capacity_samplers = 2_048; let shared = super::DeviceShared { diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index ca75bd09e..2c68961e3 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -576,6 +576,7 @@ impl super::Adapter { }, max_compute_workgroups_per_dimension, max_buffer_size: i32::MAX as u64, + max_non_sampler_bindings: std::u32::MAX, }; let mut workarounds = super::Workarounds::empty(); diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 5e44a1816..bc90954b3 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -904,6 +904,7 @@ impl super::PrivateCapabilities { max_compute_workgroup_size_z: self.max_threads_per_group, max_compute_workgroups_per_dimension: 0xFFFF, max_buffer_size: self.max_buffer_size, + max_non_sampler_bindings: std::u32::MAX, }, alignments: crate::Alignments { buffer_copy_offset: wgt::BufferSize::new(self.buffer_alignment).unwrap(), diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 4bac0eede..4a7ccf953 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -755,6 +755,7 @@ impl PhysicalDeviceCapabilities { max_compute_workgroup_size_z: max_compute_workgroup_sizes[2], max_compute_workgroups_per_dimension, max_buffer_size, + max_non_sampler_bindings: std::u32::MAX, } } diff --git a/wgpu-info/src/human.rs b/wgpu-info/src/human.rs index 66b0e506e..11d88d955 100644 --- a/wgpu-info/src/human.rs +++ b/wgpu-info/src/human.rs @@ -124,6 +124,7 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize max_compute_workgroup_size_y, max_compute_workgroup_size_z, max_compute_workgroups_per_dimension, + max_non_sampler_bindings, } = limits; writeln!(output, "\t\t Max Texture Dimension 1d: {max_texture_dimension_1d}")?; writeln!(output, "\t\t Max Texture Dimension 2d: {max_texture_dimension_2d}")?; @@ -155,6 +156,10 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize writeln!(output, "\t\t Max Compute Workgroup Size Z: {max_compute_workgroup_size_z}")?; writeln!(output, "\t\t Max Compute Workgroups Per Dimension: {max_compute_workgroups_per_dimension}")?; + // This one reflects more of a wgpu implementation limitations than a hardware limit + // so don't show it here. + let _ = max_non_sampler_bindings; + ////////////////////////// // Downlevel Properties // ////////////////////////// diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 2fc9f990a..5c2c32394 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -931,6 +931,12 @@ pub struct Limits { /// - DX11 & OpenGL don't natively support push constants, and are emulated with uniforms, /// so this number is less useful but likely 256. pub max_push_constant_size: u32, + + /// Maximum number of live non-sampler bindings. + /// + /// This limit only affects the d3d12 backend. Using a large number will allow the device + /// to create many bind groups at the cost of a large up-front allocation at device creation. + pub max_non_sampler_bindings: u32, } impl Default for Limits { @@ -965,6 +971,7 @@ impl Default for Limits { max_compute_workgroup_size_z: 64, max_compute_workgroups_per_dimension: 65535, max_push_constant_size: 0, + max_non_sampler_bindings: 1_000_000, } } } @@ -1005,6 +1012,7 @@ impl Limits { /// max_compute_workgroup_size_z: 64, /// max_compute_workgroups_per_dimension: 65535, /// max_buffer_size: 256 << 20, // (256 MiB) + /// max_non_sampler_bindings: 1_000_000, /// }); /// ``` pub fn downlevel_defaults() -> Self { @@ -1038,6 +1046,7 @@ impl Limits { max_compute_workgroup_size_z: 64, max_compute_workgroups_per_dimension: 65535, max_buffer_size: 256 << 20, + max_non_sampler_bindings: 1_000_000, } } @@ -1076,7 +1085,8 @@ impl Limits { /// max_compute_workgroup_size_y: 0, // + /// max_compute_workgroup_size_z: 0, // + /// max_compute_workgroups_per_dimension: 0, // + - /// max_buffer_size: 256 << 20, // (256 MiB) + /// max_buffer_size: 256 << 20, // (256 MiB), + /// max_non_sampler_bindings: 1_000_000, /// }); /// ``` pub fn downlevel_webgl2_defaults() -> Self { @@ -1193,6 +1203,7 @@ impl Limits { compare!(max_compute_workgroup_size_z, Less); compare!(max_compute_workgroups_per_dimension, Less); compare!(max_buffer_size, Less); + compare!(max_non_sampler_bindings, Less); } }