@@ -213,20 +213,22 @@ impl DestroyedResources<back::Backend> {
213
213
let buffer_guard = HUB . buffers . read ( ) ;
214
214
215
215
for i in ( 0 ..self . mapped . len ( ) ) . rev ( ) {
216
- // one in resource itself, one here in this list, one the owner holds, and one more somewhere?
217
- let num_refs = self . mapped [ i] . ref_count . load ( ) ;
218
- trace ! ( "{} references remain" , num_refs) ;
219
- if num_refs <= 4 {
220
- // assert_eq!(num_refs, 4);
221
- let resource_id = self . mapped . swap_remove ( i) . value ;
222
- let buf = & buffer_guard[ resource_id] ;
223
- let submit_index = buf. life_guard . submission_index . load ( Ordering :: Acquire ) ;
224
- self . active
225
- . iter_mut ( )
226
- . find ( |a| a. index == submit_index)
227
- . map_or ( & mut self . ready_to_map , |a| & mut a. mapped )
228
- . push ( resource_id) ;
229
- }
216
+ let resource_id = self . mapped . swap_remove ( i) . value ;
217
+ let buf = & buffer_guard[ resource_id] ;
218
+
219
+ let usage = match buf. pending_map_operation {
220
+ Some ( BufferMapOperation :: Read ( ..) ) => resource:: BufferUsageFlags :: MAP_READ ,
221
+ Some ( BufferMapOperation :: Write ( ..) ) => resource:: BufferUsageFlags :: MAP_WRITE ,
222
+ _ => unreachable ! ( ) ,
223
+ } ;
224
+ trackers. buffers . get_with_replaced_usage ( & buffer_guard, resource_id, usage) . unwrap ( ) ;
225
+
226
+ let submit_index = buf. life_guard . submission_index . load ( Ordering :: Acquire ) ;
227
+ self . active
228
+ . iter_mut ( )
229
+ . find ( |a| a. index == submit_index)
230
+ . map_or ( & mut self . ready_to_map , |a| & mut a. mapped )
231
+ . push ( resource_id) ;
230
232
}
231
233
}
232
234
@@ -269,34 +271,39 @@ impl DestroyedResources<back::Backend> {
269
271
}
270
272
271
273
fn handle_mapping ( & mut self , raw : & <back:: Backend as hal:: Backend >:: Device ) {
272
- let mut buffer_guard = HUB . buffers . write ( ) ;
273
-
274
274
for buffer_id in self . ready_to_map . drain ( ..) {
275
- let buffer = & mut buffer_guard[ buffer_id] ;
276
275
let mut operation = None ;
277
- std:: mem:: swap ( & mut operation, & mut buffer. pending_map_operation ) ;
278
- match operation {
279
- Some ( BufferMapOperation :: Read ( range, callback, userdata) ) => {
280
- if let Ok ( ptr) = unsafe { raw. map_memory ( & buffer. memory , range. clone ( ) ) } {
281
- if !buffer. memory_properties . contains ( hal:: memory:: Properties :: COHERENT ) {
282
- unsafe { raw. invalidate_mapped_memory_ranges ( iter:: once ( ( & buffer. memory , range. clone ( ) ) ) ) . unwrap ( ) } ; // TODO
276
+ let ( result, ptr) = {
277
+ let mut buffer_guard = HUB . buffers . write ( ) ;
278
+ let buffer = & mut buffer_guard[ buffer_id] ;
279
+ std:: mem:: swap ( & mut operation, & mut buffer. pending_map_operation ) ;
280
+ match operation. clone ( ) . unwrap ( ) {
281
+ BufferMapOperation :: Read ( range, ..) => {
282
+ if let Ok ( ptr) = unsafe { raw. map_memory ( & buffer. memory , range. clone ( ) ) } {
283
+ if !buffer. memory_properties . contains ( hal:: memory:: Properties :: COHERENT ) {
284
+ unsafe { raw. invalidate_mapped_memory_ranges ( iter:: once ( ( & buffer. memory , range. clone ( ) ) ) ) . unwrap ( ) } ; // TODO
285
+ }
286
+ ( BufferMapAsyncStatus :: Success , Some ( ptr) )
287
+ } else {
288
+ ( BufferMapAsyncStatus :: Error , None )
283
289
}
284
- callback ( BufferMapAsyncStatus :: Success , ptr , userdata ) ;
285
- } else {
286
- callback ( BufferMapAsyncStatus :: Error , std :: ptr :: null ( ) , userdata ) ;
287
- }
288
- } ,
289
- Some ( BufferMapOperation :: Write ( range , callback , userdata ) ) => {
290
- if let Ok ( ptr ) = unsafe { raw . map_memory ( & buffer . memory , range . clone ( ) ) } {
291
- if !buffer . memory_properties . contains ( hal :: memory :: Properties :: COHERENT ) {
292
- buffer . mapped_write_ranges . push ( range ) ;
290
+ } ,
291
+ BufferMapOperation :: Write ( range , .. ) => {
292
+ if let Ok ( ptr ) = unsafe { raw . map_memory ( & buffer . memory , range . clone ( ) ) } {
293
+ if !buffer . memory_properties . contains ( hal :: memory :: Properties :: COHERENT ) {
294
+ buffer . mapped_write_ranges . push ( range . clone ( ) ) ;
295
+ }
296
+ ( BufferMapAsyncStatus :: Success , Some ( ptr ) )
297
+ } else {
298
+ ( BufferMapAsyncStatus :: Error , None )
293
299
}
294
- callback ( BufferMapAsyncStatus :: Success , ptr, userdata) ;
295
- } else {
296
- callback ( BufferMapAsyncStatus :: Error , std:: ptr:: null_mut ( ) , userdata) ;
297
- }
298
- } ,
299
- _ => unreachable ! ( ) ,
300
+ } ,
301
+ }
302
+ } ;
303
+
304
+ match operation. unwrap ( ) {
305
+ BufferMapOperation :: Read ( _, callback, userdata) => callback ( result, ptr. unwrap_or ( std:: ptr:: null_mut ( ) ) , userdata) ,
306
+ BufferMapOperation :: Write ( _, callback, userdata) => callback ( result, ptr. unwrap_or ( std:: ptr:: null_mut ( ) ) , userdata) ,
300
307
} ;
301
308
}
302
309
}
@@ -1022,108 +1029,119 @@ pub extern "C" fn wgpu_queue_submit(
1022
1029
command_buffer_ptr : * const CommandBufferId ,
1023
1030
command_buffer_count : usize ,
1024
1031
) {
1025
- let mut device_guard = HUB . devices . write ( ) ;
1026
- let device = & mut device_guard[ queue_id] ;
1027
-
1028
- let mut swap_chain_links = Vec :: new ( ) ;
1029
1032
let command_buffer_ids =
1030
1033
unsafe { slice:: from_raw_parts ( command_buffer_ptr, command_buffer_count) } ;
1031
1034
1032
- let old_submit_index = device
1033
- . life_guard
1034
- . submission_index
1035
- . fetch_add ( 1 , Ordering :: Relaxed ) ;
1036
- let mut trackers = device. trackers . lock ( ) ;
1037
-
1038
- //TODO: if multiple command buffers are submitted, we can re-use the last
1039
- // native command buffer of the previous chain instead of always creating
1040
- // a temporary one, since the chains are not finished.
1041
- {
1042
- let mut command_buffer_guard = HUB . command_buffers . write ( ) ;
1043
- let buffer_guard = HUB . buffers . read ( ) ;
1044
- let texture_guard = HUB . textures . read ( ) ;
1045
- let texture_view_guard = HUB . texture_views . read ( ) ;
1046
-
1047
- // finish all the command buffers first
1048
- for & cmb_id in command_buffer_ids {
1049
- let comb = & mut command_buffer_guard[ cmb_id] ;
1050
- swap_chain_links. extend ( comb. swap_chain_links . drain ( ..) ) ;
1051
- // update submission IDs
1052
- comb. life_guard . submission_index
1053
- . store ( old_submit_index, Ordering :: Release ) ;
1054
- for id in comb. trackers . buffers . used ( ) {
1055
- buffer_guard[ id] . life_guard . submission_index
1056
- . store ( old_submit_index, Ordering :: Release ) ;
1057
- }
1058
- for id in comb. trackers . textures . used ( ) {
1059
- texture_guard[ id] . life_guard . submission_index
1060
- . store ( old_submit_index, Ordering :: Release ) ;
1061
- }
1062
- for id in comb. trackers . views . used ( ) {
1063
- texture_view_guard[ id] . life_guard . submission_index
1035
+ let ( old_submit_index, fence) = {
1036
+ let mut device_guard = HUB . devices . write ( ) ;
1037
+ let device = & mut device_guard[ queue_id] ;
1038
+
1039
+ let mut swap_chain_links = Vec :: new ( ) ;
1040
+
1041
+ let old_submit_index = device
1042
+ . life_guard
1043
+ . submission_index
1044
+ . fetch_add ( 1 , Ordering :: Relaxed ) ;
1045
+ let mut trackers = device. trackers . lock ( ) ;
1046
+
1047
+ //TODO: if multiple command buffers are submitted, we can re-use the last
1048
+ // native command buffer of the previous chain instead of always creating
1049
+ // a temporary one, since the chains are not finished.
1050
+ {
1051
+ let mut command_buffer_guard = HUB . command_buffers . write ( ) ;
1052
+ let buffer_guard = HUB . buffers . read ( ) ;
1053
+ let texture_guard = HUB . textures . read ( ) ;
1054
+ let texture_view_guard = HUB . texture_views . read ( ) ;
1055
+
1056
+ // finish all the command buffers first
1057
+ for & cmb_id in command_buffer_ids {
1058
+ let comb = & mut command_buffer_guard[ cmb_id] ;
1059
+ swap_chain_links. extend ( comb. swap_chain_links . drain ( ..) ) ;
1060
+ // update submission IDs
1061
+ comb. life_guard . submission_index
1064
1062
. store ( old_submit_index, Ordering :: Release ) ;
1065
- }
1063
+ for id in comb. trackers . buffers . used ( ) {
1064
+ buffer_guard[ id] . life_guard . submission_index
1065
+ . store ( old_submit_index, Ordering :: Release ) ;
1066
+ }
1067
+ for id in comb. trackers . textures . used ( ) {
1068
+ texture_guard[ id] . life_guard . submission_index
1069
+ . store ( old_submit_index, Ordering :: Release ) ;
1070
+ }
1071
+ for id in comb. trackers . views . used ( ) {
1072
+ texture_view_guard[ id] . life_guard . submission_index
1073
+ . store ( old_submit_index, Ordering :: Release ) ;
1074
+ }
1066
1075
1067
- // execute resource transitions
1068
- let mut transit = device. com_allocator . extend ( comb) ;
1069
- unsafe {
1070
- transit. begin (
1071
- hal:: command:: CommandBufferFlags :: ONE_TIME_SUBMIT ,
1072
- hal:: command:: CommandBufferInheritanceInfo :: default ( ) ,
1076
+ // execute resource transitions
1077
+ let mut transit = device. com_allocator . extend ( comb) ;
1078
+ unsafe {
1079
+ transit. begin (
1080
+ hal:: command:: CommandBufferFlags :: ONE_TIME_SUBMIT ,
1081
+ hal:: command:: CommandBufferInheritanceInfo :: default ( ) ,
1082
+ ) ;
1083
+ }
1084
+ command:: CommandBuffer :: insert_barriers (
1085
+ & mut transit,
1086
+ & mut * trackers,
1087
+ & comb. trackers ,
1088
+ Stitch :: Init ,
1089
+ & * buffer_guard,
1090
+ & * texture_guard,
1073
1091
) ;
1092
+ unsafe {
1093
+ transit. finish ( ) ;
1094
+ }
1095
+ comb. raw . insert ( 0 , transit) ;
1096
+ unsafe {
1097
+ comb. raw . last_mut ( ) . unwrap ( ) . finish ( ) ;
1098
+ }
1074
1099
}
1075
- command:: CommandBuffer :: insert_barriers (
1076
- & mut transit,
1077
- & mut * trackers,
1078
- & comb. trackers ,
1079
- Stitch :: Init ,
1080
- & * buffer_guard,
1081
- & * texture_guard,
1082
- ) ;
1083
- unsafe {
1084
- transit. finish ( ) ;
1085
- }
1086
- comb. raw . insert ( 0 , transit) ;
1100
+ }
1101
+
1102
+ // now prepare the GPU submission
1103
+ let fence = device. raw . create_fence ( false ) . unwrap ( ) ;
1104
+ {
1105
+ let command_buffer_guard = HUB . command_buffers . read ( ) ;
1106
+ let surface_guard = HUB . surfaces . read ( ) ;
1107
+
1108
+ let wait_semaphores = swap_chain_links
1109
+ . into_iter ( )
1110
+ . flat_map ( |link| {
1111
+ //TODO: check the epoch
1112
+ surface_guard[ link. swap_chain_id ] . swap_chain
1113
+ . as_ref ( )
1114
+ . map ( |swap_chain| (
1115
+ & swap_chain. frames [ link. image_index as usize ] . sem_available ,
1116
+ hal:: pso:: PipelineStage :: COLOR_ATTACHMENT_OUTPUT ,
1117
+ ) )
1118
+ } ) ;
1119
+
1120
+ let submission =
1121
+ hal:: queue:: Submission :: < _ , _ , & [ <back:: Backend as hal:: Backend >:: Semaphore ] > {
1122
+ //TODO: may `OneShot` be enough?
1123
+ command_buffers : command_buffer_ids
1124
+ . iter ( )
1125
+ . flat_map ( |& cmb_id| & command_buffer_guard[ cmb_id] . raw ) ,
1126
+ wait_semaphores,
1127
+ signal_semaphores : & [ ] , //TODO: signal `sem_present`?
1128
+ } ;
1129
+
1087
1130
unsafe {
1088
- comb. raw . last_mut ( ) . unwrap ( ) . finish ( ) ;
1131
+ device. queue_group . queues [ 0 ]
1132
+ . as_raw_mut ( )
1133
+ . submit ( submission, Some ( & fence) ) ;
1089
1134
}
1090
1135
}
1091
- }
1092
1136
1093
- // now prepare the GPU submission
1094
- let fence = device. raw . create_fence ( false ) . unwrap ( ) ;
1095
- {
1096
- let command_buffer_guard = HUB . command_buffers . read ( ) ;
1097
- let surface_guard = HUB . surfaces . read ( ) ;
1098
-
1099
- let wait_semaphores = swap_chain_links
1100
- . into_iter ( )
1101
- . flat_map ( |link| {
1102
- //TODO: check the epoch
1103
- surface_guard[ link. swap_chain_id ] . swap_chain
1104
- . as_ref ( )
1105
- . map ( |swap_chain| (
1106
- & swap_chain. frames [ link. image_index as usize ] . sem_available ,
1107
- hal:: pso:: PipelineStage :: COLOR_ATTACHMENT_OUTPUT ,
1108
- ) )
1109
- } ) ;
1137
+ ( old_submit_index, fence)
1138
+ } ;
1110
1139
1111
- let submission =
1112
- hal:: queue:: Submission :: < _ , _ , & [ <back:: Backend as hal:: Backend >:: Semaphore ] > {
1113
- //TODO: may `OneShot` be enough?
1114
- command_buffers : command_buffer_ids
1115
- . iter ( )
1116
- . flat_map ( |& cmb_id| & command_buffer_guard[ cmb_id] . raw ) ,
1117
- wait_semaphores,
1118
- signal_semaphores : & [ ] , //TODO: signal `sem_present`?
1119
- } ;
1140
+ // No need for write access to the device from here on out
1141
+ let device_guard = HUB . devices . read ( ) ;
1142
+ let device = & device_guard[ queue_id] ;
1120
1143
1121
- unsafe {
1122
- device. queue_group . queues [ 0 ]
1123
- . as_raw_mut ( )
1124
- . submit ( submission, Some ( & fence) ) ;
1125
- }
1126
- }
1144
+ let mut trackers = device. trackers . lock ( ) ;
1127
1145
1128
1146
let last_done = {
1129
1147
let mut destroyed = device. destroyed . lock ( ) ;
0 commit comments