67
67
68
68
69
69
class Runner :
70
- REQUIRED_FEATURES = ["multi-draw-indirect" , "indirect-first-instance" ]
70
+ REQUIRED_FEATURES = ["indirect-first-instance" ]
71
+ OPTIONAL_FEATURES = ["multi-draw-indirect" ] # we'll be adding more
71
72
72
73
@classmethod
73
74
def is_usable (cls ):
@@ -76,7 +77,11 @@ def is_usable(cls):
76
77
77
78
def __init__ (self ):
78
79
adapter = wgpu .gpu .request_adapter (power_preference = "high-performance" )
79
- self .device = adapter .request_device (required_features = self .REQUIRED_FEATURES )
80
+ features = [
81
+ * self .REQUIRED_FEATURES ,
82
+ * [x for x in self .OPTIONAL_FEATURES if x in adapter .features ],
83
+ ]
84
+ self .device = adapter .request_device (required_features = features )
80
85
self .output_texture = self .device .create_texture (
81
86
# Actual size is immaterial. Could just be 1x1
82
87
size = [128 , 128 ],
@@ -158,7 +163,8 @@ def __init__(self):
158
163
# We're going to want to try calling these draw functions from a buffer, and it
159
164
# would be nice to test that these buffers have an offset
160
165
self .draw_data_buffer = self .device .create_buffer_with_data (
161
- data = np .uint32 ([0 , 0 , * self .draw_args1 , * self .draw_args2 ]), usage = "INDIRECT"
166
+ data = np .uint32 ([0 , 0 , * self .draw_args1 , * self .draw_args2 ]),
167
+ usage = "INDIRECT" ,
162
168
)
163
169
self .draw_data_buffer_indexed = self .device .create_buffer_with_data (
164
170
data = np .uint32 ([0 , 0 , * self .draw_indexed_args1 , * self .draw_indexed_args2 ]),
@@ -181,7 +187,7 @@ def create_render_bundle_encoder(self, draw_function):
181
187
draw_function (render_bundle_encoder )
182
188
return render_bundle_encoder .finish ()
183
189
184
- def run_draw_test (self , expected_result , draw_function ):
190
+ def run_draw_test (self , draw_function , indexed , * , expected_result = None ):
185
191
encoder = self .device .create_command_encoder ()
186
192
encoder .clear_buffer (self .counter_buffer )
187
193
this_pass = encoder .begin_render_pass (** self .render_pass_descriptor )
@@ -194,12 +200,17 @@ def run_draw_test(self, expected_result, draw_function):
194
200
count = self .device .queue .read_buffer (self .counter_buffer ).cast ("i" )[0 ]
195
201
if count > MAX_INFO :
196
202
pytest .fail ("Too many data points written to output buffer" )
203
+ if count == 0 :
204
+ pytest .fail ("No data points written to output buffer" )
197
205
# Get the result as a series of tuples
198
206
info_view = self .device .queue .read_buffer (self .data_buffer , size = count * 2 * 4 )
199
- info = np .frombuffer (info_view , dtype = np .uint32 ).reshape (- 1 , 2 )
200
- info = [tuple (info [i ]) for i in range (len (info ))]
201
- info_set = set (info )
202
- assert len (info ) == len (info_set )
207
+ info = info_view .cast ("I" , (count , 2 )).tolist ()
208
+ info_set = set (tuple (x ) for x in info )
209
+ if expected_result is None :
210
+ if indexed :
211
+ expected_result = self .expected_result_draw_indexed
212
+ else :
213
+ expected_result = self .expected_result_draw
203
214
assert info_set == expected_result
204
215
205
216
@@ -217,30 +228,33 @@ def draw(encoder):
217
228
encoder .draw (* runner .draw_args1 )
218
229
encoder .draw (* runner .draw_args2 )
219
230
220
- runner .run_draw_test (runner . expected_result_draw , draw )
231
+ runner .run_draw_test (draw , False )
221
232
222
233
223
234
def test_draw_indirect (runner ):
224
235
def draw (encoder ):
225
236
encoder .draw_indirect (runner .draw_data_buffer , 8 )
226
237
encoder .draw_indirect (runner .draw_data_buffer , 8 + 16 )
227
238
228
- runner .run_draw_test (runner . expected_result_draw , draw )
239
+ runner .run_draw_test (draw , False )
229
240
230
241
231
242
def test_draw_mixed (runner ):
232
243
def draw (encoder ):
233
244
encoder .draw (* runner .draw_args1 )
234
245
encoder .draw_indirect (runner .draw_data_buffer , 8 + 16 )
235
246
236
- runner .run_draw_test (runner . expected_result_draw , draw )
247
+ runner .run_draw_test (draw , False )
237
248
238
249
239
250
def test_multi_draw_indirect (runner ):
251
+ if "multi-draw-indirect" not in runner .device .features :
252
+ pytest .skip ("Must have 'multi-draw-indirect' to run" )
253
+
240
254
def draw (encoder ):
241
255
multi_draw_indirect (encoder , runner .draw_data_buffer , offset = 8 , count = 2 )
242
256
243
- runner .run_draw_test (runner . expected_result_draw , draw )
257
+ runner .run_draw_test (draw , False )
244
258
245
259
246
260
def test_draw_via_encoder (runner ):
@@ -252,8 +266,7 @@ def draw(encoder):
252
266
for _ in range (2 ):
253
267
# We run this test twice to verify that encoders are reusable.
254
268
runner .run_draw_test (
255
- runner .expected_result_draw ,
256
- lambda encoder : encoder .execute_bundles ([render_bundle_encoder ]),
269
+ lambda encoder : encoder .execute_bundles ([render_bundle_encoder ]), False
257
270
)
258
271
259
272
@@ -269,10 +282,10 @@ def draw2(encoder):
269
282
render_bundle_encoder2 = runner .create_render_bundle_encoder (draw2 )
270
283
271
284
runner .run_draw_test (
272
- runner .expected_result_draw ,
273
285
lambda encoder : encoder .execute_bundles (
274
286
[render_bundle_encoder1 , render_bundle_encoder2 ]
275
287
),
288
+ False ,
276
289
)
277
290
278
291
@@ -281,32 +294,35 @@ def draw(encoder):
281
294
encoder .draw_indexed (* runner .draw_indexed_args1 )
282
295
encoder .draw_indexed (* runner .draw_indexed_args2 )
283
296
284
- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
297
+ runner .run_draw_test (draw , True )
285
298
286
299
287
300
def test_draw_indexed_indirect (runner ):
288
301
def draw (encoder ):
289
302
encoder .draw_indexed_indirect (runner .draw_data_buffer_indexed , 8 )
290
303
encoder .draw_indexed_indirect (runner .draw_data_buffer_indexed , 8 + 20 )
291
304
292
- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
305
+ runner .run_draw_test (draw , True )
293
306
294
307
295
308
def test_draw_indexed_mixed (runner ):
296
309
def draw (encoder ):
297
310
encoder .draw_indexed_indirect (runner .draw_data_buffer_indexed , 8 )
298
311
encoder .draw_indexed (* runner .draw_indexed_args2 )
299
312
300
- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
313
+ runner .run_draw_test (draw , True )
301
314
302
315
303
316
def test_multi_draw_indexed_indirect (runner ):
317
+ if "multi-draw-indirect" not in runner .device .features :
318
+ pytest .skip ("Must have 'multi-draw-indirect' to run" )
319
+
304
320
def draw (encoder ):
305
321
multi_draw_indexed_indirect (
306
322
encoder , runner .draw_data_buffer_indexed , offset = 8 , count = 2
307
323
)
308
324
309
- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
325
+ runner .run_draw_test (draw , True )
310
326
311
327
312
328
def test_draw_indexed_via_encoder (runner ):
@@ -317,8 +333,7 @@ def draw(encoder):
317
333
render_bundle_encoder = runner .create_render_bundle_encoder (draw )
318
334
for _ in range (2 ):
319
335
runner .run_draw_test (
320
- runner .expected_result_draw_indexed ,
321
- lambda encoder : encoder .execute_bundles ([render_bundle_encoder ]),
336
+ lambda encoder : encoder .execute_bundles ([render_bundle_encoder ]), True
322
337
)
323
338
324
339
0 commit comments