Skip to content

Commit

Permalink
Fix the validation for vertex limits for regular render passes (#5156)
Browse files Browse the repository at this point in the history
  • Loading branch information
nical authored Jan 29, 2024
1 parent dec6ea5 commit 6e020a0
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Bottom level categories:
#### General
- Fix `panic!` when dropping `Instance` without `InstanceFlags::VALIDATION`. By @hakolao in [#5134](https://github.com/gfx-rs/wgpu/pull/5134)
- Fix `serde` feature not compiling for `wgpu-types`. By @KirmesBude in [#5149](https://github.com/gfx-rs/wgpu/pull/5149)
- Fix the validation of vertex and index ranges. By @nical in [#5144](https://github.com/gfx-rs/wgpu/pull/5144) and [#5156](https://github.com/gfx-rs/wgpu/pull/5156)

#### WGL

Expand Down
29 changes: 22 additions & 7 deletions wgpu-core/src/command/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,18 +378,33 @@ struct VertexState {

impl VertexState {
fn update_limits(&mut self) {
// TODO: This isn't entirely spec-compliant.
// We currently require that the buffer range can fit `stride` * count bytes.
// The spec, however, lets a buffer be a bit smaller as long as the size of the
// last element fits in it (the last element can be smaller than the stride between
// elements).
// Implements the validation from https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-draw
// Except that the formula is shuffled to extract the number of vertices in order
// to carry the bulk of the computation when changing states intead of when producing
// draws. Draw calls tend to happen at a higher frequency. Here we determine vertex
// limits that can be cheaply checked for each draw call.
self.vertex_limit = u32::MAX as u64;
self.instance_limit = u32::MAX as u64;
for (idx, vbs) in self.inputs.iter().enumerate() {
if vbs.step.stride == 0 || !vbs.bound {
if !vbs.bound {
continue;
}
let limit = vbs.total_size / vbs.step.stride;

let limit = if vbs.total_size < vbs.step.last_stride {
// The buffer cannot fit the last vertex.
0
} else {
if vbs.step.stride == 0 {
// We already checked that the last stride fits, the same
// vertex will be repeated so this slot can accomodate any number of
// vertices.
continue;
}

// The general case.
(vbs.total_size - vbs.step.last_stride) / vbs.step.stride + 1
};

match vbs.step.mode {
VertexStepMode::Vertex => {
if limit < self.vertex_limit {
Expand Down

0 comments on commit 6e020a0

Please sign in to comment.