diff --git a/CHANGELOG.md b/CHANGELOG.md index ff9bf871bf..361c4c3be2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ By @Valaphee in [#3402](https://github.com/gfx-rs/wgpu/pull/3402) - Omit texture store bound checks since they are no-ops if out of bounds on all APIs. By @teoxoy in [#3975](https://github.com/gfx-rs/wgpu/pull/3975) - Validate `DownlevelFlags::READ_ONLY_DEPTH_STENCIL`. By @teoxoy in [#4031](https://github.com/gfx-rs/wgpu/pull/4031) +- Add validation in accordance with WebGPU `setViewport` valid usage for `x`, `y` and `this.[[attachment_size]]`. By @James2022-rgb in [#4058](https://github.com/gfx-rs/wgpu/pull/4058) ### Bug Fixes diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index 0b7b48cda9..50ca9516b4 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -89,8 +89,8 @@ pub enum RenderCommandError { MissingTextureUsage(#[from] MissingTextureUsageError), #[error(transparent)] PushConstants(#[from] PushConstantUploadError), - #[error("Viewport width {0} and/or height {1} are less than or equal to 0")] - InvalidViewportDimension(f32, f32), + #[error("Viewport has invalid rect {0:?}; origin and/or size is less than or equal to 0, and/or is not contained in the render target {1:?}")] + InvalidViewportRect(Rect, wgt::Extent3d), #[error("Viewport minDepth {0} and/or maxDepth {1} are not in [0, 1]")] InvalidViewportDepth(f32, f32), #[error("Scissor {0:?} is not contained in the render target {1:?}")] diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 3a303cb5af..7f16f31807 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1727,9 +1727,16 @@ impl Global { depth_max, } => { let scope = PassErrorScope::SetViewport; - if rect.w <= 0.0 || rect.h <= 0.0 { - return Err(RenderCommandError::InvalidViewportDimension( - rect.w, rect.h, + if rect.x < 0.0 + || rect.y < 0.0 + || rect.w <= 0.0 + || rect.h <= 0.0 + || rect.x + rect.w > info.extent.width as f32 + || rect.y + rect.h > info.extent.height as f32 + { + return Err(RenderCommandError::InvalidViewportRect( + *rect, + info.extent, )) .map_pass_err(scope); }