From c2bacc63b00809350b06dfaa77be51de10cfabd1 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 11 Aug 2022 16:50:57 +0200 Subject: [PATCH] Fix the calculation and validation of layer and mip ranges in create_texture_view. The previous code was doing "selector.layers = base_layer .. count" instead of "base_layer .. base_layer + count" which looked dubious. Same thing for the mip range. It was also not taking the base layer count when in requested_layer_count when the texture was not a texture array which led to invalid ranges and underflow when asking for a non-zero base layer with a (non-array) 2d texture. --- wgpu-core/src/device/mod.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index b3d8247ee41..51b08e6629e 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -948,18 +948,21 @@ impl Device { }, }; - let required_level_count = - desc.range.base_mip_level + desc.range.mip_level_count.map_or(1, |count| count.get()); + let mip_count = desc.range.mip_level_count.map_or(1, |count| count.get()); + let required_level_count = desc.range.base_mip_level.saturating_add(mip_count); + let required_layer_count = match desc.range.array_layer_count { - Some(count) => desc.range.base_array_layer + count.get(), + Some(count) => desc.range.base_array_layer.saturating_add(count.get()), None => match view_dim { wgt::TextureViewDimension::D1 | wgt::TextureViewDimension::D2 | wgt::TextureViewDimension::D3 => 1, wgt::TextureViewDimension::Cube => 6, _ => texture.desc.array_layer_count(), - }, + } + .max(desc.range.base_array_layer.saturating_add(1)), }; + let level_end = texture.full_range.mips.end; let layer_end = texture.full_range.layers.end; if required_level_count > level_end { @@ -1002,17 +1005,9 @@ impl Device { }); } - let end_level = desc - .range - .mip_level_count - .map_or(level_end, |_| required_level_count); - let end_layer = desc - .range - .array_layer_count - .map_or(layer_end, |_| required_layer_count); let selector = TextureSelector { - mips: desc.range.base_mip_level..end_level, - layers: desc.range.base_array_layer..end_layer, + mips: desc.range.base_mip_level..required_level_count, + layers: desc.range.base_array_layer..required_layer_count, }; let view_layer_count = selector.layers.end - selector.layers.start;