Skip to content

Commit

Permalink
add: support for 3D images
Browse files Browse the repository at this point in the history
* Exposed Image View Type and Image Type implicitely (through Extent3D).

* Applied reviewed changes

* update doc

---------

Co-authored-by: NotAPenguin <michiel.vandeginste@gmail.com>
  • Loading branch information
jedjoud10 and NotAPenguin0 authored Jul 13, 2023
1 parent a49d400 commit 7a88c54
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 35 deletions.
11 changes: 8 additions & 3 deletions examples/01_basic/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,16 @@ impl ExampleApp for Basic {
let image = Image::new(
ctx.device.clone(),
&mut ctx.allocator,
800,
600,
vk::Extent3D {
width: 800,
height: 600,
depth: 1,
},
vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::SAMPLED,
vk::Format::R8G8B8A8_SRGB,
vk::SampleCountFlags::TYPE_1,
1,
1,
)?;
ctx.device.set_name(&image, "Render Image")?;
let data: Vec<f32> = vec![
Expand All @@ -89,7 +94,7 @@ impl ExampleApp for Basic {
];

let resources = Resources {
offscreen_view: image.view(vk::ImageAspectFlags::COLOR)?,
offscreen_view: image.whole_view(vk::ImageAspectFlags::COLOR)?,
offscreen: image,
sampler: Sampler::default(ctx.device.clone())?,
vertex_buffer: staged_buffer_upload(
Expand Down
11 changes: 8 additions & 3 deletions examples/03_raytracing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,18 @@ impl ExampleApp for RaytracingSample {
let attachment = Image::new(
ctx.device.clone(),
&mut ctx.allocator,
800,
600,
vk::Extent3D {
width: 800,
height: 600,
depth: 1,
},
vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE,
vk::Format::R32G32B32A32_SFLOAT,
vk::SampleCountFlags::TYPE_1,
1,
1
)?;
let view = attachment.view(vk::ImageAspectFlags::COLOR)?;
let view = attachment.whole_view(vk::ImageAspectFlags::COLOR)?;

let sampler = Sampler::default(ctx.device.clone())?;

Expand Down
12 changes: 9 additions & 3 deletions examples/04_fsr2/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

use std::time::Instant;

use anyhow::Result;
Expand Down Expand Up @@ -48,13 +49,18 @@ impl Attachment {
let image = Image::new(
ctx.device.clone(),
&mut ctx.allocator,
width,
height,
vk::Extent3D {
width,
height,
depth: 1
},
usage | extra_usage,
format,
vk::SampleCountFlags::TYPE_1,
1,
1,
)?;
let view = image.view(aspect)?;
let view = image.whole_view(aspect)?;
Ok(Self {
image,
view,
Expand Down
123 changes: 99 additions & 24 deletions src/resource/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ pub struct ImgView {
id: u64,
}

/// Settings that describe how an image view should be created from its Image
pub struct ImageViewCreateInfo {
/// Image aspect
pub aspect: vk::ImageAspectFlags,
/// View type of the image view
pub view_type: vk::ImageViewType,
/// Base mip level (starting mip level)
pub base_mip_level: u32,
/// Number of mip levels to use in the view (set to None to use the rest)
pub level_count: Option<u32>,
/// Base layer (starting layer)
pub base_layer: u32,
/// Number of layers to use in the view (set to None to use the rest)
pub layers: Option<u32>,
}


/// Reference-counted version of [`ImgView`].
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct ImageView(pub Arc<ImgView>);
Expand All @@ -111,11 +128,12 @@ impl<A: Allocator> Image<A> {
pub fn new(
device: Device,
alloc: &mut A,
width: u32,
height: u32,
extent: vk::Extent3D,
usage: vk::ImageUsageFlags,
format: vk::Format,
samples: vk::SampleCountFlags,
mip_levels: u32,
layers: u32,
) -> Result<Self> {
let sharing_mode = if device.is_single_queue()
|| usage.intersects(
Expand All @@ -127,21 +145,27 @@ impl<A: Allocator> Image<A> {
vk::SharingMode::CONCURRENT
};

let image_type = if extent.height == 1 && extent.depth == 1 {
vk::ImageType::TYPE_1D
} else if extent.height > 1 {
vk::ImageType::TYPE_2D
} else if extent.depth > 1 {
vk::ImageType::TYPE_3D
} else {
return Err(anyhow::anyhow!("Image extents invalid"));
};

let handle = unsafe {
device.create_image(
&vk::ImageCreateInfo {
s_type: vk::StructureType::IMAGE_CREATE_INFO,
p_next: std::ptr::null(),
flags: Default::default(),
image_type: vk::ImageType::TYPE_2D,
image_type,
format,
extent: vk::Extent3D {
width,
height,
depth: 1,
},
mip_levels: 1,
array_layers: 1,
extent,
mip_levels,
array_layers: layers,
samples,
tiling: vk::ImageTiling::OPTIMAL,
usage,
Expand Down Expand Up @@ -176,13 +200,9 @@ impl<A: Allocator> Image<A> {
device,
handle,
format,
size: vk::Extent3D {
width,
height,
depth: 1,
},
layers: 1,
mip_levels: 1,
size: extent,
layers,
mip_levels,
samples,
memory: Some(memory),
})
Expand Down Expand Up @@ -210,26 +230,81 @@ impl<A: Allocator> Image<A> {
}

/// Construct a trivial [`ImageView`] from this [`Image`]. This is an image view that views the
/// entire image subresource.
/// whole image subresource.
/// * `aspect` - The image aspect flags that will be used to create the image view
/// <br>
/// <br>
/// # Lifetime
/// The returned [`ImageView`] is valid as long as `self` is valid.
pub fn view(&self, aspect: vk::ImageAspectFlags) -> Result<ImageView> {
pub fn whole_view(&self, aspect: vk::ImageAspectFlags) -> Result<ImageView> {
let view_type = if self.size.width == 1 && self.size.width == 1 && self.size.depth == 1 {
vk::ImageViewType::TYPE_1D
} else if self.size.height > 1 {
vk::ImageViewType::TYPE_2D
} else if self.size.depth > 1 {
vk::ImageViewType::TYPE_3D
} else {
anyhow::bail!("Image extents invalid");
};

self.view(
ImageViewCreateInfo {
aspect,
view_type,
base_mip_level: 0,
level_count: None,
base_layer: 0,
layers: None,
},
)
}

/// Construct an [`ImageView`] from this [`Image`]. This is an image view that views the
/// image subresource specified by the given arguments.
/// * `aspect` - The image aspect flags that will be used to create the image view
/// * `view_type` - The image type of the view. Must be supported by the image type of the current image
/// * `base_mip_level` - Starting mip level that the view sub-resource will look from
/// * `level_count` - End mip level that the view sub-resource will look to. Set to None to get the remainder of the mip levels
/// * `base_layer` - Starting layer that the view sub-resource will look from
/// * `layers` - End layer that the view sub-resource will look to. Set to None to get the remainder of the layer
/// <br>
/// <br>
/// # Lifetime
/// The returned [`ImageView`] is valid as long as `self` is valid.
pub fn view(
&self,
create_info: ImageViewCreateInfo,
) -> Result<ImageView> {
let ImageViewCreateInfo {
aspect,
view_type,
base_mip_level,
level_count,
base_layer,
layers
} = create_info;

// TODO: Validate args
let info = vk::ImageViewCreateInfo {
s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO,
p_next: std::ptr::null(),
flags: Default::default(),
image: self.handle,
view_type: vk::ImageViewType::TYPE_2D, // TODO: 3D images, cubemaps, etc
view_type,
format: self.format,
components: vk::ComponentMapping::default(),
subresource_range: vk::ImageSubresourceRange {
aspect_mask: aspect,
base_mip_level: 0,
level_count: self.mip_levels,
base_array_layer: 0,
layer_count: self.layers,
base_mip_level,
level_count: match level_count {
Some(count) => count,
None => self.mip_levels - base_mip_level,
},
base_array_layer: base_layer,
layer_count: match layers {
Some(count) => count,
None => self.layers - base_layer,
},
},
};

Expand Down
2 changes: 1 addition & 1 deletion src/wsi/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl<A: Allocator> FrameManager<A> {
vk::SampleCountFlags::TYPE_1,
);
// Create a trivial ImageView.
let view = image.view(vk::ImageAspectFlags::COLOR)?;
let view = image.whole_view(vk::ImageAspectFlags::COLOR)?;
Ok(SwapchainImage {
image,
view,
Expand Down
2 changes: 1 addition & 1 deletion src/wsi/swapchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl Swapchain {
vk::SampleCountFlags::TYPE_1,
);
// Create a trivial ImgView.
let view = image.view(vk::ImageAspectFlags::COLOR)?;
let view = image.whole_view(vk::ImageAspectFlags::COLOR)?;
// Bundle them together into an owning ImageView
Ok(SwapchainImage {
image,
Expand Down

0 comments on commit 7a88c54

Please sign in to comment.