From 6ca6d84a87324c29a7415343455a6cb080b6f416 Mon Sep 17 00:00:00 2001 From: Matej Kormuth Date: Wed, 22 Jan 2020 02:12:31 +0100 Subject: [PATCH] fix #1292: add parentheses to fix int truncation (#1299) --- .../validity/copy_image_buffer.rs | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/vulkano/src/command_buffer/validity/copy_image_buffer.rs b/vulkano/src/command_buffer/validity/copy_image_buffer.rs index d77fb8cb..a70d02da 100644 --- a/vulkano/src/command_buffer/validity/copy_image_buffer.rs +++ b/vulkano/src/command_buffer/validity/copy_image_buffer.rs @@ -97,9 +97,7 @@ pub fn check_copy_buffer_image(device: &Device, buffer: &B, image: &I, image.format().ensure_accepts()?; { - let (block_width, block_height) = image.format().block_dimensions(); - let num_blocks = (image_size[0] + block_width - 1) / block_width * (image_size[1] + block_height - 1) / block_height * image_size[2] * image_num_layers; - let required_len = num_blocks as usize * image.format().rate() as usize; + let required_len = required_len_for_format(image.format(), image_size, image_num_layers); if required_len > buffer.len() { return Err(CheckCopyBufferImageError::BufferTooSmall { required_len: required_len, @@ -113,6 +111,39 @@ pub fn check_copy_buffer_image(device: &Device, buffer: &B, image: &I, Ok(()) } +/// Computes the minimum required len in elements for buffer with image data in specified +/// format of specified size. +fn required_len_for_format

(format: Format, image_size: [u32; 3], image_num_layers: u32) -> usize +where Format: AcceptsPixels

+{ + let (block_width, block_height) = format.block_dimensions(); + let num_blocks = (image_size[0] + block_width - 1) / block_width * ((image_size[1] + block_height - 1) / block_height) * image_size[2] * image_num_layers; + let required_len = num_blocks as usize * format.rate() as usize; + + return required_len; +} + +#[cfg(test)] +mod tests { + use crate::format::Format; + use command_buffer::validity::copy_image_buffer::required_len_for_format; + + #[test] + fn test_required_len_for_format() { + // issue #1292 + assert_eq!(required_len_for_format::(Format::BC1_RGBUnormBlock, [2048, 2048, 1], 1), 2097152); + // other test cases + assert_eq!(required_len_for_format::(Format::R8G8B8A8Unorm, [2048, 2048, 1], 1), 16777216); + assert_eq!(required_len_for_format::(Format::R4G4UnormPack8, [512, 512, 1], 1), 262144); + assert_eq!(required_len_for_format::(Format::R8G8B8Uscaled, [512, 512, 1], 1), 786432); + assert_eq!(required_len_for_format::(Format::R32G32Uint, [512, 512, 1], 1), 2097152); + assert_eq!(required_len_for_format::(Format::R32G32Uint, [512, 512, 1], 1), 524288); + assert_eq!(required_len_for_format::<[u32; 2]>(Format::R32G32Uint, [512, 512, 1], 1), 262144); + assert_eq!(required_len_for_format::(Format::ASTC_8x8UnormBlock, [512, 512, 1], 1), 65536); + assert_eq!(required_len_for_format::(Format::ASTC_12x12SrgbBlock, [512, 512, 1], 1), 29584); + } +} + /// Error that can happen from `check_copy_buffer_image`. #[derive(Debug, Copy, Clone)] pub enum CheckCopyBufferImageError {