@@ -774,7 +774,11 @@ impl CommandSink {
774
774
CommandSink :: Deferred { ref mut passes, ref mut is_encoding } => {
775
775
* is_encoding = keep_open;
776
776
passes. push ( soft:: Pass :: Render {
777
- desc : descriptor. to_owned ( ) ,
777
+ //Note: the original descriptor belongs to the framebuffer,
778
+ // and will me mutated afterwards.
779
+ desc : unsafe {
780
+ msg_send ! [ descriptor, copy]
781
+ } ,
778
782
commands : init_commands. map ( soft:: RenderCommand :: own) . collect ( ) ,
779
783
} ) ;
780
784
}
@@ -1606,6 +1610,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
1606
1610
1607
1611
for subresource_range in subresource_ranges {
1608
1612
let sub = subresource_range. borrow ( ) ;
1613
+ let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
1609
1614
1610
1615
let num_layers = ( sub. layers . end - sub. layers . start ) as u64 ;
1611
1616
let layers = if CLEAR_IMAGE_ARRAY {
@@ -1633,9 +1638,54 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
1633
1638
& * image. raw
1634
1639
} ;
1635
1640
1641
+ let clear_color_attachment = sub. aspects . contains ( Aspects :: COLOR ) ;
1642
+ if image. format_desc . aspects . contains ( Aspects :: COLOR ) {
1643
+ let attachment = descriptor
1644
+ . color_attachments ( )
1645
+ . object_at ( 0 )
1646
+ . unwrap ( ) ;
1647
+ attachment. set_texture ( Some ( texture) ) ;
1648
+ attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1649
+ if clear_color_attachment {
1650
+ attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1651
+ attachment. set_clear_color ( clear_color. clone ( ) ) ;
1652
+ } else {
1653
+ attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1654
+ }
1655
+ }
1656
+
1657
+ let clear_depth_attachment = sub. aspects . contains ( Aspects :: DEPTH ) ;
1658
+ if image. format_desc . aspects . contains ( Aspects :: DEPTH ) {
1659
+ let attachment = descriptor
1660
+ . depth_attachment ( )
1661
+ . unwrap ( ) ;
1662
+ attachment. set_texture ( Some ( texture) ) ;
1663
+ attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1664
+ if clear_depth_attachment {
1665
+ attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1666
+ attachment. set_clear_depth ( depth_stencil. depth as _ ) ;
1667
+ } else {
1668
+ attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1669
+ }
1670
+ }
1671
+
1672
+ let clear_stencil_attachment = sub. aspects . contains ( Aspects :: STENCIL ) ;
1673
+ if image. format_desc . aspects . contains ( Aspects :: STENCIL ) {
1674
+ let attachment = descriptor
1675
+ . stencil_attachment ( )
1676
+ . unwrap ( ) ;
1677
+ attachment. set_texture ( Some ( texture) ) ;
1678
+ attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1679
+ if clear_stencil_attachment {
1680
+ attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1681
+ attachment. set_clear_stencil ( depth_stencil. stencil ) ;
1682
+ } else {
1683
+ attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1684
+ }
1685
+ }
1686
+
1636
1687
for layer in layers {
1637
1688
for level in sub. levels . clone ( ) {
1638
- let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
1639
1689
if image. extent . depth > 1 {
1640
1690
assert_eq ! ( sub. layers. end, 1 ) ;
1641
1691
let depth = image. extent . at_level ( level) . depth as u64 ;
@@ -1644,62 +1694,33 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
1644
1694
descriptor. set_render_target_array_length ( num_layers) ;
1645
1695
} ;
1646
1696
1647
- let clear_color_attachment = sub. aspects . contains ( Aspects :: COLOR ) ;
1648
- if clear_color_attachment || image. format_desc . aspects . contains ( Aspects :: COLOR ) {
1697
+ if clear_color_attachment {
1649
1698
let attachment = descriptor
1650
1699
. color_attachments ( )
1651
1700
. object_at ( 0 )
1652
1701
. unwrap ( ) ;
1653
- attachment. set_texture ( Some ( texture) ) ;
1654
1702
attachment. set_level ( level as _ ) ;
1655
- attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1656
1703
if !CLEAR_IMAGE_ARRAY {
1657
1704
attachment. set_slice ( layer as _ ) ;
1658
1705
}
1659
- if clear_color_attachment {
1660
- attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1661
- attachment. set_clear_color ( clear_color. clone ( ) ) ;
1662
- } else {
1663
- attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1664
- }
1665
1706
}
1666
-
1667
- let clear_depth_attachment = sub. aspects . contains ( Aspects :: DEPTH ) ;
1668
- if clear_depth_attachment || image. format_desc . aspects . contains ( Aspects :: DEPTH ) {
1707
+ if clear_depth_attachment {
1669
1708
let attachment = descriptor
1670
1709
. depth_attachment ( )
1671
1710
. unwrap ( ) ;
1672
- attachment. set_texture ( Some ( texture) ) ;
1673
1711
attachment. set_level ( level as _ ) ;
1674
- attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1675
1712
if !CLEAR_IMAGE_ARRAY {
1676
1713
attachment. set_slice ( layer as _ ) ;
1677
1714
}
1678
- if clear_depth_attachment {
1679
- attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1680
- attachment. set_clear_depth ( depth_stencil. depth as _ ) ;
1681
- } else {
1682
- attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1683
- }
1684
1715
}
1685
-
1686
- let clear_stencil_attachment = sub. aspects . contains ( Aspects :: STENCIL ) ;
1687
- if clear_stencil_attachment || image. format_desc . aspects . contains ( Aspects :: STENCIL ) {
1716
+ if clear_stencil_attachment {
1688
1717
let attachment = descriptor
1689
1718
. stencil_attachment ( )
1690
1719
. unwrap ( ) ;
1691
- attachment. set_texture ( Some ( texture) ) ;
1692
1720
attachment. set_level ( level as _ ) ;
1693
- attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1694
1721
if !CLEAR_IMAGE_ARRAY {
1695
1722
attachment. set_slice ( layer as _ ) ;
1696
1723
}
1697
- if clear_stencil_attachment {
1698
- attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1699
- attachment. set_clear_stencil ( depth_stencil. stencil ) ;
1700
- } else {
1701
- attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1702
- }
1703
1724
}
1704
1725
1705
1726
sink. as_mut ( )
@@ -2019,6 +2040,27 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2019
2040
}
2020
2041
}
2021
2042
2043
+ let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
2044
+ if src. format_desc . aspects . contains ( Aspects :: COLOR ) {
2045
+ descriptor
2046
+ . color_attachments ( )
2047
+ . object_at ( 0 )
2048
+ . unwrap ( )
2049
+ . set_texture ( Some ( & dst. raw ) ) ;
2050
+ }
2051
+ if src. format_desc . aspects . contains ( Aspects :: DEPTH ) {
2052
+ descriptor
2053
+ . depth_attachment ( )
2054
+ . unwrap ( )
2055
+ . set_texture ( Some ( & dst. raw ) ) ;
2056
+ }
2057
+ if src. format_desc . aspects . contains ( Aspects :: STENCIL ) {
2058
+ descriptor
2059
+ . stencil_attachment ( )
2060
+ . unwrap ( )
2061
+ . set_texture ( Some ( & dst. raw ) ) ;
2062
+ }
2063
+
2022
2064
let mut inner = self . inner . borrow_mut ( ) ;
2023
2065
// Note: we don't bother to restore any render states here, since we are currently
2024
2066
// outside of a render pass, and the state will be reset automatically once
@@ -2062,7 +2104,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2062
2104
} ;
2063
2105
2064
2106
for ( ( aspects, level) , list) in vertices. drain ( ) {
2065
- let ext = & dst. extent ;
2107
+ let ext = dst. extent . at_level ( level ) ;
2066
2108
2067
2109
let extra = [
2068
2110
//Note: flipping Y coordinate of the destination here
@@ -2097,29 +2139,25 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2097
2139
} ,
2098
2140
] ;
2099
2141
2100
- let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
2101
2142
descriptor. set_render_target_array_length ( ext. depth as _ ) ;
2102
2143
if aspects. contains ( Aspects :: COLOR ) {
2103
- let attachment = descriptor
2144
+ descriptor
2104
2145
. color_attachments ( )
2105
2146
. object_at ( 0 )
2106
- . unwrap ( ) ;
2107
- attachment. set_texture ( Some ( & dst. raw ) ) ;
2108
- attachment. set_level ( level as _ ) ;
2147
+ . unwrap ( )
2148
+ . set_level ( level as _ ) ;
2109
2149
}
2110
2150
if aspects. contains ( Aspects :: DEPTH ) {
2111
- let attachment = descriptor
2151
+ descriptor
2112
2152
. depth_attachment ( )
2113
- . unwrap ( ) ;
2114
- attachment. set_texture ( Some ( & dst. raw ) ) ;
2115
- attachment. set_level ( level as _ ) ;
2153
+ . unwrap ( )
2154
+ . set_level ( level as _ ) ;
2116
2155
}
2117
2156
if aspects. contains ( Aspects :: STENCIL ) {
2118
- let attachment = descriptor
2157
+ descriptor
2119
2158
. stencil_attachment ( )
2120
- . unwrap ( ) ;
2121
- attachment. set_texture ( Some ( & dst. raw ) ) ;
2122
- attachment. set_level ( level as _ ) ;
2159
+ . unwrap ( )
2160
+ . set_level ( level as _ ) ;
2123
2161
}
2124
2162
2125
2163
let commands = prelude
@@ -2128,7 +2166,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2128
2166
. chain ( & extra)
2129
2167
. cloned ( ) ;
2130
2168
2131
- inner. sink ( ) . begin_render_pass ( false , descriptor, commands) ;
2169
+ inner. sink ( ) . begin_render_pass ( false , & descriptor, commands) ;
2132
2170
}
2133
2171
}
2134
2172
@@ -2292,11 +2330,13 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2292
2330
T : IntoIterator ,
2293
2331
T :: Item : Borrow < com:: ClearValueRaw > ,
2294
2332
{
2295
- let _ap = AutoreleasePool :: new ( ) ;
2296
2333
// FIXME: subpasses
2297
- let descriptor: metal:: RenderPassDescriptor = unsafe {
2298
- msg_send ! [ framebuffer. descriptor, copy]
2299
- } ;
2334
+ let _ap = AutoreleasePool :: new ( ) ;
2335
+
2336
+ // we are going to modify the RP descriptor here, so
2337
+ // locking to avoid data races.
2338
+ let descriptor = framebuffer. descriptor . lock ( ) . unwrap ( ) ;
2339
+
2300
2340
let mut num_colors = 0 ;
2301
2341
let mut full_aspects = Aspects :: empty ( ) ;
2302
2342
let mut inner = self . inner . borrow_mut ( ) ;
@@ -2355,7 +2395,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2355
2395
let init_commands = self . state . make_render_commands ( full_aspects) ;
2356
2396
inner
2357
2397
. sink ( )
2358
- . begin_render_pass ( true , & descriptor, init_commands) ;
2398
+ . begin_render_pass ( true , & * descriptor, init_commands) ;
2359
2399
}
2360
2400
2361
2401
fn next_subpass ( & mut self , _contents : com:: SubpassContents ) {
0 commit comments