Skip to content

Commit 4593f95

Browse files
vk: fix surface view formats validation error (#3432)
Co-authored-by: Connor Fitzgerald <[email protected]>
1 parent 0d5b484 commit 4593f95

File tree

4 files changed

+70
-10
lines changed

4 files changed

+70
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Bottom level categories:
6161
#### Vulkan
6262

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

6566
### Bug Fixes
6667

wgpu-hal/src/vulkan/device.rs

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,20 +217,32 @@ impl super::DeviceShared {
217217
.iter()
218218
.map(|at| self.private_caps.map_texture_format(at.view_format))
219219
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
220+
let vk_view_formats_list = e
221+
.key()
222+
.attachments
223+
.iter()
224+
.map(|at| at.raw_view_formats.clone())
225+
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
226+
220227
let vk_image_infos = e
221228
.key()
222229
.attachments
223230
.iter()
224231
.enumerate()
225232
.map(|(i, at)| {
226-
vk::FramebufferAttachmentImageInfo::builder()
233+
let mut info = vk::FramebufferAttachmentImageInfo::builder()
227234
.usage(conv::map_texture_usage(at.view_usage))
228235
.flags(at.raw_image_flags)
229236
.width(e.key().extent.width)
230237
.height(e.key().extent.height)
231-
.layer_count(e.key().extent.depth_or_array_layers)
232-
.view_formats(&vk_view_formats[i..i + 1])
233-
.build()
238+
.layer_count(e.key().extent.depth_or_array_layers);
239+
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkRenderPassBeginInfo.html#VUID-VkRenderPassBeginInfo-framebuffer-03214
240+
if vk_view_formats_list[i].is_empty() {
241+
info = info.view_formats(&vk_view_formats[i..i + 1]);
242+
} else {
243+
info = info.view_formats(&vk_view_formats_list[i]);
244+
};
245+
info.build()
234246
})
235247
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
236248

@@ -550,6 +562,7 @@ impl super::Device {
550562
let original_format = self.shared.private_caps.map_texture_format(config.format);
551563
let mut raw_flags = vk::SwapchainCreateFlagsKHR::empty();
552564
let mut raw_view_formats: Vec<vk::Format> = vec![];
565+
let mut wgt_view_formats = vec![];
553566
if !config.view_formats.is_empty() {
554567
raw_flags |= vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT;
555568
raw_view_formats = config
@@ -558,6 +571,9 @@ impl super::Device {
558571
.map(|f| self.shared.private_caps.map_texture_format(*f))
559572
.collect();
560573
raw_view_formats.push(original_format);
574+
575+
wgt_view_formats = config.view_formats.clone();
576+
wgt_view_formats.push(config.format);
561577
}
562578

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

618634
Ok(super::Swapchain {
619635
raw,
636+
raw_flags,
620637
functor,
621638
device: Arc::clone(&self.shared),
622639
fence,
623640
images,
624641
config: config.clone(),
642+
view_formats: wgt_view_formats,
625643
})
626644
}
627645

@@ -630,11 +648,26 @@ impl super::Device {
630648
/// - `vk_image` must be created respecting `desc`
631649
/// - If `drop_guard` is `Some`, the application must manually destroy the image handle. This
632650
/// can be done inside the `Drop` impl of `drop_guard`.
651+
/// - If the `ImageCreateFlags` does not contain `MUTABLE_FORMAT`, the `view_formats` of `desc` must be empty.
633652
pub unsafe fn texture_from_raw(
634653
vk_image: vk::Image,
635654
desc: &crate::TextureDescriptor,
636655
drop_guard: Option<crate::DropGuard>,
637656
) -> super::Texture {
657+
let mut raw_flags = vk::ImageCreateFlags::empty();
658+
let mut view_formats = vec![];
659+
for tf in desc.view_formats.iter() {
660+
if *tf == desc.format {
661+
continue;
662+
}
663+
view_formats.push(*tf);
664+
}
665+
if !view_formats.is_empty() {
666+
raw_flags |=
667+
vk::ImageCreateFlags::MUTABLE_FORMAT | vk::ImageCreateFlags::EXTENDED_USAGE;
668+
view_formats.push(desc.format)
669+
}
670+
638671
super::Texture {
639672
raw: vk_image,
640673
drop_guard,
@@ -644,6 +677,7 @@ impl super::Device {
644677
format_info: desc.format.describe(),
645678
raw_flags: vk::ImageCreateFlags::empty(),
646679
copy_size: desc.copy_extent(),
680+
view_formats,
647681
}
648682
}
649683

@@ -908,20 +942,24 @@ impl crate::Device<super::Api> for super::Device {
908942
}
909943

910944
let original_format = self.shared.private_caps.map_texture_format(desc.format);
911-
let mut hal_view_formats: Vec<vk::Format> = vec![];
945+
let mut vk_view_formats = vec![];
946+
let mut wgt_view_formats = vec![];
912947
if !desc.view_formats.is_empty() {
913948
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
949+
wgt_view_formats = desc.view_formats.clone();
950+
wgt_view_formats.push(desc.format);
951+
914952
if self.shared_instance().driver_api_version >= vk::API_VERSION_1_2
915953
|| self
916954
.enabled_device_extensions()
917955
.contains(&vk::KhrImageFormatListFn::name())
918956
{
919-
hal_view_formats = desc
957+
vk_view_formats = desc
920958
.view_formats
921959
.iter()
922960
.map(|f| self.shared.private_caps.map_texture_format(*f))
923961
.collect();
924-
hal_view_formats.push(original_format)
962+
vk_view_formats.push(original_format)
925963
}
926964
}
927965

@@ -939,8 +977,8 @@ impl crate::Device<super::Api> for super::Device {
939977
.initial_layout(vk::ImageLayout::UNDEFINED);
940978

941979
let mut format_list_info = vk::ImageFormatListCreateInfo::builder();
942-
if !hal_view_formats.is_empty() {
943-
format_list_info = format_list_info.view_formats(&hal_view_formats);
980+
if !vk_view_formats.is_empty() {
981+
format_list_info = format_list_info.view_formats(&vk_view_formats);
944982
vk_info = vk_info.push_next(&mut format_list_info);
945983
}
946984

@@ -981,6 +1019,7 @@ impl crate::Device<super::Api> for super::Device {
9811019
format_info: desc.format.describe(),
9821020
raw_flags,
9831021
copy_size,
1022+
view_formats: wgt_view_formats,
9841023
})
9851024
}
9861025
unsafe fn destroy_texture(&self, texture: super::Texture) {
@@ -1036,6 +1075,11 @@ impl crate::Device<super::Api> for super::Device {
10361075
raw_image_flags: texture.raw_flags,
10371076
view_usage,
10381077
view_format: desc.format,
1078+
raw_view_formats: texture
1079+
.view_formats
1080+
.iter()
1081+
.map(|tf| self.shared.private_caps.map_texture_format(*tf))
1082+
.collect(),
10391083
};
10401084

10411085
Ok(super::TextureView {

wgpu-hal/src/vulkan/instance.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,16 @@ impl crate::Surface<super::Api> for super::Surface {
782782
.map_err(crate::DeviceError::from)?;
783783
unsafe { sc.device.raw.reset_fences(fences) }.map_err(crate::DeviceError::from)?;
784784

785+
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkRenderPassBeginInfo.html#VUID-VkRenderPassBeginInfo-framebuffer-03209
786+
let raw_flags = if sc
787+
.raw_flags
788+
.contains(vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT)
789+
{
790+
vk::ImageCreateFlags::MUTABLE_FORMAT | vk::ImageCreateFlags::EXTENDED_USAGE
791+
} else {
792+
vk::ImageCreateFlags::empty()
793+
};
794+
785795
let texture = super::SurfaceTexture {
786796
index,
787797
texture: super::Texture {
@@ -791,12 +801,13 @@ impl crate::Surface<super::Api> for super::Surface {
791801
usage: sc.config.usage,
792802
aspects: crate::FormatAspects::COLOR,
793803
format_info: sc.config.format.describe(),
794-
raw_flags: vk::ImageCreateFlags::empty(),
804+
raw_flags,
795805
copy_size: crate::CopyExtent {
796806
width: sc.config.extent.width,
797807
height: sc.config.extent.height,
798808
depth: 1,
799809
},
810+
view_formats: sc.view_formats.clone(),
800811
},
801812
};
802813
Ok(Some(crate::AcquiredSurfaceTexture {

wgpu-hal/src/vulkan/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,13 @@ pub struct Instance {
9696

9797
struct Swapchain {
9898
raw: vk::SwapchainKHR,
99+
raw_flags: vk::SwapchainCreateFlagsKHR,
99100
functor: khr::Swapchain,
100101
device: Arc<DeviceShared>,
101102
fence: vk::Fence,
102103
images: Vec<vk::Image>,
103104
config: crate::SurfaceConfiguration,
105+
view_formats: Vec<wgt::TextureFormat>,
104106
}
105107

106108
pub struct Surface {
@@ -225,6 +227,7 @@ struct FramebufferAttachment {
225227
raw_image_flags: vk::ImageCreateFlags,
226228
view_usage: crate::TextureUses,
227229
view_format: wgt::TextureFormat,
230+
raw_view_formats: Vec<vk::Format>,
228231
}
229232

230233
#[derive(Clone, Eq, Hash, PartialEq)]
@@ -294,6 +297,7 @@ pub struct Texture {
294297
format_info: wgt::TextureFormatInfo,
295298
raw_flags: vk::ImageCreateFlags,
296299
copy_size: crate::CopyExtent,
300+
view_formats: Vec<wgt::TextureFormat>,
297301
}
298302

299303
impl Texture {

0 commit comments

Comments
 (0)