diff --git a/CHANGELOG_VULKANO.md b/CHANGELOG_VULKANO.md index d1c07fc8..7ae66fa7 100644 --- a/CHANGELOG_VULKANO.md +++ b/CHANGELOG_VULKANO.md @@ -2,6 +2,7 @@ - Update MacOS dependencies metal to 0.17 and cocoa to 0.19 - Added dynamic stencil elements to `DynamicState` +- Fixed `ImageDimensions::mipmap_dimensions` and `max_mipmaps` in cases where the original size is not a power of two. # Version 0.14.0 (2019-08-17) diff --git a/vulkano/src/image/mod.rs b/vulkano/src/image/mod.rs index c14f0565..3bc9af97 100644 --- a/vulkano/src/image/mod.rs +++ b/vulkano/src/image/mod.rs @@ -415,17 +415,11 @@ impl ImageDimensions { /// array_layers: 1, /// }; /// - /// assert_eq!(dims.max_mipmaps(), 7); + /// assert_eq!(dims.max_mipmaps(), 6); /// ``` /// - /// # Panic - /// - /// May panic if the dimensions are 0. - /// pub fn max_mipmaps(&self) -> u32 { - let max_dim = cmp::max(cmp::max(self.width(), self.height()), self.depth()); - let num_zeroes = 32 - (max_dim - 1).leading_zeros(); - num_zeroes + 1 + 32 - (self.width() | self.height() | self.depth()).leading_zeros() } /// Returns the dimensions of the `level`th mipmap level. If `level` is 0, then the dimensions @@ -447,19 +441,19 @@ impl ImageDimensions { /// /// assert_eq!(dims.mipmap_dimensions(0), Some(dims)); /// assert_eq!(dims.mipmap_dimensions(1), Some(ImageDimensions::Dim2d { - /// width: 512, + /// width: 481, /// height: 128, /// cubemap_compatible: false, /// array_layers: 1, /// })); /// assert_eq!(dims.mipmap_dimensions(6), Some(ImageDimensions::Dim2d { - /// width: 16, + /// width: 15, /// height: 4, /// cubemap_compatible: false, /// array_layers: 1, /// })); /// assert_eq!(dims.mipmap_dimensions(9), Some(ImageDimensions::Dim2d { - /// width: 2, + /// width: 1, /// height: 1, /// cubemap_compatible: false, /// array_layers: 1, @@ -489,7 +483,7 @@ impl ImageDimensions { debug_assert_ne!(width, 0); ImageDimensions::Dim1d { array_layers: array_layers, - width: (((width - 1) >> level) + 1).next_power_of_two(), + width: cmp::max(1, width >> level), } }, @@ -502,8 +496,8 @@ impl ImageDimensions { debug_assert_ne!(width, 0); debug_assert_ne!(height, 0); ImageDimensions::Dim2d { - width: (((width - 1) >> level) + 1).next_power_of_two(), - height: (((height - 1) >> level) + 1).next_power_of_two(), + width: cmp::max(1, width >> level), + height: cmp::max(1, height >> level), array_layers: array_layers, cubemap_compatible: cubemap_compatible, } @@ -517,9 +511,9 @@ impl ImageDimensions { debug_assert_ne!(width, 0); debug_assert_ne!(height, 0); ImageDimensions::Dim3d { - width: (((width - 1) >> level) + 1).next_power_of_two(), - height: (((height - 1) >> level) + 1).next_power_of_two(), - depth: (((depth - 1) >> level) + 1).next_power_of_two(), + width: cmp::max(1, width >> level), + height: cmp::max(1, height >> level), + depth: cmp::max(1, depth >> level), } }, }) @@ -546,7 +540,7 @@ mod tests { cubemap_compatible: false, array_layers: 1, }; - assert_eq!(dims.max_mipmaps(), 3); + assert_eq!(dims.max_mipmaps(), 2); let dims = ImageDimensions::Dim2d { width: 512, @@ -568,67 +562,61 @@ mod tests { assert_eq!(dims.mipmap_dimensions(0), Some(dims)); assert_eq!(dims.mipmap_dimensions(1), Some(ImageDimensions::Dim2d { - width: 256, - height: 128, + width: 141, + height: 87, cubemap_compatible: false, array_layers: 1, })); assert_eq!(dims.mipmap_dimensions(2), Some(ImageDimensions::Dim2d { - width: 128, - height: 64, + width: 70, + height: 43, cubemap_compatible: false, array_layers: 1, })); assert_eq!(dims.mipmap_dimensions(3), Some(ImageDimensions::Dim2d { - width: 64, - height: 32, + width: 35, + height: 21, cubemap_compatible: false, array_layers: 1, })); + assert_eq!(dims.mipmap_dimensions(4), Some(ImageDimensions::Dim2d { - width: 32, - height: 16, + width: 17, + height: 10, cubemap_compatible: false, array_layers: 1, })); assert_eq!(dims.mipmap_dimensions(5), Some(ImageDimensions::Dim2d { - width: 16, - height: 8, + width: 8, + height: 5, cubemap_compatible: false, array_layers: 1, })); assert_eq!(dims.mipmap_dimensions(6), - Some(ImageDimensions::Dim2d { - width: 8, - height: 4, - cubemap_compatible: false, - array_layers: 1, - })); - assert_eq!(dims.mipmap_dimensions(7), Some(ImageDimensions::Dim2d { width: 4, height: 2, cubemap_compatible: false, array_layers: 1, })); - assert_eq!(dims.mipmap_dimensions(8), + assert_eq!(dims.mipmap_dimensions(7), Some(ImageDimensions::Dim2d { width: 2, height: 1, cubemap_compatible: false, array_layers: 1, })); - assert_eq!(dims.mipmap_dimensions(9), + assert_eq!(dims.mipmap_dimensions(8), Some(ImageDimensions::Dim2d { width: 1, height: 1, cubemap_compatible: false, array_layers: 1, })); - assert_eq!(dims.mipmap_dimensions(10), None); + assert_eq!(dims.mipmap_dimensions(9), None); } }