@@ -121,9 +121,10 @@ const {
121121
122122import * as webidl from "ext:deno_webidl/00_webidl.js" ;
123123import {
124+ defineEventHandler ,
124125 Event ,
125126 EventTarget ,
126- defineEventHandler ,
127+ setEventTargetData ,
127128} from "ext:deno_web/02_event.js" ;
128129import { DOMException } from "ext:deno_web/01_dom_exception.js" ;
129130import { createFilteredInspectProxy } from "ext:deno_console/01_console.js" ;
@@ -299,7 +300,6 @@ class GPUValidationError extends GPUError {
299300 this [ _message ] = message ;
300301 }
301302}
302- const GPUValidationErrorPrototype = GPUValidationError . prototype ;
303303
304304class GPUOutOfMemoryError extends GPUError {
305305 name = "GPUOutOfMemoryError" ;
@@ -312,7 +312,6 @@ class GPUOutOfMemoryError extends GPUError {
312312 this [ _message ] = message ;
313313 }
314314}
315- const GPUOutOfMemoryErrorPrototype = GPUOutOfMemoryError . prototype ;
316315
317316class GPUInternalError extends GPUError {
318317 name = "GPUInternalError" ;
@@ -321,7 +320,6 @@ class GPUInternalError extends GPUError {
321320 this [ webidl . brand ] = webidl . brand ;
322321 }
323322}
324- const GPUInternalErrorPrototype = GPUInternalError . prototype ;
325323
326324class GPUUncapturedErrorEvent extends Event {
327325 #error;
@@ -333,7 +331,7 @@ class GPUUncapturedErrorEvent extends Event {
333331 const prefix = "Failed to construct 'GPUUncapturedErrorEvent'" ;
334332 webidl . requiredArguments ( arguments . length , 2 , prefix ) ;
335333 gpuUncapturedErrorEventInitDict = webidl . converters
336- . gpuUncapturedErrorEventInitDict (
334+ . GPUUncapturedErrorEventInit (
337335 gpuUncapturedErrorEventInitDict ,
338336 prefix ,
339337 "Argument 2" ,
@@ -348,7 +346,6 @@ class GPUUncapturedErrorEvent extends Event {
348346 }
349347}
350348const GPUUncapturedErrorEventPrototype = GPUUncapturedErrorEvent . prototype ;
351- defineEventHandler ( GPUUncapturedErrorEvent . prototype , "uncapturederror" ) ;
352349
353350class GPU {
354351 [ webidl . brand ] = webidl . brand ;
@@ -420,9 +417,12 @@ function createGPUAdapter(inner) {
420417 return adapter ;
421418}
422419
420+ const _invalid = Symbol ( "[[invalid]]" ) ;
423421class GPUAdapter {
424422 /** @type {InnerGPUAdapter } */
425423 [ _adapter ] ;
424+ /** @type {bool } */
425+ [ _invalid ] ;
426426
427427 /** @returns {GPUSupportedFeatures } */
428428 get features ( ) {
@@ -469,23 +469,33 @@ class GPUAdapter {
469469 }
470470 }
471471
472+ if ( this [ _invalid ] ) {
473+ throw new TypeError (
474+ "The adapter cannot be reused, as it has been invalidated by a device creation" ,
475+ ) ;
476+ }
477+
472478 const { rid, queueRid, features, limits } = op_webgpu_request_device (
473479 this [ _adapter ] . rid ,
474480 descriptor . label ,
475481 requiredFeatures ,
476482 descriptor . requiredLimits ,
477483 ) ;
478484
485+ this [ _invalid ] = true ;
486+
479487 const inner = new InnerGPUDevice ( {
480488 rid,
481489 adapter : this ,
482490 features : createGPUSupportedFeatures ( features ) ,
483491 limits : createGPUSupportedLimits ( limits ) ,
484492 } ) ;
493+ const queue = createGPUQueue ( descriptor . label , inner , queueRid ) ;
494+ inner . trackResource ( queue ) ;
485495 const device = createGPUDevice (
486496 descriptor . label ,
487497 inner ,
488- createGPUQueue ( descriptor . label , inner , queueRid ) ,
498+ queue ,
489499 ) ;
490500 inner . device = device ;
491501 return device ;
@@ -497,6 +507,12 @@ class GPUAdapter {
497507 requestAdapterInfo ( ) {
498508 webidl . assertBranded ( this , GPUAdapterPrototype ) ;
499509
510+ if ( this [ _invalid ] ) {
511+ throw new TypeError (
512+ "The adapter cannot be reused, as it has been invalidated by a device creation" ,
513+ ) ;
514+ }
515+
500516 const {
501517 vendor,
502518 architecture,
@@ -977,7 +993,9 @@ class InnerGPUDevice {
977993 ) ;
978994 return ;
979995 case "validation" :
980- constructedError = new GPUValidationError ( error . value ?? "validation error" ) ;
996+ constructedError = new GPUValidationError (
997+ error . value ?? "validation error" ,
998+ ) ;
981999 break ;
9821000 case "out-of-memory" :
9831001 constructedError = new GPUOutOfMemoryError ( ) ;
@@ -996,11 +1014,13 @@ class InnerGPUDevice {
9961014 ( { filter } ) => filter === error . type ,
9971015 ) ;
9981016 if ( scope ) {
999- scope . errors . push ( constructedError ) ;
1017+ ArrayPrototypePush ( scope . errors , constructedError ) ;
10001018 } else {
1001- this . device . dispatchEvent ( new GPUUncapturedErrorEvent ( "uncapturederror" , {
1002- error : constructedError ,
1003- } ) ) ;
1019+ this . device . dispatchEvent (
1020+ new GPUUncapturedErrorEvent ( "uncapturederror" , {
1021+ error : constructedError ,
1022+ } ) ,
1023+ ) ;
10041024 }
10051025 }
10061026}
@@ -1017,6 +1037,7 @@ function createGPUDevice(label, inner, queue) {
10171037 device [ _label ] = label ;
10181038 device [ _device ] = inner ;
10191039 device [ _queue ] = queue ;
1040+ setEventTargetData ( device ) ;
10201041 return device ;
10211042}
10221043
@@ -1132,10 +1153,11 @@ class GPUDevice extends EventTarget {
11321153 "Argument 1" ,
11331154 ) ;
11341155 const device = assertDevice ( this , prefix , "this" ) ;
1156+ // assign normalized size to descriptor due to createGPUTexture needs it
1157+ descriptor . size = normalizeGPUExtent3D ( descriptor . size ) ;
11351158 const { rid, err } = op_webgpu_create_texture ( {
11361159 deviceRid : device . rid ,
11371160 ...descriptor ,
1138- size : normalizeGPUExtent3D ( descriptor . size ) ,
11391161 } ) ;
11401162 device . pushError ( err ) ;
11411163
@@ -1307,7 +1329,6 @@ class GPUDevice extends EventTarget {
13071329 } else {
13081330 // deno-lint-ignore prefer-primordials
13091331 const rid = assertResource ( resource . buffer , prefix , context ) ;
1310- // deno-lint-ignore prefer-primordials
13111332 return {
13121333 binding : entry . binding ,
13131334 kind : "GPUBufferBinding" ,
@@ -1816,6 +1837,7 @@ class GPUDevice extends EventTarget {
18161837}
18171838GPUObjectBaseMixin ( "GPUDevice" , GPUDevice ) ;
18181839const GPUDevicePrototype = GPUDevice . prototype ;
1840+ defineEventHandler ( GPUDevice . prototype , "uncapturederror" ) ;
18191841
18201842class GPUPipelineError extends DOMException {
18211843 #reason;
@@ -1861,6 +1883,15 @@ class GPUQueue {
18611883 /** @type {number } */
18621884 [ _rid ] ;
18631885
1886+ [ _cleanup ] ( ) {
1887+ const rid = this [ _rid ] ;
1888+ if ( rid !== undefined ) {
1889+ core . close ( rid ) ;
1890+ /** @type {number | undefined } */
1891+ this [ _rid ] = undefined ;
1892+ }
1893+ }
1894+
18641895 constructor ( ) {
18651896 webidl . illegalConstructor ( ) ;
18661897 }
@@ -5488,6 +5519,16 @@ webidl.converters["GPUExtent3D"] = (V, opts) => {
54885519 if ( typeof V === "object" ) {
54895520 const method = V [ SymbolIterator ] ;
54905521 if ( method !== undefined ) {
5522+ // validate length of GPUExtent3D
5523+ const min = 1 ;
5524+ const max = 3 ;
5525+ if ( V . length < min || V . length > max ) {
5526+ throw webidl . makeException (
5527+ TypeError ,
5528+ `A sequence of number used as a GPUExtent3D must have between ${ min } and ${ max } elements.` ,
5529+ opts ,
5530+ ) ;
5531+ }
54915532 return webidl . converters [ "sequence<GPUIntegerCoordinate>" ] ( V , opts ) ;
54925533 }
54935534 return webidl . converters [ "GPUExtent3DDict" ] ( V , opts ) ;
@@ -6823,6 +6864,15 @@ webidl.converters["GPUOrigin3D"] = (V, opts) => {
68236864 if ( typeof V === "object" ) {
68246865 const method = V [ SymbolIterator ] ;
68256866 if ( method !== undefined ) {
6867+ // validate length of GPUOrigin3D
6868+ const length = 3 ;
6869+ if ( V . length > length ) {
6870+ throw webidl . makeException (
6871+ TypeError ,
6872+ `A sequence of number used as a GPUOrigin3D must have at most ${ length } elements.` ,
6873+ opts ,
6874+ ) ;
6875+ }
68266876 return webidl . converters [ "sequence<GPUIntegerCoordinate>" ] ( V , opts ) ;
68276877 }
68286878 return webidl . converters [ "GPUOrigin3DDict" ] ( V , opts ) ;
@@ -6891,6 +6941,15 @@ webidl.converters["GPUOrigin2D"] = (V, opts) => {
68916941 if ( typeof V === "object" ) {
68926942 const method = V [ SymbolIterator ] ;
68936943 if ( method !== undefined ) {
6944+ // validate length of GPUOrigin2D
6945+ const length = 2 ;
6946+ if ( V . length > length ) {
6947+ throw webidl . makeException (
6948+ TypeError ,
6949+ `A sequence of number used as a GPUOrigin2D must have at most ${ length } elements.` ,
6950+ opts ,
6951+ ) ;
6952+ }
68946953 return webidl . converters [ "sequence<GPUIntegerCoordinate>" ] ( V , opts ) ;
68956954 }
68966955 return webidl . converters [ "GPUOrigin2DDict" ] ( V , opts ) ;
@@ -6976,6 +7035,15 @@ webidl.converters["GPUColor"] = (V, opts) => {
69767035 if ( typeof V === "object" ) {
69777036 const method = V [ SymbolIterator ] ;
69787037 if ( method !== undefined ) {
7038+ // validate length of GPUColor
7039+ const length = 4 ;
7040+ if ( V . length !== length ) {
7041+ throw webidl . makeException (
7042+ TypeError ,
7043+ `A sequence of number used as a GPUColor must have exactly ${ length } elements.` ,
7044+ opts ,
7045+ ) ;
7046+ }
69797047 return webidl . converters [ "sequence<double>" ] ( V , opts ) ;
69807048 }
69817049 return webidl . converters [ "GPUColorDict" ] ( V , opts ) ;
0 commit comments