@@ -14,10 +14,12 @@ async function waitForGC(ref, label) {
14
14
debug ( label , 'was GCed' ) ;
15
15
}
16
16
17
+ const kGCTimeout = 5000 ;
18
+
17
19
describe ( 'reference count tests' , ( ) => {
18
20
19
21
it ( 'correctly handles GC with device.features' , async function ( ) {
20
- this . timeout ( 20000 ) ;
22
+ this . timeout ( kGCTimeout ) ;
21
23
const adapter = await navigator . gpu . requestAdapter ( ) ;
22
24
23
25
const [ iterWeakRef , featuresWeakRef ] = await ( async ( ) => {
@@ -40,5 +42,93 @@ describe('reference count tests', () => {
40
42
// dawn.node will likely crash before this if this is not working.
41
43
} ) ;
42
44
45
+ it ( 'persists the GPUBuffer until the arrayBuffer is destroyed' , async function ( ) {
46
+ this . timeout ( kGCTimeout ) ;
47
+
48
+ const adapter = await navigator . gpu . requestAdapter ( ) ;
49
+ const device = await adapter . requestDevice ( ) ;
50
+
51
+ const arrayBufferRef = await ( async ( ) => {
52
+ const [ arrayBuffer , bufferWeakRef ] = await ( async ( ) => {
53
+ const buffer = device . createBuffer ( { size : 16 , usage : GPUBufferUsage . COPY_SRC | GPUBufferUsage . MAP_WRITE } )
54
+ await buffer . mapAsync ( GPUMapMode . WRITE ) ;
55
+ const arrayBuffer = buffer . getMappedRange ( ) ;
56
+ buffer . destroy ( ) ;
57
+ return [ arrayBuffer , new WeakRef ( buffer ) ] ;
58
+ } ) ( ) ;
59
+
60
+ await waitForGC ( bufferWeakRef , 'buffer' ) ;
61
+ // access the arrayBuffer
62
+ assert ( typeof arrayBuffer . byteLength === 'number' ) ;
63
+
64
+ return new WeakRef ( arrayBuffer ) ;
65
+ } ) ( ) ;
66
+
67
+ // Will timeout if never released
68
+ await waitForGC ( arrayBufferRef , 'arrayBuffer' ) ;
69
+ } ) ;
70
+
71
+ it ( 'persists the GPUBuffer until the arrayBuffer is GCed without being destroyed' , async function ( ) {
72
+ this . timeout ( kGCTimeout ) ;
73
+
74
+ const adapter = await navigator . gpu . requestAdapter ( ) ;
75
+ const device = await adapter . requestDevice ( ) ;
76
+
77
+ const arrayBufferRef = await ( async ( ) => {
78
+ const [ arrayBuffer , bufferWeakRef ] = await ( async ( ) => {
79
+ const buffer = device . createBuffer ( { size : 16 , usage : GPUBufferUsage . COPY_SRC | GPUBufferUsage . MAP_WRITE } )
80
+ await buffer . mapAsync ( GPUMapMode . WRITE ) ;
81
+ const arrayBuffer = buffer . getMappedRange ( ) ;
82
+ return [ arrayBuffer , new WeakRef ( buffer ) ] ;
83
+ } ) ( ) ;
84
+
85
+ await waitForGC ( bufferWeakRef , 'buffer' ) ;
86
+ // access the arrayBuffer
87
+ assert ( typeof arrayBuffer . byteLength === 'number' ) ;
88
+
89
+ return new WeakRef ( arrayBuffer ) ;
90
+ } ) ( ) ;
91
+
92
+ // Will timeout if never released
93
+ await waitForGC ( arrayBufferRef , 'arrayBuffer' ) ;
94
+ } ) ;
95
+
96
+ it ( 'GCs GPUBuffer and arrayBuffer when buffer references arrayBuffer' , async function ( ) {
97
+ this . timeout ( kGCTimeout ) ;
98
+
99
+ const adapter = await navigator . gpu . requestAdapter ( ) ;
100
+ const device = await adapter . requestDevice ( ) ;
101
+
102
+ const [ arrayBufferRef , bufferWeakRef ] = await ( async ( ) => {
103
+ const buffer = device . createBuffer ( { size : 16 , usage : GPUBufferUsage . COPY_SRC | GPUBufferUsage . MAP_WRITE } )
104
+ await buffer . mapAsync ( GPUMapMode . WRITE ) ;
105
+ const arrayBuffer = buffer . getMappedRange ( ) ;
106
+ buffer . buf = arrayBuffer ;
107
+ return [ new WeakRef ( arrayBuffer ) , new WeakRef ( buffer ) ] ;
108
+ } ) ( ) ;
109
+
110
+ // Will timeout if never released
111
+ await waitForGC ( bufferWeakRef , 'buffer' ) ;
112
+ await waitForGC ( arrayBufferRef , 'arrayBuffer' ) ;
113
+ } ) ;
114
+
115
+ it ( 'GCs GPUBuffer and arrayBuffer when arrayBuffer references Buffer' , async function ( ) {
116
+ this . timeout ( kGCTimeout ) ;
117
+
118
+ const adapter = await navigator . gpu . requestAdapter ( ) ;
119
+ const device = await adapter . requestDevice ( ) ;
120
+
121
+ const [ arrayBufferRef , bufferWeakRef ] = await ( async ( ) => {
122
+ const buffer = device . createBuffer ( { size : 16 , usage : GPUBufferUsage . COPY_SRC | GPUBufferUsage . MAP_WRITE } )
123
+ await buffer . mapAsync ( GPUMapMode . WRITE ) ;
124
+ const arrayBuffer = buffer . getMappedRange ( ) ;
125
+ arrayBuffer . buf = buffer ;
126
+ return [ new WeakRef ( arrayBuffer ) , new WeakRef ( buffer ) ] ;
127
+ } ) ( ) ;
128
+
129
+ // Will timeout if never released
130
+ await waitForGC ( bufferWeakRef , 'buffer' ) ;
131
+ await waitForGC ( arrayBufferRef , 'arrayBuffer' ) ;
132
+ } ) ;
43
133
44
134
} ) ;
0 commit comments