@@ -98,9 +98,8 @@ unsafe impl<B: hal::Backend> Send for DestroyedResources<B> {}
98
98
unsafe impl < B : hal:: Backend > Sync for DestroyedResources < B > { }
99
99
100
100
impl < B : hal:: Backend > DestroyedResources < B > {
101
- fn add ( & mut self , resource_id : ResourceId , life_guard : & LifeGuard ) {
102
- self . referenced
103
- . push ( ( resource_id, life_guard. ref_count . clone ( ) ) ) ;
101
+ fn add ( & mut self , resource_id : ResourceId , ref_count : RefCount ) {
102
+ self . referenced . push ( ( resource_id, ref_count) ) ;
104
103
}
105
104
106
105
/// Returns the last submission index that is done.
@@ -139,7 +138,11 @@ impl<B: hal::Backend> DestroyedResources<B> {
139
138
}
140
139
141
140
impl DestroyedResources < back:: Backend > {
142
- fn triage_referenced ( & mut self ) {
141
+ fn triage_referenced (
142
+ & mut self ,
143
+ buffer_tracker : & mut BufferTracker ,
144
+ texture_tracker : & mut TextureTracker ,
145
+ ) {
143
146
for i in ( 0 ..self . referenced . len ( ) ) . rev ( ) {
144
147
// one in resource itself, and one here in this list
145
148
let num_refs = self . referenced [ i] . 1 . load ( ) ;
@@ -148,11 +151,13 @@ impl DestroyedResources<back::Backend> {
148
151
let resource_id = self . referenced . swap_remove ( i) . 0 ;
149
152
let ( submit_index, resource) = match resource_id {
150
153
ResourceId :: Buffer ( id) => {
154
+ buffer_tracker. remove ( id) ;
151
155
let buf = HUB . buffers . unregister ( id) ;
152
156
let si = buf. life_guard . submission_index . load ( Ordering :: Acquire ) ;
153
157
( si, Resource :: Buffer ( buf) )
154
158
}
155
159
ResourceId :: Texture ( id) => {
160
+ texture_tracker. remove ( id) ;
156
161
let tex = HUB . textures . unregister ( id) ;
157
162
let si = tex. life_guard . submission_index . load ( Ordering :: Acquire ) ;
158
163
( si, Resource :: Texture ( tex) )
@@ -369,7 +374,10 @@ pub extern "C" fn wgpu_buffer_destroy(buffer_id: BufferId) {
369
374
. get ( buffer. device_id . value )
370
375
. destroyed
371
376
. lock ( )
372
- . add ( ResourceId :: Buffer ( buffer_id) , & buffer. life_guard ) ;
377
+ . add (
378
+ ResourceId :: Buffer ( buffer_id) ,
379
+ buffer. life_guard . ref_count . clone ( ) ,
380
+ ) ;
373
381
}
374
382
375
383
@@ -579,7 +587,10 @@ pub extern "C" fn wgpu_texture_destroy(texture_id: TextureId) {
579
587
. get ( texture. device_id . value )
580
588
. destroyed
581
589
. lock ( )
582
- . add ( ResourceId :: Texture ( texture_id) , & texture. life_guard ) ;
590
+ . add (
591
+ ResourceId :: Texture ( texture_id) ,
592
+ texture. life_guard . ref_count . clone ( ) ,
593
+ ) ;
583
594
}
584
595
585
596
#[ no_mangle]
@@ -595,7 +606,10 @@ pub extern "C" fn wgpu_texture_view_destroy(texture_view_id: TextureViewId) {
595
606
. get ( device_id)
596
607
. destroyed
597
608
. lock ( )
598
- . add ( ResourceId :: TextureView ( texture_view_id) , & view. life_guard ) ;
609
+ . add (
610
+ ResourceId :: TextureView ( texture_view_id) ,
611
+ view. life_guard . ref_count . clone ( ) ,
612
+ ) ;
599
613
}
600
614
601
615
@@ -902,6 +916,8 @@ pub extern "C" fn wgpu_queue_submit(
902
916
. life_guard
903
917
. submission_index
904
918
. fetch_add ( 1 , Ordering :: Relaxed ) ;
919
+ let mut buffer_tracker = device. buffer_tracker . lock ( ) ;
920
+ let mut texture_tracker = device. texture_tracker . lock ( ) ;
905
921
906
922
//TODO: if multiple command buffers are submitted, we can re-use the last
907
923
// native command buffer of the previous chain instead of always creating
@@ -910,8 +926,6 @@ pub extern "C" fn wgpu_queue_submit(
910
926
let mut command_buffer_guard = HUB . command_buffers . write ( ) ;
911
927
let buffer_guard = HUB . buffers . read ( ) ;
912
928
let texture_guard = HUB . textures . read ( ) ;
913
- let mut buffer_tracker = device. buffer_tracker . lock ( ) ;
914
- let mut texture_tracker = device. texture_tracker . lock ( ) ;
915
929
916
930
// finish all the command buffers first
917
931
for & cmb_id in command_buffer_ids {
@@ -965,17 +979,20 @@ pub extern "C" fn wgpu_queue_submit(
965
979
let fence = device. raw . create_fence ( false ) . unwrap ( ) ;
966
980
{
967
981
let command_buffer_guard = HUB . command_buffers . read ( ) ;
968
- let swap_chain_guard = HUB . swap_chains . read ( ) ;
982
+ let surface_guard = HUB . surfaces . read ( ) ;
969
983
970
984
let wait_semaphores = swap_chain_links
971
985
. into_iter ( )
972
- . map ( |link| {
986
+ . flat_map ( |link| {
973
987
//TODO: check the epoch
974
- let sem = & swap_chain_guard
988
+ surface_guard
975
989
. get ( link. swap_chain_id . 0 )
976
- . frames [ link. image_index as usize ]
977
- . sem_available ;
978
- ( sem, hal:: pso:: PipelineStage :: COLOR_ATTACHMENT_OUTPUT )
990
+ . swap_chain
991
+ . as_ref ( )
992
+ . map ( |swap_chain| (
993
+ & swap_chain. frames [ link. image_index as usize ] . sem_available ,
994
+ hal:: pso:: PipelineStage :: COLOR_ATTACHMENT_OUTPUT ,
995
+ ) )
979
996
} ) ;
980
997
981
998
let submission =
@@ -997,7 +1014,7 @@ pub extern "C" fn wgpu_queue_submit(
997
1014
998
1015
let last_done = {
999
1016
let mut destroyed = device. destroyed . lock ( ) ;
1000
- destroyed. triage_referenced ( ) ;
1017
+ destroyed. triage_referenced ( & mut * buffer_tracker , & mut * texture_tracker ) ;
1001
1018
let last_done = destroyed. cleanup ( & device. raw ) ;
1002
1019
1003
1020
destroyed. active . push ( ActiveSubmission {
@@ -1294,12 +1311,12 @@ pub extern "C" fn wgpu_device_create_compute_pipeline(
1294
1311
HUB . compute_pipelines . register ( pipeline)
1295
1312
}
1296
1313
1297
-
1298
1314
pub fn device_create_swap_chain (
1299
1315
device_id : DeviceId ,
1300
1316
surface_id : SurfaceId ,
1301
1317
desc : & swap_chain:: SwapChainDescriptor ,
1302
- ) -> ( swap_chain:: SwapChain < back:: Backend > , Vec < resource:: Texture < back:: Backend > > ) {
1318
+ outdated : swap_chain:: OutdatedFrame ,
1319
+ ) -> Vec < resource:: Texture < back:: Backend > > {
1303
1320
let device_guard = HUB . devices . read ( ) ;
1304
1321
let device = device_guard. get ( device_id) ;
1305
1322
let mut surface_guard = HUB . surfaces . write ( ) ;
@@ -1331,42 +1348,60 @@ pub fn device_create_swap_chain(
1331
1348
"Requested size {}x{} is outside of the supported range: {:?}" ,
1332
1349
desc. width, desc. height, caps. extents) ;
1333
1350
1351
+
1352
+ let ( old_raw, sem_available, command_pool) = match surface. swap_chain . take ( ) {
1353
+ Some ( mut old) => {
1354
+ assert_eq ! ( old. device_id. value, device_id) ;
1355
+ let mut destroyed = device. destroyed . lock ( ) ;
1356
+ destroyed. add ( ResourceId :: Texture ( old. outdated . texture_id . value ) , old. outdated . texture_id . ref_count ) ;
1357
+ destroyed. add ( ResourceId :: TextureView ( old. outdated . view_id . value ) , old. outdated . view_id . ref_count ) ;
1358
+ unsafe {
1359
+ old. command_pool . reset ( )
1360
+ } ;
1361
+ ( Some ( old. raw ) , old. sem_available , old. command_pool )
1362
+ }
1363
+ _ => unsafe {
1364
+ let sem_available = device. raw
1365
+ . create_semaphore ( )
1366
+ . unwrap ( ) ;
1367
+ let command_pool = device. raw
1368
+ . create_command_pool_typed (
1369
+ & device. queue_group ,
1370
+ hal:: pool:: CommandPoolCreateFlags :: RESET_INDIVIDUAL ,
1371
+ )
1372
+ . unwrap ( ) ;
1373
+ ( None , sem_available, command_pool)
1374
+ }
1375
+ } ;
1376
+
1334
1377
let ( raw, backbuffer) = unsafe {
1335
1378
device. raw
1336
1379
. create_swapchain (
1337
1380
& mut surface. raw ,
1338
1381
config. with_image_usage ( usage) ,
1339
- None ,
1382
+ old_raw ,
1340
1383
)
1341
1384
. unwrap ( )
1342
1385
} ;
1343
- let command_pool = unsafe {
1344
- device. raw
1345
- . create_command_pool_typed (
1346
- & device. queue_group ,
1347
- hal:: pool:: CommandPoolCreateFlags :: RESET_INDIVIDUAL ,
1348
- )
1349
- . unwrap ( )
1350
- } ;
1351
-
1352
- let swap_chain = swap_chain:: SwapChain {
1386
+ surface. swap_chain = Some ( swap_chain:: SwapChain {
1353
1387
raw,
1354
1388
device_id : Stored {
1355
1389
value : device_id,
1356
1390
ref_count : device. life_guard . ref_count . clone ( ) ,
1357
1391
} ,
1358
1392
frames : Vec :: with_capacity ( num_frames as usize ) ,
1359
1393
acquired : Vec :: with_capacity ( 1 ) , //TODO: get it from gfx-hal?
1360
- sem_available : device. raw . create_semaphore ( ) . unwrap ( ) ,
1394
+ sem_available,
1395
+ outdated,
1361
1396
command_pool,
1362
- } ;
1397
+ } ) ;
1363
1398
1364
1399
let images = match backbuffer {
1365
1400
hal:: Backbuffer :: Images ( images) => images,
1366
1401
hal:: Backbuffer :: Framebuffer ( _) => panic ! ( "Deprecated API detected!" ) ,
1367
1402
} ;
1368
1403
1369
- let textures = images
1404
+ images
1370
1405
. into_iter ( )
1371
1406
. map ( |raw| resource:: Texture {
1372
1407
raw,
@@ -1384,18 +1419,20 @@ pub fn device_create_swap_chain(
1384
1419
swap_chain_link : None ,
1385
1420
life_guard : LifeGuard :: new ( ) ,
1386
1421
} )
1387
- . collect ( ) ;
1388
-
1389
- ( swap_chain, textures)
1422
+ . collect ( )
1390
1423
}
1391
1424
1392
1425
#[ cfg( feature = "local" ) ]
1393
1426
fn swap_chain_populate_textures (
1394
1427
swap_chain_id : SwapChainId ,
1395
1428
textures : Vec < resource:: Texture < back:: Backend > > ,
1396
1429
) {
1397
- let mut swap_chain_guard = HUB . swap_chains . write ( ) ;
1398
- let swap_chain = swap_chain_guard. get_mut ( swap_chain_id) ;
1430
+ let mut surface_guard = HUB . surfaces . write ( ) ;
1431
+ let swap_chain = surface_guard
1432
+ . get_mut ( swap_chain_id)
1433
+ . swap_chain
1434
+ . as_mut ( )
1435
+ . unwrap ( ) ;
1399
1436
let device_guard = HUB . devices . read ( ) ;
1400
1437
let device = device_guard. get ( swap_chain. device_id . value ) ;
1401
1438
@@ -1457,10 +1494,28 @@ pub extern "C" fn wgpu_device_create_swap_chain(
1457
1494
surface_id : SurfaceId ,
1458
1495
desc : & swap_chain:: SwapChainDescriptor ,
1459
1496
) -> SwapChainId {
1460
- let ( swap_chain, textures) = device_create_swap_chain ( device_id, surface_id, desc) ;
1461
- let id = HUB . swap_chains . register ( swap_chain) ;
1462
- swap_chain_populate_textures ( id, textures) ;
1463
- id
1497
+ let outdated = {
1498
+ let outdated_texture = device_create_texture ( device_id, & desc. to_texture_desc ( ) ) ;
1499
+ let texture_id = Stored {
1500
+ ref_count : outdated_texture. life_guard . ref_count . clone ( ) ,
1501
+ value : HUB . textures . register ( outdated_texture) ,
1502
+ } ;
1503
+ device_track_texture ( device_id, texture_id. value , texture_id. ref_count . clone ( ) ) ;
1504
+
1505
+ let outdated_view = texture_create_default_view ( texture_id. value ) ;
1506
+ let view_id = Stored {
1507
+ ref_count : outdated_view. life_guard . ref_count . clone ( ) ,
1508
+ value : HUB . texture_views . register ( outdated_view) ,
1509
+ } ;
1510
+ swap_chain:: OutdatedFrame {
1511
+ texture_id,
1512
+ view_id,
1513
+ }
1514
+ } ;
1515
+
1516
+ let textures = device_create_swap_chain ( device_id, surface_id, desc, outdated) ;
1517
+ swap_chain_populate_textures ( surface_id, textures) ;
1518
+ surface_id
1464
1519
}
1465
1520
1466
1521
0 commit comments