@@ -23,10 +23,35 @@ class TestFailedButDeviceReusable extends Error {}
2323class FeaturesNotSupported extends Error { }
2424export class TestOOMedShouldAttemptGC extends Error { }
2525
26- export type DescriptorModifierFn = (
27- adapter : GPUAdapter ,
28- desc : CanonicalDeviceDescriptor | undefined
29- ) => CanonicalDeviceDescriptor ;
26+ /**
27+ * DescriptorModifier lets you supply a function to select a device
28+ * based on the limits/features available from the adapter.
29+ * Devices pooled based on a key and that key is derived before
30+ * an adapter is requested. That means you select key without
31+ * knowledge of what the adapter will provide. You do this by
32+ * providing a keyModifier function that appends a suffix.
33+ *
34+ * For example: If your modifier adds all the limits you might
35+ * choose 'maxLimits' are your suffix
36+ *
37+ * ```js
38+ * keyModifier(s: string) { return `${s}:maxLimits`; },
39+ * ```
40+ *
41+ * If your modifier selects only `maxBindGroups` and `maxColorAttachments`
42+ * then your suffix might be `maxBindGroups&maxColorAttachments`
43+ *
44+ * ```js
45+ * keyModifier(s: string) { return `${s}:maxBindGroups&maxColorAttachments`; },
46+ * ```
47+ */
48+ export type DescriptorModifier = {
49+ keyModifier ( baseKey : string ) : string ;
50+ descriptorModifier (
51+ adapter : GPUAdapter ,
52+ desc : CanonicalDeviceDescriptor | undefined
53+ ) : CanonicalDeviceDescriptor ;
54+ } ;
3055
3156export class DevicePool {
3257 private holders : 'uninitialized' | 'failed' | DescriptorToHolderMap = 'uninitialized' ;
@@ -35,13 +60,13 @@ export class DevicePool {
3560 async acquire (
3661 recorder : TestCaseRecorder ,
3762 descriptor : UncanonicalizedDeviceDescriptor | undefined ,
38- descriptorModifierFn : DescriptorModifierFn | undefined
63+ descriptorModifier : DescriptorModifier | undefined
3964 ) : Promise < DeviceProvider > {
4065 let errorMessage = '' ;
4166 if ( this . holders === 'uninitialized' ) {
4267 this . holders = new DescriptorToHolderMap ( ) ;
4368 try {
44- await this . holders . getOrCreate ( recorder , undefined , descriptorModifierFn ) ;
69+ await this . holders . getOrCreate ( recorder , undefined , descriptorModifier ) ;
4570 } catch ( ex ) {
4671 this . holders = 'failed' ;
4772 if ( ex instanceof Error ) {
@@ -55,7 +80,7 @@ export class DevicePool {
5580 `WebGPU device failed to initialize${ errorMessage } ; not retrying`
5681 ) ;
5782
58- const holder = await this . holders . getOrCreate ( recorder , descriptor , descriptorModifierFn ) ;
83+ const holder = await this . holders . getOrCreate ( recorder , descriptor , descriptorModifier ) ;
5984
6085 assert ( holder . state === 'free' , 'Device was in use on DevicePool.acquire' ) ;
6186 holder . state = 'acquired' ;
@@ -150,9 +175,10 @@ class DescriptorToHolderMap {
150175 async getOrCreate (
151176 recorder : TestCaseRecorder ,
152177 uncanonicalizedDescriptor : UncanonicalizedDeviceDescriptor | undefined ,
153- descriptorModifierFn : DescriptorModifierFn | undefined
178+ descriptorModifier : DescriptorModifier | undefined
154179 ) : Promise < DeviceHolder > {
155- const [ descriptor , key ] = canonicalizeDescriptor ( uncanonicalizedDescriptor ) ;
180+ const [ descriptor , baseKey ] = canonicalizeDescriptor ( uncanonicalizedDescriptor ) ;
181+ const key = descriptorModifier ?. keyModifier ( baseKey ) || baseKey ;
156182 // Quick-reject descriptors that are known to be unsupported already.
157183 if ( this . unsupported . has ( key ) ) {
158184 throw new SkipTestCase (
@@ -174,7 +200,7 @@ class DescriptorToHolderMap {
174200 // No existing item was found; add a new one.
175201 let value ;
176202 try {
177- value = await DeviceHolder . create ( recorder , descriptor , descriptorModifierFn ) ;
203+ value = await DeviceHolder . create ( recorder , descriptor , descriptorModifier ) ;
178204 } catch ( ex ) {
179205 if ( ex instanceof FeaturesNotSupported ) {
180206 this . unsupported . add ( key ) ;
@@ -313,13 +339,13 @@ class DeviceHolder implements DeviceProvider {
313339 static async create (
314340 recorder : TestCaseRecorder ,
315341 descriptor : CanonicalDeviceDescriptor | undefined ,
316- descriptorModifierFn : DescriptorModifierFn | undefined
342+ descriptorModifier : DescriptorModifier | undefined
317343 ) : Promise < DeviceHolder > {
318344 const gpu = getGPU ( recorder ) ;
319345 const adapter = await gpu . requestAdapter ( ) ;
320346 assert ( adapter !== null , 'requestAdapter returned null' ) ;
321- if ( descriptorModifierFn ) {
322- descriptor = descriptorModifierFn ( adapter , descriptor ) ;
347+ if ( descriptorModifier ) {
348+ descriptor = descriptorModifier . descriptorModifier ( adapter , descriptor ) ;
323349 }
324350 if ( ! supportsFeature ( adapter , descriptor ) ) {
325351 throw new FeaturesNotSupported ( 'One or more features are not supported' ) ;
0 commit comments