6767
6868
6969class 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
7172
7273 @classmethod
7374 def is_usable (cls ):
@@ -76,7 +77,11 @@ def is_usable(cls):
7677
7778 def __init__ (self ):
7879 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 )
8085 self .output_texture = self .device .create_texture (
8186 # Actual size is immaterial. Could just be 1x1
8287 size = [128 , 128 ],
@@ -158,7 +163,8 @@ def __init__(self):
158163 # We're going to want to try calling these draw functions from a buffer, and it
159164 # would be nice to test that these buffers have an offset
160165 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" ,
162168 )
163169 self .draw_data_buffer_indexed = self .device .create_buffer_with_data (
164170 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):
181187 draw_function (render_bundle_encoder )
182188 return render_bundle_encoder .finish ()
183189
184- def run_draw_test (self , expected_result , draw_function ):
190+ def run_draw_test (self , draw_function , indexed , * , expected_result = None ):
185191 encoder = self .device .create_command_encoder ()
186192 encoder .clear_buffer (self .counter_buffer )
187193 this_pass = encoder .begin_render_pass (** self .render_pass_descriptor )
@@ -194,12 +200,17 @@ def run_draw_test(self, expected_result, draw_function):
194200 count = self .device .queue .read_buffer (self .counter_buffer ).cast ("i" )[0 ]
195201 if count > MAX_INFO :
196202 pytest .fail ("Too many data points written to output buffer" )
203+ if count == 0 :
204+ pytest .fail ("No data points written to output buffer" )
197205 # Get the result as a series of tuples
198206 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
203214 assert info_set == expected_result
204215
205216
@@ -217,30 +228,33 @@ def draw(encoder):
217228 encoder .draw (* runner .draw_args1 )
218229 encoder .draw (* runner .draw_args2 )
219230
220- runner .run_draw_test (runner . expected_result_draw , draw )
231+ runner .run_draw_test (draw , False )
221232
222233
223234def test_draw_indirect (runner ):
224235 def draw (encoder ):
225236 encoder .draw_indirect (runner .draw_data_buffer , 8 )
226237 encoder .draw_indirect (runner .draw_data_buffer , 8 + 16 )
227238
228- runner .run_draw_test (runner . expected_result_draw , draw )
239+ runner .run_draw_test (draw , False )
229240
230241
231242def test_draw_mixed (runner ):
232243 def draw (encoder ):
233244 encoder .draw (* runner .draw_args1 )
234245 encoder .draw_indirect (runner .draw_data_buffer , 8 + 16 )
235246
236- runner .run_draw_test (runner . expected_result_draw , draw )
247+ runner .run_draw_test (draw , False )
237248
238249
239250def 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+
240254 def draw (encoder ):
241255 multi_draw_indirect (encoder , runner .draw_data_buffer , offset = 8 , count = 2 )
242256
243- runner .run_draw_test (runner . expected_result_draw , draw )
257+ runner .run_draw_test (draw , False )
244258
245259
246260def test_draw_via_encoder (runner ):
@@ -252,8 +266,7 @@ def draw(encoder):
252266 for _ in range (2 ):
253267 # We run this test twice to verify that encoders are reusable.
254268 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
257270 )
258271
259272
@@ -269,10 +282,10 @@ def draw2(encoder):
269282 render_bundle_encoder2 = runner .create_render_bundle_encoder (draw2 )
270283
271284 runner .run_draw_test (
272- runner .expected_result_draw ,
273285 lambda encoder : encoder .execute_bundles (
274286 [render_bundle_encoder1 , render_bundle_encoder2 ]
275287 ),
288+ False ,
276289 )
277290
278291
@@ -281,32 +294,35 @@ def draw(encoder):
281294 encoder .draw_indexed (* runner .draw_indexed_args1 )
282295 encoder .draw_indexed (* runner .draw_indexed_args2 )
283296
284- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
297+ runner .run_draw_test (draw , True )
285298
286299
287300def test_draw_indexed_indirect (runner ):
288301 def draw (encoder ):
289302 encoder .draw_indexed_indirect (runner .draw_data_buffer_indexed , 8 )
290303 encoder .draw_indexed_indirect (runner .draw_data_buffer_indexed , 8 + 20 )
291304
292- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
305+ runner .run_draw_test (draw , True )
293306
294307
295308def test_draw_indexed_mixed (runner ):
296309 def draw (encoder ):
297310 encoder .draw_indexed_indirect (runner .draw_data_buffer_indexed , 8 )
298311 encoder .draw_indexed (* runner .draw_indexed_args2 )
299312
300- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
313+ runner .run_draw_test (draw , True )
301314
302315
303316def 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+
304320 def draw (encoder ):
305321 multi_draw_indexed_indirect (
306322 encoder , runner .draw_data_buffer_indexed , offset = 8 , count = 2
307323 )
308324
309- runner .run_draw_test (runner . expected_result_draw_indexed , draw )
325+ runner .run_draw_test (draw , True )
310326
311327
312328def test_draw_indexed_via_encoder (runner ):
@@ -317,8 +333,7 @@ def draw(encoder):
317333 render_bundle_encoder = runner .create_render_bundle_encoder (draw )
318334 for _ in range (2 ):
319335 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
322337 )
323338
324339
0 commit comments