@@ -777,7 +777,11 @@ impl CommandSink {
777
777
CommandSink :: Deferred { ref mut passes, ref mut is_encoding } => {
778
778
* is_encoding = keep_open;
779
779
passes. push ( soft:: Pass :: Render {
780
- desc : descriptor. to_owned ( ) ,
780
+ //Note: the original descriptor belongs to the framebuffer,
781
+ // and will me mutated afterwards.
782
+ desc : unsafe {
783
+ msg_send ! [ descriptor, copy]
784
+ } ,
781
785
commands : init_commands. map ( soft:: RenderCommand :: own) . collect ( ) ,
782
786
} ) ;
783
787
}
@@ -1596,6 +1600,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
1596
1600
1597
1601
for subresource_range in subresource_ranges {
1598
1602
let sub = subresource_range. borrow ( ) ;
1603
+ let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
1599
1604
1600
1605
let num_layers = ( sub. layers . end - sub. layers . start ) as u64 ;
1601
1606
let layers = if CLEAR_IMAGE_ARRAY {
@@ -1623,9 +1628,54 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
1623
1628
& * image. raw
1624
1629
} ;
1625
1630
1631
+ let clear_color_attachment = sub. aspects . contains ( Aspects :: COLOR ) ;
1632
+ if image. format_desc . aspects . contains ( Aspects :: COLOR ) {
1633
+ let attachment = descriptor
1634
+ . color_attachments ( )
1635
+ . object_at ( 0 )
1636
+ . unwrap ( ) ;
1637
+ attachment. set_texture ( Some ( texture) ) ;
1638
+ attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1639
+ if clear_color_attachment {
1640
+ attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1641
+ attachment. set_clear_color ( clear_color. clone ( ) ) ;
1642
+ } else {
1643
+ attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1644
+ }
1645
+ }
1646
+
1647
+ let clear_depth_attachment = sub. aspects . contains ( Aspects :: DEPTH ) ;
1648
+ if image. format_desc . aspects . contains ( Aspects :: DEPTH ) {
1649
+ let attachment = descriptor
1650
+ . depth_attachment ( )
1651
+ . unwrap ( ) ;
1652
+ attachment. set_texture ( Some ( texture) ) ;
1653
+ attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1654
+ if clear_depth_attachment {
1655
+ attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1656
+ attachment. set_clear_depth ( depth_stencil. depth as _ ) ;
1657
+ } else {
1658
+ attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1659
+ }
1660
+ }
1661
+
1662
+ let clear_stencil_attachment = sub. aspects . contains ( Aspects :: STENCIL ) ;
1663
+ if image. format_desc . aspects . contains ( Aspects :: STENCIL ) {
1664
+ let attachment = descriptor
1665
+ . stencil_attachment ( )
1666
+ . unwrap ( ) ;
1667
+ attachment. set_texture ( Some ( texture) ) ;
1668
+ attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1669
+ if clear_stencil_attachment {
1670
+ attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1671
+ attachment. set_clear_stencil ( depth_stencil. stencil ) ;
1672
+ } else {
1673
+ attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1674
+ }
1675
+ }
1676
+
1626
1677
for layer in layers {
1627
1678
for level in sub. levels . clone ( ) {
1628
- let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
1629
1679
if image. extent . depth > 1 {
1630
1680
assert_eq ! ( sub. layers. end, 1 ) ;
1631
1681
let depth = image. extent . at_level ( level) . depth as u64 ;
@@ -1634,62 +1684,33 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
1634
1684
descriptor. set_render_target_array_length ( num_layers) ;
1635
1685
} ;
1636
1686
1637
- let clear_color_attachment = sub. aspects . contains ( Aspects :: COLOR ) ;
1638
- if clear_color_attachment || image. format_desc . aspects . contains ( Aspects :: COLOR ) {
1687
+ if clear_color_attachment {
1639
1688
let attachment = descriptor
1640
1689
. color_attachments ( )
1641
1690
. object_at ( 0 )
1642
1691
. unwrap ( ) ;
1643
- attachment. set_texture ( Some ( texture) ) ;
1644
1692
attachment. set_level ( level as _ ) ;
1645
- attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1646
1693
if !CLEAR_IMAGE_ARRAY {
1647
1694
attachment. set_slice ( layer as _ ) ;
1648
1695
}
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
1696
}
1656
-
1657
- let clear_depth_attachment = sub. aspects . contains ( Aspects :: DEPTH ) ;
1658
- if clear_depth_attachment || image. format_desc . aspects . contains ( Aspects :: DEPTH ) {
1697
+ if clear_depth_attachment {
1659
1698
let attachment = descriptor
1660
1699
. depth_attachment ( )
1661
1700
. unwrap ( ) ;
1662
- attachment. set_texture ( Some ( texture) ) ;
1663
1701
attachment. set_level ( level as _ ) ;
1664
- attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1665
1702
if !CLEAR_IMAGE_ARRAY {
1666
1703
attachment. set_slice ( layer as _ ) ;
1667
1704
}
1668
- if clear_depth_attachment {
1669
- attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1670
- attachment. set_clear_depth ( depth_stencil. depth as _ ) ;
1671
- } else {
1672
- attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1673
- }
1674
1705
}
1675
-
1676
- let clear_stencil_attachment = sub. aspects . contains ( Aspects :: STENCIL ) ;
1677
- if clear_stencil_attachment || image. format_desc . aspects . contains ( Aspects :: STENCIL ) {
1706
+ if clear_stencil_attachment {
1678
1707
let attachment = descriptor
1679
1708
. stencil_attachment ( )
1680
1709
. unwrap ( ) ;
1681
- attachment. set_texture ( Some ( texture) ) ;
1682
1710
attachment. set_level ( level as _ ) ;
1683
- attachment. set_store_action ( metal:: MTLStoreAction :: Store ) ;
1684
1711
if !CLEAR_IMAGE_ARRAY {
1685
1712
attachment. set_slice ( layer as _ ) ;
1686
1713
}
1687
- if clear_stencil_attachment {
1688
- attachment. set_load_action ( metal:: MTLLoadAction :: Clear ) ;
1689
- attachment. set_clear_stencil ( depth_stencil. stencil ) ;
1690
- } else {
1691
- attachment. set_load_action ( metal:: MTLLoadAction :: Load ) ;
1692
- }
1693
1714
}
1694
1715
1695
1716
sink. as_mut ( )
@@ -2009,6 +2030,27 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2009
2030
}
2010
2031
}
2011
2032
2033
+ let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
2034
+ if src. format_desc . aspects . contains ( Aspects :: COLOR ) {
2035
+ descriptor
2036
+ . color_attachments ( )
2037
+ . object_at ( 0 )
2038
+ . unwrap ( )
2039
+ . set_texture ( Some ( & dst. raw ) ) ;
2040
+ }
2041
+ if src. format_desc . aspects . contains ( Aspects :: DEPTH ) {
2042
+ descriptor
2043
+ . depth_attachment ( )
2044
+ . unwrap ( )
2045
+ . set_texture ( Some ( & dst. raw ) ) ;
2046
+ }
2047
+ if src. format_desc . aspects . contains ( Aspects :: STENCIL ) {
2048
+ descriptor
2049
+ . stencil_attachment ( )
2050
+ . unwrap ( )
2051
+ . set_texture ( Some ( & dst. raw ) ) ;
2052
+ }
2053
+
2012
2054
let mut inner = self . inner . borrow_mut ( ) ;
2013
2055
// Note: we don't bother to restore any render states here, since we are currently
2014
2056
// outside of a render pass, and the state will be reset automatically once
@@ -2052,7 +2094,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2052
2094
} ;
2053
2095
2054
2096
for ( ( aspects, level) , list) in vertices. drain ( ) {
2055
- let ext = & dst. extent ;
2097
+ let ext = dst. extent . at_level ( level ) ;
2056
2098
2057
2099
let extra = [
2058
2100
//Note: flipping Y coordinate of the destination here
@@ -2087,29 +2129,25 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2087
2129
} ,
2088
2130
] ;
2089
2131
2090
- let descriptor = metal:: RenderPassDescriptor :: new ( ) ;
2091
2132
descriptor. set_render_target_array_length ( ext. depth as _ ) ;
2092
2133
if aspects. contains ( Aspects :: COLOR ) {
2093
- let attachment = descriptor
2134
+ descriptor
2094
2135
. color_attachments ( )
2095
2136
. object_at ( 0 )
2096
- . unwrap ( ) ;
2097
- attachment. set_texture ( Some ( & dst. raw ) ) ;
2098
- attachment. set_level ( level as _ ) ;
2137
+ . unwrap ( )
2138
+ . set_level ( level as _ ) ;
2099
2139
}
2100
2140
if aspects. contains ( Aspects :: DEPTH ) {
2101
- let attachment = descriptor
2141
+ descriptor
2102
2142
. depth_attachment ( )
2103
- . unwrap ( ) ;
2104
- attachment. set_texture ( Some ( & dst. raw ) ) ;
2105
- attachment. set_level ( level as _ ) ;
2143
+ . unwrap ( )
2144
+ . set_level ( level as _ ) ;
2106
2145
}
2107
2146
if aspects. contains ( Aspects :: STENCIL ) {
2108
- let attachment = descriptor
2147
+ descriptor
2109
2148
. stencil_attachment ( )
2110
- . unwrap ( ) ;
2111
- attachment. set_texture ( Some ( & dst. raw ) ) ;
2112
- attachment. set_level ( level as _ ) ;
2149
+ . unwrap ( )
2150
+ . set_level ( level as _ ) ;
2113
2151
}
2114
2152
2115
2153
let commands = prelude
@@ -2118,7 +2156,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2118
2156
. chain ( & extra)
2119
2157
. cloned ( ) ;
2120
2158
2121
- inner. sink ( ) . begin_render_pass ( false , descriptor, commands) ;
2159
+ inner. sink ( ) . begin_render_pass ( false , & descriptor, commands) ;
2122
2160
}
2123
2161
}
2124
2162
@@ -2283,11 +2321,13 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2283
2321
T : IntoIterator ,
2284
2322
T :: Item : Borrow < com:: ClearValueRaw > ,
2285
2323
{
2286
- let _ap = AutoreleasePool :: new ( ) ;
2287
2324
// FIXME: subpasses
2288
- let descriptor: metal:: RenderPassDescriptor = unsafe {
2289
- msg_send ! [ framebuffer. descriptor, copy]
2290
- } ;
2325
+ let _ap = AutoreleasePool :: new ( ) ;
2326
+
2327
+ // we are going to modify the RP descriptor here, so
2328
+ // locking to avoid data races.
2329
+ let descriptor = framebuffer. descriptor . lock ( ) . unwrap ( ) ;
2330
+
2291
2331
let mut num_colors = 0 ;
2292
2332
let mut full_aspects = Aspects :: empty ( ) ;
2293
2333
let mut inner = self . inner . borrow_mut ( ) ;
@@ -2346,7 +2386,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
2346
2386
let init_commands = self . state . make_render_commands ( full_aspects) ;
2347
2387
inner
2348
2388
. sink ( )
2349
- . begin_render_pass ( true , & descriptor, init_commands) ;
2389
+ . begin_render_pass ( true , & * descriptor, init_commands) ;
2350
2390
}
2351
2391
2352
2392
fn next_subpass ( & mut self , _contents : com:: SubpassContents ) {
0 commit comments