Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cts_runner/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ webgpu:api,validation,encoding,cmds,index_access:*
//FAIL: webgpu:api,validation,encoding,cmds,render,draw:*
webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:*
webgpu:api,validation,encoding,cmds,render,draw:unused_buffer_bound:*
webgpu:api,validation,encoding,cmds,render,setIndexBuffer:index_buffer_state:*
webgpu:api,validation,encoding,cmds,render,setVertexBuffer:vertex_buffer_state:*
webgpu:api,validation,encoding,cmds,render,setIndexBuffer:*
webgpu:api,validation,encoding,cmds,render,setVertexBuffer:*
webgpu:api,validation,encoding,encoder_state:*
webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:*
webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:*
Expand Down
10 changes: 10 additions & 0 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,13 @@ fn set_index_buffer(
buffer.same_device(&state.device)?;
buffer.check_usage(wgt::BufferUsages::INDEX)?;

if offset % u64::try_from(index_format.byte_size()).unwrap() != 0 {
return Err(RenderCommandError::UnalignedIndexBuffer {
offset,
alignment: index_format.byte_size(),
}
.into());
}
let end = offset + buffer.resolve_binding_size(offset, size)?;

state
Expand Down Expand Up @@ -663,6 +670,9 @@ fn set_vertex_buffer(
buffer.same_device(&state.device)?;
buffer.check_usage(wgt::BufferUsages::VERTEX)?;

if offset % wgt::VERTEX_ALIGNMENT != 0 {
return Err(RenderCommandError::UnalignedVertexBuffer { slot, offset }.into());
}
let end = offset + buffer.resolve_binding_size(offset, size)?;

state
Expand Down
8 changes: 8 additions & 0 deletions wgpu-core/src/command/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ pub enum RenderCommandError {
BindGroupIndexOutOfRange(#[from] pass::BindGroupIndexOutOfRange),
#[error("Vertex buffer index {index} is greater than the device's requested `max_vertex_buffers` limit {max}")]
VertexBufferIndexOutOfRange { index: u32, max: u32 },
#[error(
"Offset {offset} for vertex buffer in slot {slot} is not a multiple of `VERTEX_ALIGNMENT`"
)]
UnalignedVertexBuffer { slot: u32, offset: u64 },
#[error("Offset {offset} for index buffer is not a multiple of {alignment}")]
UnalignedIndexBuffer { offset: u64, alignment: usize },
#[error("Render pipeline targets are incompatible with render pass")]
IncompatiblePipelineTargets(#[from] crate::device::RenderPassCompatibilityError),
#[error("{0} writes to depth, while the pass has read-only depth access")]
Expand Down Expand Up @@ -116,6 +122,8 @@ impl WebGpuError for RenderCommandError {

Self::BindGroupIndexOutOfRange { .. }
| Self::VertexBufferIndexOutOfRange { .. }
| Self::UnalignedIndexBuffer { .. }
| Self::UnalignedVertexBuffer { .. }
| Self::IncompatibleDepthAccess(..)
| Self::IncompatibleStencilAccess(..)
| Self::InvalidViewportRectSize { .. }
Expand Down
10 changes: 10 additions & 0 deletions wgpu-core/src/command/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2344,6 +2344,13 @@ fn set_index_buffer(

buffer.check_usage(BufferUsages::INDEX)?;

if offset % u64::try_from(index_format.byte_size()).unwrap() != 0 {
return Err(RenderCommandError::UnalignedIndexBuffer {
offset,
alignment: index_format.byte_size(),
}
.into());
}
let (binding, resolved_size) = buffer
.binding(offset, size, state.general.snatch_guard)
.map_err(RenderCommandError::from)?;
Expand Down Expand Up @@ -2397,6 +2404,9 @@ fn set_vertex_buffer(

buffer.check_usage(BufferUsages::VERTEX)?;

if offset % wgt::VERTEX_ALIGNMENT != 0 {
return Err(RenderCommandError::UnalignedVertexBuffer { slot, offset }.into());
}
let (binding, buffer_size) = buffer
.binding(offset, size, state.general.snatch_guard)
.map_err(RenderCommandError::from)?;
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3159,7 +3159,7 @@ impl Device {
limit: self.limits.max_vertex_buffer_array_stride,
});
}
if vb_state.array_stride % wgt::VERTEX_STRIDE_ALIGNMENT != 0 {
if vb_state.array_stride % wgt::VERTEX_ALIGNMENT != 0 {
return Err(pipeline::CreateRenderPipelineError::UnalignedVertexStride {
index: i as u32,
stride: vb_state.array_stride,
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ pub enum CreateRenderPipelineError {
given: u32,
limit: u32,
},
#[error("Vertex buffer {index} stride {stride} does not respect `VERTEX_STRIDE_ALIGNMENT`")]
#[error("Vertex buffer {index} stride {stride} does not respect `VERTEX_ALIGNMENT`")]
UnalignedVertexStride {
index: u32,
stride: wgt::BufferAddress,
Expand Down
8 changes: 8 additions & 0 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,18 @@ pub const COPY_BUFFER_ALIGNMENT: BufferAddress = 4;
/// [`get_mapped_range()`]: ../wgpu/struct.Buffer.html#method.get_mapped_range
pub const MAP_ALIGNMENT: BufferAddress = 8;

/// [Vertex buffer offsets] and [strides] have to be a multiple of this number.
///
/// [Vertex buffer offsets]: ../wgpu/util/trait.RenderEncoder.html#tymethod.set_vertex_buffer
/// [strides]: ../wgpu/struct.VertexBufferLayout.html#structfield.array_stride
pub const VERTEX_ALIGNMENT: BufferAddress = 4;

/// [Vertex buffer strides] have to be a multiple of this number.
///
/// [Vertex buffer strides]: ../wgpu/struct.VertexBufferLayout.html#structfield.array_stride
#[deprecated(note = "Use `VERTEX_ALIGNMENT` instead", since = "27.0.0")]
pub const VERTEX_STRIDE_ALIGNMENT: BufferAddress = 4;

/// Ranges of [writes to push constant storage] must be at least this aligned.
///
/// [writes to push constant storage]: ../wgpu/struct.RenderPass.html#method.set_push_constants
Expand Down
2 changes: 1 addition & 1 deletion wgpu/src/api/render_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl RenderPipeline {
pub struct VertexBufferLayout<'a> {
/// The stride, in bytes, between elements of this buffer (between vertices).
///
/// This must be a multiple of [`VERTEX_STRIDE_ALIGNMENT`].
/// This must be a multiple of [`VERTEX_ALIGNMENT`].
pub array_stride: BufferAddress,
/// How often this vertex buffer is "stepped" forward.
pub step_mode: VertexStepMode,
Expand Down
6 changes: 5 additions & 1 deletion wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,12 @@ pub use wgt::{
TextureTransition, TextureUsages, TextureUses, TextureViewDimension, Trace, VertexAttribute,
VertexFormat, VertexStepMode, WasmNotSend, WasmNotSendSync, WasmNotSync, COPY_BUFFER_ALIGNMENT,
COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT,
QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_STRIDE_ALIGNMENT,
QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_ALIGNMENT,
};

#[expect(deprecated)]
pub use wgt::VERTEX_STRIDE_ALIGNMENT;

// wasm-only types, we try to keep as many types non-platform
// specific, but these need to depend on web-sys.
#[cfg(web)]
Expand Down