Skip to content

Commit 702faa2

Browse files
committed
Fix allocation leaks on error paths
1 parent 8809021 commit 702faa2

2 files changed

Lines changed: 50 additions & 25 deletions

File tree

wgpu-hal/src/dx12/suballocation.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,12 +1076,17 @@ impl DeviceAllocationContext<'_> {
10761076
name,
10771077
)?;
10781078

1079+
self.counters.buffer_memory.add(allocation.size() as isize);
1080+
10791081
if let Some(label) = desc.label {
1080-
resource.set_name(label)?;
1082+
// If naming fails, free the resource (which also subtracts the counter
1083+
// added above) so the allocation is not leaked.
1084+
if let Err(e) = resource.set_name(label) {
1085+
self.free_resource(resource, allocation);
1086+
return Err(e);
1087+
}
10811088
}
10821089

1083-
self.counters.buffer_memory.add(allocation.size() as isize);
1084-
10851090
Ok((resource, allocation))
10861091
}
10871092

@@ -1110,12 +1115,17 @@ impl DeviceAllocationContext<'_> {
11101115
name,
11111116
)?;
11121117

1118+
self.counters.texture_memory.add(allocation.size() as isize);
1119+
11131120
if let Some(label) = desc.label {
1114-
resource.set_name(label)?;
1121+
// If naming fails, free the resource (which also subtracts the counter
1122+
// added above) so the allocation is not leaked.
1123+
if let Err(e) = resource.set_name(label) {
1124+
self.free_resource(resource, allocation);
1125+
return Err(e);
1126+
}
11151127
}
11161128

1117-
self.counters.texture_memory.add(allocation.size() as isize);
1118-
11191129
Ok((resource, allocation))
11201130
}
11211131

@@ -1144,14 +1154,19 @@ impl DeviceAllocationContext<'_> {
11441154
name,
11451155
)?;
11461156

1147-
if let Some(label) = desc.label {
1148-
resource.set_name(label)?;
1149-
}
1150-
11511157
self.counters
11521158
.acceleration_structure_memory
11531159
.add(allocation.size() as isize);
11541160

1161+
if let Some(label) = desc.label {
1162+
// If naming fails, free the resource (which also subtracts the counter
1163+
// added above) so the allocation is not leaked.
1164+
if let Err(e) = resource.set_name(label) {
1165+
self.free_resource(resource, allocation);
1166+
return Err(e);
1167+
}
1168+
}
1169+
11551170
Ok((resource, allocation))
11561171
}
11571172

wgpu-hal/src/vulkan/device.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,20 +1173,21 @@ impl crate::Device for super::Device {
11731173
unsafe { self.shared.raw.destroy_image(image.raw, None) };
11741174
})?;
11751175

1176-
self.counters.texture_memory.add(allocation.size() as isize);
1177-
11781176
if let Err(e) = unsafe {
11791177
self.shared
11801178
.raw
11811179
.bind_image_memory(image.raw, allocation.memory(), allocation.offset())
11821180
} {
11831181
// Bind failed: free the allocation back to the allocator before destroying the
1184-
// image, so the pooled slot / dedicated memory is not leaked.
1182+
// image, so the pooled slot / dedicated memory is not leaked. The counter is
1183+
// only added after a successful bind, so nothing needs to be subtracted here.
11851184
self.mem_allocator.lock().free(&self.shared, allocation);
11861185
unsafe { self.shared.raw.destroy_image(image.raw, None) };
11871186
return Err(super::map_host_device_oom_err(e));
11881187
}
11891188

1189+
self.counters.texture_memory.add(allocation.size() as isize);
1190+
11901191
Ok(unsafe {
11911192
self.texture_from_raw(
11921193
image.raw,
@@ -2836,13 +2837,20 @@ impl crate::Device for super::Device {
28362837
.size(desc.size)
28372838
.ty(conv::map_acceleration_structure_format(desc.format));
28382839

2839-
let raw_acceleration_structure = ray_tracing_functions
2840+
let raw_acceleration_structure = match ray_tracing_functions
28402841
.acceleration_structure
28412842
.create_acceleration_structure(&vk_info, None)
2842-
.map_err(super::map_host_oom_and_ioca_err)
2843-
.inspect_err(|_| {
2843+
{
2844+
Ok(raw) => raw,
2845+
Err(e) => {
2846+
// Creation failed: free the allocation back to the allocator before
2847+
// destroying the buffer, so the pooled slot / dedicated memory is not
2848+
// leaked.
2849+
self.mem_allocator.lock().free(&self.shared, allocation);
28442850
self.shared.raw.destroy_buffer(raw_buffer, None);
2845-
})?;
2851+
return Err(super::map_host_oom_and_ioca_err(e));
2852+
}
2853+
};
28462854

28472855
if let Some(label) = desc.label {
28482856
self.shared
@@ -2854,18 +2862,20 @@ impl crate::Device for super::Device {
28542862
.query_type(vk::QueryType::ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR)
28552863
.query_count(1);
28562864

2857-
let raw = self
2858-
.shared
2859-
.raw
2860-
.create_query_pool(&vk_info, None)
2861-
.map_err(super::map_host_device_oom_err)
2862-
.inspect_err(|_| {
2865+
match self.shared.raw.create_query_pool(&vk_info, None) {
2866+
Ok(raw) => Some(raw),
2867+
Err(e) => {
2868+
// Creation failed: free the allocation back to the allocator before
2869+
// destroying the acceleration structure and buffer, so the pooled
2870+
// slot / dedicated memory is not leaked.
2871+
self.mem_allocator.lock().free(&self.shared, allocation);
28632872
ray_tracing_functions
28642873
.acceleration_structure
28652874
.destroy_acceleration_structure(raw_acceleration_structure, None);
28662875
self.shared.raw.destroy_buffer(raw_buffer, None);
2867-
})?;
2868-
Some(raw)
2876+
return Err(super::map_host_device_oom_err(e));
2877+
}
2878+
}
28692879
} else {
28702880
None
28712881
};

0 commit comments

Comments
 (0)