Skip to content

Commit

Permalink
vk: fix surface view formats validation error (gfx-rs#3432)
Browse files Browse the repository at this point in the history
Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
  • Loading branch information
jinleili and cwfitzgerald committed Feb 9, 2023
1 parent 2f2206e commit f8cf01c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Bottom level categories:
#### Vulkan

- Improve format MSAA capabilities detection. By @jinleili in [#3429](https://github.com/gfx-rs/wgpu/pull/3429)
- Fix surface view formats validation error. By @jinleili in [#3432](https://github.com/gfx-rs/wgpu/pull/3432)

### Bug Fixes

Expand Down
62 changes: 53 additions & 9 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,20 +217,32 @@ impl super::DeviceShared {
.iter()
.map(|at| self.private_caps.map_texture_format(at.view_format))
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
let vk_view_formats_list = e
.key()
.attachments
.iter()
.map(|at| at.raw_view_formats.clone())
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();

let vk_image_infos = e
.key()
.attachments
.iter()
.enumerate()
.map(|(i, at)| {
vk::FramebufferAttachmentImageInfo::builder()
let mut info = vk::FramebufferAttachmentImageInfo::builder()
.usage(conv::map_texture_usage(at.view_usage))
.flags(at.raw_image_flags)
.width(e.key().extent.width)
.height(e.key().extent.height)
.layer_count(e.key().extent.depth_or_array_layers)
.view_formats(&vk_view_formats[i..i + 1])
.build()
.layer_count(e.key().extent.depth_or_array_layers);
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkRenderPassBeginInfo.html#VUID-VkRenderPassBeginInfo-framebuffer-03214
if vk_view_formats_list[i].is_empty() {
info = info.view_formats(&vk_view_formats[i..i + 1]);
} else {
info = info.view_formats(&vk_view_formats_list[i]);
};
info.build()
})
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();

Expand Down Expand Up @@ -550,6 +562,7 @@ impl super::Device {
let original_format = self.shared.private_caps.map_texture_format(config.format);
let mut raw_flags = vk::SwapchainCreateFlagsKHR::empty();
let mut raw_view_formats: Vec<vk::Format> = vec![];
let mut wgt_view_formats = vec![];
if !config.view_formats.is_empty() {
raw_flags |= vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT;
raw_view_formats = config
Expand All @@ -558,6 +571,9 @@ impl super::Device {
.map(|f| self.shared.private_caps.map_texture_format(*f))
.collect();
raw_view_formats.push(original_format);

wgt_view_formats = config.view_formats.clone();
wgt_view_formats.push(config.format);
}

let mut info = vk::SwapchainCreateInfoKHR::builder()
Expand Down Expand Up @@ -617,11 +633,13 @@ impl super::Device {

Ok(super::Swapchain {
raw,
raw_flags,
functor,
device: Arc::clone(&self.shared),
fence,
images,
config: config.clone(),
view_formats: wgt_view_formats,
})
}

Expand All @@ -630,11 +648,26 @@ impl super::Device {
/// - `vk_image` must be created respecting `desc`
/// - If `drop_guard` is `Some`, the application must manually destroy the image handle. This
/// can be done inside the `Drop` impl of `drop_guard`.
/// - If the `ImageCreateFlags` does not contain `MUTABLE_FORMAT`, the `view_formats` of `desc` must be empty.
pub unsafe fn texture_from_raw(
vk_image: vk::Image,
desc: &crate::TextureDescriptor,
drop_guard: Option<crate::DropGuard>,
) -> super::Texture {
let mut raw_flags = vk::ImageCreateFlags::empty();
let mut view_formats = vec![];
for tf in desc.view_formats.iter() {
if *tf == desc.format {
continue;
}
view_formats.push(*tf);
}
if !view_formats.is_empty() {
raw_flags |=
vk::ImageCreateFlags::MUTABLE_FORMAT | vk::ImageCreateFlags::EXTENDED_USAGE;
view_formats.push(desc.format)
}

super::Texture {
raw: vk_image,
drop_guard,
Expand All @@ -644,6 +677,7 @@ impl super::Device {
format_info: desc.format.describe(),
raw_flags: vk::ImageCreateFlags::empty(),
copy_size: crate::CopyExtent::map_extent_to_copy_size(&desc.size, desc.dimension),
view_formats,
}
}

Expand Down Expand Up @@ -916,20 +950,24 @@ impl crate::Device<super::Api> for super::Device {
}

let original_format = self.shared.private_caps.map_texture_format(desc.format);
let mut hal_view_formats: Vec<vk::Format> = vec![];
let mut vk_view_formats = vec![];
let mut wgt_view_formats = vec![];
if !desc.view_formats.is_empty() {
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
wgt_view_formats = desc.view_formats.clone();
wgt_view_formats.push(desc.format);

if self.shared_instance().driver_api_version >= vk::API_VERSION_1_2
|| self
.enabled_device_extensions()
.contains(&vk::KhrImageFormatListFn::name())
{
hal_view_formats = desc
vk_view_formats = desc
.view_formats
.iter()
.map(|f| self.shared.private_caps.map_texture_format(*f))
.collect();
hal_view_formats.push(original_format)
vk_view_formats.push(original_format)
}
}

Expand All @@ -951,8 +989,8 @@ impl crate::Device<super::Api> for super::Device {
.initial_layout(vk::ImageLayout::UNDEFINED);

let mut format_list_info = vk::ImageFormatListCreateInfo::builder();
if !hal_view_formats.is_empty() {
format_list_info = format_list_info.view_formats(&hal_view_formats);
if !vk_view_formats.is_empty() {
format_list_info = format_list_info.view_formats(&vk_view_formats);
vk_info = vk_info.push_next(&mut format_list_info);
}

Expand Down Expand Up @@ -993,6 +1031,7 @@ impl crate::Device<super::Api> for super::Device {
format_info: desc.format.describe(),
raw_flags,
copy_size,
view_formats: wgt_view_formats,
})
}
unsafe fn destroy_texture(&self, texture: super::Texture) {
Expand Down Expand Up @@ -1048,6 +1087,11 @@ impl crate::Device<super::Api> for super::Device {
raw_image_flags: texture.raw_flags,
view_usage,
view_format: desc.format,
raw_view_formats: texture
.view_formats
.iter()
.map(|tf| self.shared.private_caps.map_texture_format(*tf))
.collect(),
};

Ok(super::TextureView {
Expand Down
11 changes: 11 additions & 0 deletions wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,16 @@ impl crate::Surface<super::Api> for super::Surface {
.map_err(crate::DeviceError::from)?;
unsafe { sc.device.raw.reset_fences(fences) }.map_err(crate::DeviceError::from)?;

// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkRenderPassBeginInfo.html#VUID-VkRenderPassBeginInfo-framebuffer-03209
let raw_flags = if sc
.raw_flags
.contains(vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT)
{
vk::ImageCreateFlags::MUTABLE_FORMAT | vk::ImageCreateFlags::EXTENDED_USAGE
} else {
vk::ImageCreateFlags::empty()
};

let texture = super::SurfaceTexture {
index,
texture: super::Texture {
Expand All @@ -798,6 +808,7 @@ impl crate::Surface<super::Api> for super::Surface {
&sc.config.extent,
wgt::TextureDimension::D2,
),
view_formats: sc.view_formats.clone(),
},
};
Ok(Some(crate::AcquiredSurfaceTexture {
Expand Down
4 changes: 4 additions & 0 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ pub struct Instance {

struct Swapchain {
raw: vk::SwapchainKHR,
raw_flags: vk::SwapchainCreateFlagsKHR,
functor: khr::Swapchain,
device: Arc<DeviceShared>,
fence: vk::Fence,
images: Vec<vk::Image>,
config: crate::SurfaceConfiguration,
view_formats: Vec<wgt::TextureFormat>,
}

pub struct Surface {
Expand Down Expand Up @@ -225,6 +227,7 @@ struct FramebufferAttachment {
raw_image_flags: vk::ImageCreateFlags,
view_usage: crate::TextureUses,
view_format: wgt::TextureFormat,
raw_view_formats: Vec<vk::Format>,
}

#[derive(Clone, Eq, Hash, PartialEq)]
Expand Down Expand Up @@ -294,6 +297,7 @@ pub struct Texture {
format_info: wgt::TextureFormatInfo,
raw_flags: vk::ImageCreateFlags,
copy_size: crate::CopyExtent,
view_formats: Vec<wgt::TextureFormat>,
}

impl Texture {
Expand Down

0 comments on commit f8cf01c

Please sign in to comment.