Skip to content

Commit a59a627

Browse files
authored
Fix memory leak on macOS (#2092)
* Fix memory RenderCommandEncoder, BlitCommandEncoder, label leak on macOS * Don't wrap autoreleasepool when blit command encoder is already active * Revert wrap set_label, instead focus on gfx-rs/metal-rs#218
1 parent 417de10 commit a59a627

1 file changed

Lines changed: 68 additions & 64 deletions

File tree

‎wgpu-hal/src/metal/command.rs‎

Lines changed: 68 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ impl super::CommandEncoder {
2424
fn enter_blit(&mut self) -> &mtl::BlitCommandEncoderRef {
2525
if self.state.blit.is_none() {
2626
debug_assert!(self.state.render.is_none() && self.state.compute.is_none());
27-
let cmd_buf = self.raw_cmd_buf.as_ref().unwrap();
28-
self.state.blit = Some(cmd_buf.new_blit_command_encoder().to_owned());
27+
objc::rc::autoreleasepool(|| {
28+
let cmd_buf = self.raw_cmd_buf.as_ref().unwrap();
29+
self.state.blit = Some(cmd_buf.new_blit_command_encoder().to_owned());
30+
});
2931
}
3032
self.state.blit.as_ref().unwrap()
3133
}
@@ -321,80 +323,82 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
321323
self.begin_pass();
322324
self.state.index = None;
323325

324-
let descriptor = mtl::RenderPassDescriptor::new();
325-
//TODO: set visibility results buffer
326+
objc::rc::autoreleasepool(|| {
327+
let descriptor = mtl::RenderPassDescriptor::new();
328+
//TODO: set visibility results buffer
326329

327-
for (i, at) in desc.color_attachments.iter().enumerate() {
328-
let at_descriptor = descriptor.color_attachments().object_at(i as u64).unwrap();
329-
at_descriptor.set_texture(Some(&at.target.view.raw));
330-
if let Some(ref resolve) = at.resolve_target {
331-
//Note: the selection of levels and slices is already handled by `TextureView`
332-
at_descriptor.set_resolve_texture(Some(&resolve.view.raw));
333-
}
334-
let load_action = if at.ops.contains(crate::AttachmentOps::LOAD) {
335-
mtl::MTLLoadAction::Load
336-
} else {
337-
at_descriptor.set_clear_color(conv::map_clear_color(&at.clear_value));
338-
mtl::MTLLoadAction::Clear
339-
};
340-
let store_action = conv::map_store_action(
341-
at.ops.contains(crate::AttachmentOps::STORE),
342-
at.resolve_target.is_some(),
343-
);
344-
at_descriptor.set_load_action(load_action);
345-
at_descriptor.set_store_action(store_action);
346-
}
347-
348-
if let Some(ref at) = desc.depth_stencil_attachment {
349-
if at.target.view.aspects.contains(crate::FormatAspects::DEPTH) {
350-
let at_descriptor = descriptor.depth_attachment().unwrap();
330+
for (i, at) in desc.color_attachments.iter().enumerate() {
331+
let at_descriptor = descriptor.color_attachments().object_at(i as u64).unwrap();
351332
at_descriptor.set_texture(Some(&at.target.view.raw));
352-
353-
let load_action = if at.depth_ops.contains(crate::AttachmentOps::LOAD) {
333+
if let Some(ref resolve) = at.resolve_target {
334+
//Note: the selection of levels and slices is already handled by `TextureView`
335+
at_descriptor.set_resolve_texture(Some(&resolve.view.raw));
336+
}
337+
let load_action = if at.ops.contains(crate::AttachmentOps::LOAD) {
354338
mtl::MTLLoadAction::Load
355339
} else {
356-
at_descriptor.set_clear_depth(at.clear_value.0 as f64);
340+
at_descriptor.set_clear_color(conv::map_clear_color(&at.clear_value));
357341
mtl::MTLLoadAction::Clear
358342
};
359-
let store_action = if at.depth_ops.contains(crate::AttachmentOps::STORE) {
360-
mtl::MTLStoreAction::Store
361-
} else {
362-
mtl::MTLStoreAction::DontCare
363-
};
343+
let store_action = conv::map_store_action(
344+
at.ops.contains(crate::AttachmentOps::STORE),
345+
at.resolve_target.is_some(),
346+
);
364347
at_descriptor.set_load_action(load_action);
365348
at_descriptor.set_store_action(store_action);
366349
}
367-
if at
368-
.target
369-
.view
370-
.aspects
371-
.contains(crate::FormatAspects::STENCIL)
372-
{
373-
let at_descriptor = descriptor.stencil_attachment().unwrap();
374-
at_descriptor.set_texture(Some(&at.target.view.raw));
375350

376-
let load_action = if at.stencil_ops.contains(crate::AttachmentOps::LOAD) {
377-
mtl::MTLLoadAction::Load
378-
} else {
379-
at_descriptor.set_clear_stencil(at.clear_value.1);
380-
mtl::MTLLoadAction::Clear
381-
};
382-
let store_action = if at.stencil_ops.contains(crate::AttachmentOps::STORE) {
383-
mtl::MTLStoreAction::Store
384-
} else {
385-
mtl::MTLStoreAction::DontCare
386-
};
387-
at_descriptor.set_load_action(load_action);
388-
at_descriptor.set_store_action(store_action);
351+
if let Some(ref at) = desc.depth_stencil_attachment {
352+
if at.target.view.aspects.contains(crate::FormatAspects::DEPTH) {
353+
let at_descriptor = descriptor.depth_attachment().unwrap();
354+
at_descriptor.set_texture(Some(&at.target.view.raw));
355+
356+
let load_action = if at.depth_ops.contains(crate::AttachmentOps::LOAD) {
357+
mtl::MTLLoadAction::Load
358+
} else {
359+
at_descriptor.set_clear_depth(at.clear_value.0 as f64);
360+
mtl::MTLLoadAction::Clear
361+
};
362+
let store_action = if at.depth_ops.contains(crate::AttachmentOps::STORE) {
363+
mtl::MTLStoreAction::Store
364+
} else {
365+
mtl::MTLStoreAction::DontCare
366+
};
367+
at_descriptor.set_load_action(load_action);
368+
at_descriptor.set_store_action(store_action);
369+
}
370+
if at
371+
.target
372+
.view
373+
.aspects
374+
.contains(crate::FormatAspects::STENCIL)
375+
{
376+
let at_descriptor = descriptor.stencil_attachment().unwrap();
377+
at_descriptor.set_texture(Some(&at.target.view.raw));
378+
379+
let load_action = if at.stencil_ops.contains(crate::AttachmentOps::LOAD) {
380+
mtl::MTLLoadAction::Load
381+
} else {
382+
at_descriptor.set_clear_stencil(at.clear_value.1);
383+
mtl::MTLLoadAction::Clear
384+
};
385+
let store_action = if at.stencil_ops.contains(crate::AttachmentOps::STORE) {
386+
mtl::MTLStoreAction::Store
387+
} else {
388+
mtl::MTLStoreAction::DontCare
389+
};
390+
at_descriptor.set_load_action(load_action);
391+
at_descriptor.set_store_action(store_action);
392+
}
389393
}
390-
}
391394

392-
let raw = self.raw_cmd_buf.as_ref().unwrap();
393-
let encoder = raw.new_render_command_encoder(descriptor);
394-
if let Some(label) = desc.label {
395-
encoder.set_label(label);
396-
}
397-
self.state.render = Some(encoder.to_owned());
395+
let raw = self.raw_cmd_buf.as_ref().unwrap();
396+
let encoder = raw.new_render_command_encoder(descriptor);
397+
if let Some(label) = desc.label {
398+
encoder.set_label(label);
399+
}
400+
self.state.render = Some(encoder.to_owned());
401+
});
398402
}
399403

400404
unsafe fn end_render_pass(&mut self) {

0 commit comments

Comments
 (0)