Skip to content

Commit 0fa3c03

Browse files
committed
[mtl] don't reuse deferred render pass descriptors
1 parent 90ca04c commit 0fa3c03

File tree

1 file changed

+86
-118
lines changed

1 file changed

+86
-118
lines changed

src/backend/metal/src/command.rs

Lines changed: 86 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const WORD_SIZE: usize = 4;
3737
const WORD_ALIGNMENT: u64 = WORD_SIZE as _;
3838
/// Enable an optimization to have multi-layered render passed
3939
/// with clear operations set up to implement our `clear_image`
40-
/// Note: currently doesn't work, needs a repro case for Apple
40+
/// Note: multi-target clears don't appear to work properly on Intel GPUs
4141
const CLEAR_IMAGE_ARRAY: bool = false && cfg!(target_os = "macos");
4242
/// Number of frames to average when reporting the performance counters.
4343
const COUNTERS_REPORT_WINDOW: usize = 0;
@@ -867,30 +867,30 @@ impl CommandSink {
867867
}
868868

869869
/// Switch the active encoder to render by starting a render pass.
870-
fn switch_render<'a>(
871-
&'a mut self,
872-
descriptor: &'a metal::RenderPassDescriptorRef,
873-
) -> PreRender<'a> {
870+
fn switch_render(
871+
&mut self,
872+
descriptor: metal::RenderPassDescriptor,
873+
) -> PreRender {
874874
//assert!(AutoReleasePool::is_active());
875875
self.stop_encoding();
876876

877877
match *self {
878878
CommandSink::Immediate { ref cmd_buffer, ref mut encoder_state, ref mut num_passes, .. } => {
879879
*num_passes += 1;
880-
let encoder = cmd_buffer.new_render_command_encoder(descriptor);
880+
let encoder = cmd_buffer.new_render_command_encoder(&descriptor);
881881
*encoder_state = EncoderState::Render(encoder.to_owned());
882882
PreRender::Immediate(encoder)
883883
}
884884
CommandSink::Deferred { ref mut is_encoding, ref mut journal } => {
885-
let pass = soft::Pass::Render(descriptor.to_owned());
885+
let pass = soft::Pass::Render(descriptor);
886886
*is_encoding = true;
887887
journal.passes.push((pass, journal.render_commands.len() .. 0));
888888
PreRender::Deferred(&mut journal.resources, &mut journal.render_commands)
889889
}
890890
#[cfg(feature = "dispatch")]
891891
CommandSink::Remote { ref mut pass, ref capacity, .. } => {
892892
let mut list = Vec::with_capacity(capacity.render);
893-
*pass = Some(EncodePass::Render(list, descriptor.to_owned()));
893+
*pass = Some(EncodePass::Render(list, descriptor));
894894
match *pass {
895895
Some(EncodePass::Render(ref mut list, _)) => PreRender::Deferred(list),
896896
_ => unreachable!()
@@ -902,7 +902,7 @@ impl CommandSink {
902902
fn quick_render<'a, I>(
903903
&mut self,
904904
label: &str,
905-
descriptor: &'a metal::RenderPassDescriptorRef,
905+
descriptor: metal::RenderPassDescriptor,
906906
commands: I,
907907
)
908908
where
@@ -2125,8 +2125,6 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
21252125
let raw = image.like.as_texture();
21262126
for subresource_range in subresource_ranges {
21272127
let sub = subresource_range.borrow();
2128-
let descriptor = metal::RenderPassDescriptor::new();
2129-
21302128
let num_layers = (sub.layers.end - sub.layers.start) as u64;
21312129
let layers = if CLEAR_IMAGE_ARRAY {
21322130
0 .. 1
@@ -2153,66 +2151,9 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
21532151
raw
21542152
};
21552153

2156-
let color_attachment = if image.format_desc.aspects.contains(Aspects::COLOR) {
2157-
let attachment = descriptor
2158-
.color_attachments()
2159-
.object_at(0)
2160-
.unwrap();
2161-
attachment.set_texture(Some(texture));
2162-
attachment.set_store_action(metal::MTLStoreAction::Store);
2163-
if sub.aspects.contains(Aspects::COLOR) {
2164-
attachment.set_load_action(metal::MTLLoadAction::Clear);
2165-
attachment.set_clear_color(clear_color.clone());
2166-
Some(attachment)
2167-
} else {
2168-
attachment.set_load_action(metal::MTLLoadAction::Load);
2169-
None
2170-
}
2171-
} else {
2172-
assert!(!sub.aspects.contains(Aspects::COLOR));
2173-
None
2174-
};
2175-
2176-
let depth_attachment = if image.format_desc.aspects.contains(Aspects::DEPTH) {
2177-
let attachment = descriptor
2178-
.depth_attachment()
2179-
.unwrap();
2180-
attachment.set_texture(Some(texture));
2181-
attachment.set_store_action(metal::MTLStoreAction::Store);
2182-
if sub.aspects.contains(Aspects::DEPTH) {
2183-
attachment.set_load_action(metal::MTLLoadAction::Clear);
2184-
attachment.set_clear_depth(depth_stencil.depth as _);
2185-
Some(attachment)
2186-
} else {
2187-
attachment.set_load_action(metal::MTLLoadAction::Load);
2188-
None
2189-
}
2190-
} else {
2191-
assert!(!sub.aspects.contains(Aspects::DEPTH));
2192-
None
2193-
};
2194-
2195-
let stencil_attachment = if image.format_desc.aspects.contains(Aspects::STENCIL) {
2196-
let attachment = descriptor
2197-
.stencil_attachment()
2198-
.unwrap();
2199-
attachment.set_texture(Some(texture));
2200-
attachment.set_store_action(metal::MTLStoreAction::Store);
2201-
if sub.aspects.contains(Aspects::STENCIL) {
2202-
attachment.set_load_action(metal::MTLLoadAction::Clear);
2203-
attachment.set_clear_stencil(depth_stencil.stencil);
2204-
Some(attachment)
2205-
} else {
2206-
attachment.set_load_action(metal::MTLLoadAction::Load);
2207-
None
2208-
}
2209-
} else {
2210-
assert!(!sub.aspects.contains(Aspects::STENCIL));
2211-
None
2212-
};
2213-
22142154
for layer in layers {
22152155
for level in sub.levels.clone() {
2156+
let descriptor = metal::RenderPassDescriptor::new().to_owned();
22162157
if base_extent.depth > 1 {
22172158
assert_eq!(sub.layers.end, 1);
22182159
let depth = base_extent.at_level(level).depth as u64;
@@ -2221,24 +2162,66 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
22212162
descriptor.set_render_target_array_length(num_layers);
22222163
};
22232164

2224-
if let Some(attachment) = color_attachment {
2165+
if image.format_desc.aspects.contains(Aspects::COLOR) {
2166+
let attachment = descriptor
2167+
.color_attachments()
2168+
.object_at(0)
2169+
.unwrap();
2170+
attachment.set_texture(Some(texture));
22252171
attachment.set_level(level as _);
22262172
if !CLEAR_IMAGE_ARRAY {
22272173
attachment.set_slice(layer as _);
22282174
}
2229-
}
2230-
if let Some(attachment) = depth_attachment {
2175+
attachment.set_store_action(metal::MTLStoreAction::Store);
2176+
if sub.aspects.contains(Aspects::COLOR) {
2177+
attachment.set_load_action(metal::MTLLoadAction::Clear);
2178+
attachment.set_clear_color(clear_color.clone());
2179+
} else {
2180+
attachment.set_load_action(metal::MTLLoadAction::Load);
2181+
}
2182+
} else {
2183+
assert!(!sub.aspects.contains(Aspects::COLOR));
2184+
};
2185+
2186+
if image.format_desc.aspects.contains(Aspects::DEPTH) {
2187+
let attachment = descriptor
2188+
.depth_attachment()
2189+
.unwrap();
2190+
attachment.set_texture(Some(texture));
22312191
attachment.set_level(level as _);
22322192
if !CLEAR_IMAGE_ARRAY {
22332193
attachment.set_slice(layer as _);
22342194
}
2235-
}
2236-
if let Some(attachment) = stencil_attachment {
2195+
attachment.set_store_action(metal::MTLStoreAction::Store);
2196+
if sub.aspects.contains(Aspects::DEPTH) {
2197+
attachment.set_load_action(metal::MTLLoadAction::Clear);
2198+
attachment.set_clear_depth(depth_stencil.depth as _);
2199+
} else {
2200+
attachment.set_load_action(metal::MTLLoadAction::Load);
2201+
}
2202+
} else {
2203+
assert!(!sub.aspects.contains(Aspects::DEPTH));
2204+
};
2205+
2206+
if image.format_desc.aspects.contains(Aspects::STENCIL) {
2207+
let attachment = descriptor
2208+
.stencil_attachment()
2209+
.unwrap();
2210+
attachment.set_texture(Some(texture));
22372211
attachment.set_level(level as _);
22382212
if !CLEAR_IMAGE_ARRAY {
22392213
attachment.set_slice(layer as _);
22402214
}
2241-
}
2215+
attachment.set_store_action(metal::MTLStoreAction::Store);
2216+
if sub.aspects.contains(Aspects::STENCIL) {
2217+
attachment.set_load_action(metal::MTLLoadAction::Clear);
2218+
attachment.set_clear_stencil(depth_stencil.stencil);
2219+
} else {
2220+
attachment.set_load_action(metal::MTLLoadAction::Load);
2221+
}
2222+
} else {
2223+
assert!(!sub.aspects.contains(Aspects::STENCIL));
2224+
};
22422225

22432226
sink.as_mut()
22442227
.unwrap()
@@ -2607,32 +2590,38 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
26072590
};
26082591

26092592
autoreleasepool(|| {
2610-
let descriptor = metal::RenderPassDescriptor::new();
26112593
let dst_new = match dst_cubish {
26122594
Some(ref tex) => tex.as_ref(),
26132595
None => dst.like.as_texture(),
26142596
};
2615-
if src.format_desc.aspects.contains(Aspects::COLOR) {
2616-
descriptor
2617-
.color_attachments()
2618-
.object_at(0)
2619-
.unwrap()
2620-
.set_texture(Some(dst_new));
2621-
}
2622-
if src.format_desc.aspects.contains(Aspects::DEPTH) {
2623-
descriptor
2624-
.depth_attachment()
2625-
.unwrap()
2626-
.set_texture(Some(dst_new));
2627-
}
2628-
if src.format_desc.aspects.contains(Aspects::STENCIL) {
2629-
descriptor
2630-
.stencil_attachment()
2631-
.unwrap()
2632-
.set_texture(Some(dst_new));
2633-
}
26342597

26352598
for ((aspects, level), list) in vertices.drain() {
2599+
let descriptor = metal::RenderPassDescriptor::new().to_owned();
2600+
descriptor.set_render_target_array_length(dst_layers as _);
2601+
2602+
if aspects.contains(Aspects::COLOR) {
2603+
let att = descriptor
2604+
.color_attachments()
2605+
.object_at(0)
2606+
.unwrap();
2607+
att.set_texture(Some(dst_new));
2608+
att.set_level(level as _);
2609+
}
2610+
if aspects.contains(Aspects::DEPTH) {
2611+
let att = descriptor
2612+
.depth_attachment()
2613+
.unwrap();
2614+
att.set_texture(Some(dst_new));
2615+
att.set_level(level as _);
2616+
}
2617+
if aspects.contains(Aspects::STENCIL) {
2618+
let att = descriptor
2619+
.stencil_attachment()
2620+
.unwrap();
2621+
att.set_texture(Some(dst_new));
2622+
att.set_level(level as _);
2623+
}
2624+
26362625
let ext = dst.kind.extent().at_level(level);
26372626
//Note: flipping Y coordinate of the destination here
26382627
let rect = pso::Rect {
@@ -2667,27 +2656,6 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
26672656
},
26682657
];
26692658

2670-
descriptor.set_render_target_array_length(dst_layers as _);
2671-
if aspects.contains(Aspects::COLOR) {
2672-
descriptor
2673-
.color_attachments()
2674-
.object_at(0)
2675-
.unwrap()
2676-
.set_level(level as _);
2677-
}
2678-
if aspects.contains(Aspects::DEPTH) {
2679-
descriptor
2680-
.depth_attachment()
2681-
.unwrap()
2682-
.set_level(level as _);
2683-
}
2684-
if aspects.contains(Aspects::STENCIL) {
2685-
descriptor
2686-
.stencil_attachment()
2687-
.unwrap()
2688-
.set_level(level as _);
2689-
}
2690-
26912659
let commands = prelude
26922660
.iter()
26932661
.chain(&com_ds)
@@ -2697,7 +2665,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
26972665
sink
26982666
.as_mut()
26992667
.unwrap()
2700-
.quick_render("blit_image", &descriptor, commands);
2668+
.quick_render("blit_image", descriptor, commands);
27012669
}
27022670
});
27032671

@@ -3004,7 +2972,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
30042972
self.inner
30052973
.borrow_mut()
30062974
.sink()
3007-
.switch_render(&sin.descriptor)
2975+
.switch_render(sin.descriptor)
30082976
.issue_many(init_commands);
30092977
}
30102978

0 commit comments

Comments
 (0)