diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index ed761b34f6..f9e7426b43 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -852,7 +852,7 @@ impl Device { )); } - let mut allow_different_view_format = false; + let mut hal_view_formats = vec![]; for format in desc.view_formats.iter() { if desc.format == *format { continue; @@ -860,7 +860,7 @@ impl Device { if desc.format.remove_srgb_suffix() != format.remove_srgb_suffix() { return Err(CreateTextureError::InvalidViewFormat(*format, desc.format)); } - allow_different_view_format = true; + hal_view_formats.push(*format); } // Enforce having COPY_DST/DEPTH_STENCIL_WRIT/COLOR_TARGET otherwise we @@ -893,7 +893,7 @@ impl Device { format: desc.format, usage: hal_usage, memory_flags: hal::MemoryFlags::empty(), - allow_different_view_format, + view_formats: hal_view_formats, }; let raw_texture = unsafe { diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 6bcde926c8..bc7b042d8b 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -299,7 +299,7 @@ impl Example { format: wgt::TextureFormat::Rgba8UnormSrgb, usage: hal::TextureUses::COPY_DST | hal::TextureUses::RESOURCE, memory_flags: hal::MemoryFlags::empty(), - allow_different_view_format: false, + view_formats: vec![], }; let texture = unsafe { device.create_texture(&texture_desc).unwrap() }; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 57a1854b74..8d9b876a70 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -846,8 +846,8 @@ pub struct TextureDescriptor<'a> { pub usage: TextureUses, pub memory_flags: MemoryFlags, /// Allows views of this texture to have a different format - /// than the this texture does. - pub allow_different_view_format: bool, + /// than the texture does. + pub view_formats: Vec, } /// TextureView descriptor. diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 12a700d473..f76d3cc79b 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -589,11 +589,14 @@ impl PhysicalDeviceCapabilities { } if self.effective_api_version < vk::API_VERSION_1_2 { + // Optional `VK_KHR_image_format_list` + if self.supports_extension(vk::KhrImageFormatListFn::name()) { + extensions.push(vk::KhrImageFormatListFn::name()); + } + // Optional `VK_KHR_imageless_framebuffer` if self.supports_extension(vk::KhrImagelessFramebufferFn::name()) { extensions.push(vk::KhrImagelessFramebufferFn::name()); - // Require `VK_KHR_image_format_list` due to it being a dependency - extensions.push(vk::KhrImageFormatListFn::name()); // Require `VK_KHR_maintenance2` due to it being a dependency if self.effective_api_version < vk::API_VERSION_1_1 { extensions.push(vk::KhrMaintenance2Fn::name()); diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 62843487c8..41d7330440 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -895,14 +895,28 @@ impl crate::Device for super::Device { raw_flags |= vk::ImageCreateFlags::CUBE_COMPATIBLE; } - if desc.allow_different_view_format { + let original_format = self.shared.private_caps.map_texture_format(desc.format); + let mut hal_view_formats: Vec = vec![]; + if !desc.view_formats.is_empty() { raw_flags |= vk::ImageCreateFlags::MUTABLE_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 + .view_formats + .iter() + .map(|f| self.shared.private_caps.map_texture_format(*f)) + .collect(); + hal_view_formats.push(original_format) + } } - let vk_info = vk::ImageCreateInfo::builder() + let mut vk_info = vk::ImageCreateInfo::builder() .flags(raw_flags) .image_type(conv::map_texture_dimension(desc.dimension)) - .format(self.shared.private_caps.map_texture_format(desc.format)) + .format(original_format) .extent(vk::Extent3D { width: copy_size.width, height: copy_size.height, @@ -916,6 +930,12 @@ impl crate::Device for super::Device { .sharing_mode(vk::SharingMode::EXCLUSIVE) .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); + vk_info = vk_info.push_next(&mut format_list_info); + } + let raw = unsafe { self.shared.raw.create_image(&vk_info, None)? }; let req = unsafe { self.shared.raw.get_image_memory_requirements(raw) };