Fix cube map mip-map-levels
This commit is contained in:
parent
e76d35d8d5
commit
71ddeee80c
1 changed files with 98 additions and 80 deletions
|
@ -381,6 +381,22 @@ impl ImageBuilder {
|
||||||
info.vk_image_create_info.extent.height,
|
info.vk_image_create_info.extent.height,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.mip_map_levels(levels)
|
||||||
|
}
|
||||||
|
_ => panic!("wrong builder type in ImageBuilder"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mip_map_levels(mut self, levels: u32) -> Self {
|
||||||
|
match self.builder_type {
|
||||||
|
ImageBuilderInternalType::NewImage(ref mut info) => {
|
||||||
|
let max_levels = Self::calc_mip_map_levels(
|
||||||
|
info.vk_image_create_info.extent.width,
|
||||||
|
info.vk_image_create_info.extent.height,
|
||||||
|
);
|
||||||
|
|
||||||
|
debug_assert!(levels <= max_levels, "too many mip maps levels");
|
||||||
|
|
||||||
info.vk_image_create_info.mipLevels = levels;
|
info.vk_image_create_info.mipLevels = levels;
|
||||||
self.subresource_range.levelCount = levels;
|
self.subresource_range.levelCount = levels;
|
||||||
|
|
||||||
|
@ -1276,90 +1292,92 @@ fn blit_mip_maps(
|
||||||
image: &Arc<Image>,
|
image: &Arc<Image>,
|
||||||
target_image_layout: VkImageLayout,
|
target_image_layout: VkImageLayout,
|
||||||
) {
|
) {
|
||||||
let mut mip_width = image.width();
|
for layer in 0..image.layers() {
|
||||||
let mut mip_height = image.height();
|
// subresource information
|
||||||
|
let mut subresource_range = VkImageSubresourceRange {
|
||||||
// subresource information
|
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
||||||
let mut subresource_range = VkImageSubresourceRange {
|
baseMipLevel: 0,
|
||||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
levelCount: 1,
|
||||||
baseMipLevel: 0,
|
baseArrayLayer: layer,
|
||||||
levelCount: 1,
|
layerCount: image.layers(),
|
||||||
baseArrayLayer: 0,
|
|
||||||
layerCount: image.layers(),
|
|
||||||
};
|
|
||||||
|
|
||||||
for i in 1..image.levels() {
|
|
||||||
let source_mip_level = i - 1;
|
|
||||||
let target_mip_level = i;
|
|
||||||
|
|
||||||
// transition the previous mip level from destination to source
|
|
||||||
subresource_range.baseMipLevel = source_mip_level;
|
|
||||||
buffer_recorder.set_image_layout(
|
|
||||||
image,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
||||||
subresource_range.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// create the blit information to blit the data from one mip level to another
|
|
||||||
let image_blit = VkImageBlit {
|
|
||||||
srcSubresource: VkImageSubresourceLayers {
|
|
||||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
|
||||||
mipLevel: source_mip_level,
|
|
||||||
baseArrayLayer: 0,
|
|
||||||
layerCount: 1,
|
|
||||||
},
|
|
||||||
srcOffsets: [
|
|
||||||
VkOffset3D { x: 0, y: 0, z: 0 },
|
|
||||||
VkOffset3D {
|
|
||||||
x: mip_width as i32,
|
|
||||||
y: mip_height as i32,
|
|
||||||
z: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
dstSubresource: VkImageSubresourceLayers {
|
|
||||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
|
||||||
mipLevel: target_mip_level,
|
|
||||||
baseArrayLayer: 0,
|
|
||||||
layerCount: 1,
|
|
||||||
},
|
|
||||||
dstOffsets: [
|
|
||||||
VkOffset3D { x: 0, y: 0, z: 0 },
|
|
||||||
VkOffset3D {
|
|
||||||
x: if mip_width > 1 {
|
|
||||||
mip_width as i32 / 2
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
},
|
|
||||||
y: if mip_height > 1 {
|
|
||||||
mip_height as i32 / 2
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
},
|
|
||||||
z: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// execute the actual blit
|
let mut mip_width = image.width();
|
||||||
buffer_recorder.blit_image(
|
let mut mip_height = image.height();
|
||||||
image,
|
|
||||||
image,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
&[image_blit],
|
|
||||||
VK_FILTER_LINEAR,
|
|
||||||
);
|
|
||||||
|
|
||||||
// set mip level i - 1 to target layout
|
for i in 1..image.levels() {
|
||||||
buffer_recorder.set_image_layout(image, target_image_layout, subresource_range.clone());
|
let source_mip_level = i - 1;
|
||||||
|
let target_mip_level = i;
|
||||||
|
|
||||||
image.set_image_layout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
// transition the previous mip level from destination to source
|
||||||
|
subresource_range.baseMipLevel = source_mip_level;
|
||||||
|
buffer_recorder.set_image_layout(
|
||||||
|
image,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
subresource_range.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
mip_width = if mip_width > 1 { mip_width / 2 } else { 1 };
|
// create the blit information to blit the data from one mip level to another
|
||||||
mip_height = if mip_height > 1 { mip_height / 2 } else { 1 };
|
let image_blit = VkImageBlit {
|
||||||
|
srcSubresource: VkImageSubresourceLayers {
|
||||||
|
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
||||||
|
mipLevel: source_mip_level,
|
||||||
|
baseArrayLayer: layer,
|
||||||
|
layerCount: 1,
|
||||||
|
},
|
||||||
|
srcOffsets: [
|
||||||
|
VkOffset3D { x: 0, y: 0, z: 0 },
|
||||||
|
VkOffset3D {
|
||||||
|
x: mip_width as i32,
|
||||||
|
y: mip_height as i32,
|
||||||
|
z: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
dstSubresource: VkImageSubresourceLayers {
|
||||||
|
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
||||||
|
mipLevel: target_mip_level,
|
||||||
|
baseArrayLayer: layer,
|
||||||
|
layerCount: 1,
|
||||||
|
},
|
||||||
|
dstOffsets: [
|
||||||
|
VkOffset3D { x: 0, y: 0, z: 0 },
|
||||||
|
VkOffset3D {
|
||||||
|
x: if mip_width > 1 {
|
||||||
|
mip_width as i32 / 2
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
},
|
||||||
|
y: if mip_height > 1 {
|
||||||
|
mip_height as i32 / 2
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
},
|
||||||
|
z: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// execute the actual blit
|
||||||
|
buffer_recorder.blit_image(
|
||||||
|
image,
|
||||||
|
image,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
&[image_blit],
|
||||||
|
VK_FILTER_LINEAR,
|
||||||
|
);
|
||||||
|
|
||||||
|
// set mip level i - 1 to target layout
|
||||||
|
buffer_recorder.set_image_layout(image, target_image_layout, subresource_range.clone());
|
||||||
|
|
||||||
|
image.set_image_layout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
mip_width = if mip_width > 1 { mip_width / 2 } else { 1 };
|
||||||
|
mip_height = if mip_height > 1 { mip_height / 2 } else { 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// set last level to be target layout
|
||||||
|
subresource_range.baseMipLevel = image.levels() - 1;
|
||||||
|
buffer_recorder.set_image_layout(image, target_image_layout, subresource_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set last level to be target layout
|
|
||||||
subresource_range.baseMipLevel = image.levels() - 1;
|
|
||||||
buffer_recorder.set_image_layout(image, target_image_layout, subresource_range);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue