Skip to content

Commit ee6b710

Browse files
committed
hal/vulkan: generate separate hash identity for Texture/TextureViews
1 parent 96ef5ec commit ee6b710

File tree

5 files changed

+106
-13
lines changed

5 files changed

+106
-13
lines changed

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use core::{ffi::CStr, marker::PhantomData};
44
use ash::{ext, google, khr, vk};
55
use parking_lot::Mutex;
66

7+
use crate::vulkan::ResourceIdentityFactory;
8+
79
use super::conv;
810

911
fn depth_stencil_required_flags() -> vk::FormatFeatureFlags {
@@ -2162,6 +2164,9 @@ impl super::Adapter {
21622164
self.private_caps.maximum_samplers,
21632165
)),
21642166
memory_allocations_counter: Default::default(),
2167+
2168+
texture_identity_factory: ResourceIdentityFactory::new(),
2169+
texture_view_identity_factory: ResourceIdentityFactory::new(),
21652170
});
21662171

21672172
let relay_semaphores = super::RelaySemaphores::new(&shared)?;

wgpu-hal/src/vulkan/command.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ impl super::CommandEncoder {
6161
Entry::Vacant(e) => {
6262
let super::FramebufferKey {
6363
raw_pass,
64-
ref attachments,
64+
ref attachment_views,
65+
attachment_identities: _,
6566
extent,
6667
} = *e.key();
6768

@@ -70,7 +71,7 @@ impl super::CommandEncoder {
7071
.width(extent.width)
7172
.height(extent.height)
7273
.layers(extent.depth_or_array_layers)
73-
.attachments(attachments);
74+
.attachments(attachment_views);
7475

7576
let raw = unsafe { self.device.raw.create_framebuffer(&vk_info, None).unwrap() };
7677
*e.insert(raw)
@@ -81,12 +82,13 @@ impl super::CommandEncoder {
8182
fn make_temp_texture_view(
8283
&mut self,
8384
key: super::TempTextureViewKey,
84-
) -> Result<vk::ImageView, crate::DeviceError> {
85+
) -> Result<super::IdentifiedTextureView, crate::DeviceError> {
8586
Ok(match self.temp_texture_views.entry(key) {
8687
Entry::Occupied(e) => *e.get(),
8788
Entry::Vacant(e) => {
8889
let super::TempTextureViewKey {
8990
texture,
91+
texture_identity: _,
9092
format,
9193
mip_level,
9294
depth_slice,
@@ -105,7 +107,10 @@ impl super::CommandEncoder {
105107
});
106108
let raw = unsafe { self.device.raw.create_image_view(&vk_info, None) }
107109
.map_err(super::map_host_device_oom_and_ioca_err)?;
108-
*e.insert(raw)
110+
111+
let identity = self.device.texture_view_identity_factory.next();
112+
113+
*e.insert(super::IdentifiedTextureView { raw, identity })
109114
}
110115
})
111116
}
@@ -779,7 +784,8 @@ impl crate::CommandEncoder for super::CommandEncoder {
779784
};
780785
let mut fb_key = super::FramebufferKey {
781786
raw_pass: vk::RenderPass::null(),
782-
attachments: ArrayVec::default(),
787+
attachment_views: ArrayVec::default(),
788+
attachment_identities: ArrayVec::default(),
783789
extent: desc.extent,
784790
};
785791

@@ -788,13 +794,14 @@ impl crate::CommandEncoder for super::CommandEncoder {
788794
let color_view = if cat.target.view.dimension == wgt::TextureViewDimension::D3 {
789795
let key = super::TempTextureViewKey {
790796
texture: cat.target.view.raw_texture,
797+
texture_identity: cat.target.view.texture_identity,
791798
format: cat.target.view.raw_format,
792799
mip_level: cat.target.view.base_mip_level,
793800
depth_slice: cat.depth_slice.unwrap(),
794801
};
795802
self.make_temp_texture_view(key)?
796803
} else {
797-
cat.target.view.raw
804+
cat.target.view.identified_raw_view()
798805
};
799806

800807
vk_clear_values.push(vk::ClearValue {
@@ -809,10 +816,10 @@ impl crate::CommandEncoder for super::CommandEncoder {
809816
};
810817

811818
rp_key.colors.push(Some(color));
812-
fb_key.attachments.push(color_view);
819+
fb_key.push_view(color_view);
813820
if let Some(ref at) = cat.resolve_target {
814821
vk_clear_values.push(unsafe { mem::zeroed() });
815-
fb_key.attachments.push(at.view.raw);
822+
fb_key.push_view(at.view.identified_raw_view());
816823
}
817824

818825
// Assert this attachment is valid for the detected multiview, as a sanity check
@@ -838,7 +845,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
838845
base: ds.target.make_attachment_key(ds.depth_ops),
839846
stencil_ops: ds.stencil_ops,
840847
});
841-
fb_key.attachments.push(ds.target.view.raw);
848+
fb_key.push_view(ds.target.view.identified_raw_view());
842849

843850
// Assert this attachment is valid for the detected multiview, as a sanity check
844851
// The driver crash for this is really bad on AMD, so the check is worth it

wgpu-hal/src/vulkan/device.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ impl super::Device {
603603
/// `drop_callback` is [`Some`], `vk_image` must be valid until the callback is called.
604604
/// - If the `ImageCreateFlags` does not contain `MUTABLE_FORMAT`, the `view_formats` of `desc` must be empty.
605605
pub unsafe fn texture_from_raw(
606+
&self,
606607
vk_image: vk::Image,
607608
desc: &crate::TextureDescriptor,
608609
drop_callback: Option<crate::DropCallback>,
@@ -624,6 +625,8 @@ impl super::Device {
624625
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
625626
}
626627

628+
let identity = self.shared.texture_identity_factory.next();
629+
627630
let drop_guard = crate::DropGuard::from_option(drop_callback);
628631

629632
super::Texture {
@@ -633,6 +636,7 @@ impl super::Device {
633636
block: None,
634637
format: desc.format,
635638
copy_size: desc.copy_extent(),
639+
identity,
636640
}
637641
}
638642

@@ -796,6 +800,8 @@ impl super::Device {
796800
unsafe { self.shared.set_object_name(image.raw, label) };
797801
}
798802

803+
let identity = self.shared.texture_identity_factory.next();
804+
799805
self.counters.textures.add(1);
800806

801807
Ok(super::Texture {
@@ -805,6 +811,7 @@ impl super::Device {
805811
block: None,
806812
format: desc.format,
807813
copy_size: image.copy_size,
814+
identity,
808815
})
809816
}
810817

@@ -1274,6 +1281,8 @@ impl crate::Device for super::Device {
12741281
unsafe { self.shared.set_object_name(image.raw, label) };
12751282
}
12761283

1284+
let identity = self.shared.texture_identity_factory.next();
1285+
12771286
self.counters.textures.add(1);
12781287

12791288
Ok(super::Texture {
@@ -1283,6 +1292,7 @@ impl crate::Device for super::Device {
12831292
block: Some(block),
12841293
format: desc.format,
12851294
copy_size: image.copy_size,
1295+
identity,
12861296
})
12871297
}
12881298
unsafe fn destroy_texture(&self, texture: super::Texture) {
@@ -1335,6 +1345,8 @@ impl crate::Device for super::Device {
13351345
unsafe { self.shared.set_object_name(raw, label) };
13361346
}
13371347

1348+
let identity = self.shared.texture_view_identity_factory.next();
1349+
13381350
self.counters.texture_views.add(1);
13391351

13401352
Ok(super::TextureView {
@@ -1345,6 +1357,8 @@ impl crate::Device for super::Device {
13451357
raw_format,
13461358
base_mip_level: desc.range.base_mip_level,
13471359
dimension: desc.dimension,
1360+
texture_identity: texture.identity,
1361+
view_identity: identity,
13481362
})
13491363
}
13501364
unsafe fn destroy_texture_view(&self, view: super::TextureView) {

wgpu-hal/src/vulkan/instance.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,8 @@ impl crate::Surface for super::Surface {
11391139
return Err(crate::SurfaceError::Outdated);
11401140
}
11411141

1142+
let identity = swapchain.device.texture_identity_factory.next();
1143+
11421144
let texture = super::SurfaceTexture {
11431145
index,
11441146
texture: super::Texture {
@@ -1152,6 +1154,7 @@ impl crate::Surface for super::Surface {
11521154
height: swapchain.config.extent.height,
11531155
depth: 1,
11541156
},
1157+
identity,
11551158
},
11561159
surface_semaphores: swapchain_semaphores_arc,
11571160
};

wgpu-hal/src/vulkan/mod.rs

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,15 @@ mod semaphore_list;
3636
pub use adapter::PhysicalDeviceFeatures;
3737

3838
use alloc::{boxed::Box, ffi::CString, sync::Arc, vec::Vec};
39-
use core::{borrow::Borrow, ffi::CStr, fmt, marker::PhantomData, mem, num::NonZeroU32};
39+
use core::{
40+
borrow::Borrow,
41+
ffi::CStr,
42+
fmt,
43+
marker::PhantomData,
44+
mem,
45+
num::NonZeroU32,
46+
sync::atomic::{AtomicU64, Ordering},
47+
};
4048

4149
use arrayvec::ArrayVec;
4250
use ash::{ext, khr, vk};
@@ -651,6 +659,9 @@ struct DeviceShared {
651659
render_passes: Mutex<FastHashMap<RenderPassKey, vk::RenderPass>>,
652660
sampler_cache: Mutex<sampler::SamplerCache>,
653661
memory_allocations_counter: InternalCounter,
662+
663+
texture_identity_factory: ResourceIdentityFactory<vk::Image>,
664+
texture_view_identity_factory: ResourceIdentityFactory<vk::ImageView>,
654665
}
655666

656667
impl Drop for DeviceShared {
@@ -864,6 +875,7 @@ pub struct Texture {
864875
block: Option<gpu_alloc::MemoryBlock<vk::DeviceMemory>>,
865876
format: wgt::TextureFormat,
866877
copy_size: crate::CopyExtent,
878+
identity: ResourceIdentity<vk::Image>,
867879
}
868880

869881
impl crate::DynTexture for Texture {}
@@ -886,6 +898,8 @@ pub struct TextureView {
886898
raw_format: vk::Format,
887899
base_mip_level: u32,
888900
dimension: wgt::TextureViewDimension,
901+
texture_identity: ResourceIdentity<vk::Image>,
902+
view_identity: ResourceIdentity<vk::ImageView>,
889903
}
890904

891905
impl crate::DynTextureView for TextureView {}
@@ -897,6 +911,13 @@ impl TextureView {
897911
pub unsafe fn raw_handle(&self) -> vk::ImageView {
898912
self.raw
899913
}
914+
915+
fn identified_raw_view(&self) -> IdentifiedTextureView {
916+
IdentifiedTextureView {
917+
raw: self.raw,
918+
identity: self.view_identity,
919+
}
920+
}
900921
}
901922

902923
#[derive(Debug)]
@@ -956,16 +977,59 @@ impl Temp {
956977
}
957978
}
958979

980+
struct ResourceIdentityFactory<T> {
981+
next_id: AtomicU64,
982+
_phantom: PhantomData<T>,
983+
}
984+
985+
impl<T> ResourceIdentityFactory<T> {
986+
fn new() -> Self {
987+
Self {
988+
next_id: AtomicU64::new(1),
989+
_phantom: PhantomData,
990+
}
991+
}
992+
993+
/// Returns a new unique ID for a resource of type `T`.
994+
fn next(&self) -> ResourceIdentity<T> {
995+
ResourceIdentity {
996+
id: self.next_id.fetch_add(1, Ordering::Relaxed),
997+
_phantom: PhantomData,
998+
}
999+
}
1000+
}
1001+
1002+
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
1003+
struct ResourceIdentity<T> {
1004+
id: u64,
1005+
_phantom: PhantomData<T>,
1006+
}
1007+
9591008
#[derive(Clone, Eq, Hash, PartialEq)]
9601009
struct FramebufferKey {
9611010
raw_pass: vk::RenderPass,
962-
attachments: ArrayVec<vk::ImageView, { MAX_TOTAL_ATTACHMENTS }>,
1011+
attachment_identities: ArrayVec<ResourceIdentity<vk::ImageView>, { MAX_TOTAL_ATTACHMENTS }>,
1012+
attachment_views: ArrayVec<vk::ImageView, { MAX_TOTAL_ATTACHMENTS }>,
9631013
extent: wgt::Extent3d,
9641014
}
9651015

1016+
impl FramebufferKey {
1017+
fn push_view(&mut self, view: IdentifiedTextureView) {
1018+
self.attachment_identities.push(view.identity);
1019+
self.attachment_views.push(view.raw);
1020+
}
1021+
}
1022+
1023+
#[derive(Copy, Clone)]
1024+
struct IdentifiedTextureView {
1025+
raw: vk::ImageView,
1026+
identity: ResourceIdentity<vk::ImageView>,
1027+
}
1028+
9661029
#[derive(Clone, Eq, Hash, PartialEq)]
9671030
struct TempTextureViewKey {
9681031
texture: vk::Image,
1032+
texture_identity: ResourceIdentity<vk::Image>,
9691033
format: vk::Format,
9701034
mip_level: u32,
9711035
depth_slice: u32,
@@ -1008,7 +1072,7 @@ pub struct CommandEncoder {
10081072
end_of_pass_timer_query: Option<(vk::QueryPool, u32)>,
10091073

10101074
framebuffers: FastHashMap<FramebufferKey, vk::Framebuffer>,
1011-
temp_texture_views: FastHashMap<TempTextureViewKey, vk::ImageView>,
1075+
temp_texture_views: FastHashMap<TempTextureViewKey, IdentifiedTextureView>,
10121076

10131077
counters: Arc<wgt::HalCounters>,
10141078
}
@@ -1037,7 +1101,7 @@ impl Drop for CommandEncoder {
10371101
}
10381102

10391103
for (_, view) in self.temp_texture_views.drain() {
1040-
unsafe { self.device.raw.destroy_image_view(view, None) };
1104+
unsafe { self.device.raw.destroy_image_view(view.raw, None) };
10411105
}
10421106

10431107
self.counters.command_encoders.sub(1);

0 commit comments

Comments
 (0)