From 9fd13dcce36a9f5e61c6163a014f91d16219dde5 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Fri, 27 Oct 2023 01:48:03 +0200 Subject: [PATCH] Validate max_vertex_buffers in set_vertex_buffer (#4574) --- wgpu-core/src/command/draw.rs | 2 ++ wgpu-core/src/command/render.rs | 9 +++++++++ wgpu-hal/src/dx11/adapter.rs | 3 ++- wgpu-hal/src/gles/adapter.rs | 3 ++- wgpu-hal/src/metal/adapter.rs | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index 50ca9516b4..c5b0bb7527 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -67,6 +67,8 @@ pub enum RenderCommandError { InvalidRenderBundle(id::RenderBundleId), #[error("Bind group index {index} is greater than the device's requested `max_bind_group` limit {max}")] BindGroupIndexOutOfRange { index: u32, max: u32 }, + #[error("Vertex buffer index {index} is greater than the device's requested `max_vertex_buffers` limit {max}")] + VertexBufferIndexOutOfRange { index: u32, max: u32 }, #[error("Dynamic buffer offset {0} does not respect device's requested `{1}` limit {2}")] UnalignedBufferOffset(u64, &'static str, u32), #[error("Number of buffer offsets ({actual}) does not match the number of dynamic bindings ({expected})")] diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index ea3810bdd1..1d0f7cf717 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1714,6 +1714,15 @@ impl Global { return Err(DeviceError::WrongDevice).map_pass_err(scope); } + let max_vertex_buffers = device.limits.max_vertex_buffers; + if slot > max_vertex_buffers { + return Err(RenderCommandError::VertexBufferIndexOutOfRange { + index: slot, + max: max_vertex_buffers, + }) + .map_pass_err(scope); + } + check_buffer_usage(buffer.usage, BufferUsages::VERTEX) .map_pass_err(scope)?; let buf_raw = buffer diff --git a/wgpu-hal/src/dx11/adapter.rs b/wgpu-hal/src/dx11/adapter.rs index e2beb06571..41b4b4e573 100644 --- a/wgpu-hal/src/dx11/adapter.rs +++ b/wgpu-hal/src/dx11/adapter.rs @@ -173,7 +173,8 @@ impl super::Adapter { let max_vertex_buffers = match feature_level { FL9_1..=FL9_3 => 16, _ => 32, - }; + } + .min(crate::MAX_VERTEX_BUFFERS as u32); let max_compute_workgroup_storage_size = match feature_level { FL9_1..=FL9_3 => 0, FL10_0 | FL10_1 => 4096 * 4, // This doesn't have an equiv SM4 constant :\ diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index e8cf3d270d..4b88926cd1 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -639,7 +639,8 @@ impl super::Adapter { (unsafe { gl.get_parameter_i32(glow::MAX_VERTEX_ATTRIB_BINDINGS) } as u32) } else { 16 // should this be different? - }, + } + .min(crate::MAX_VERTEX_BUFFERS as u32), max_vertex_attributes: (unsafe { gl.get_parameter_i32(glow::MAX_VERTEX_ATTRIBS) } as u32) .min(super::MAX_VERTEX_ATTRIBUTES as u32), diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 2f48712b9b..fe7122f425 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -675,7 +675,7 @@ 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_vertex_buffers: 31, + max_vertex_buffers: 31.min(crate::MAX_VERTEX_BUFFERS as u32), max_textures_per_stage: if os_is_mac || (family_check && device.supports_family(MTLGPUFamily::Apple6)) {