• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/transform/vertex_pulling.h"
16 
17 #include <utility>
18 
19 #include "src/transform/test_helper.h"
20 
21 namespace tint {
22 namespace transform {
23 namespace {
24 
25 using VertexPullingTest = TransformTest;
26 
TEST_F(VertexPullingTest,Error_NoEntryPoint)27 TEST_F(VertexPullingTest, Error_NoEntryPoint) {
28   auto* src = "";
29 
30   auto* expect = "error: Vertex stage entry point not found";
31 
32   DataMap data;
33   data.Add<VertexPulling::Config>();
34   auto got = Run<VertexPulling>(src, data);
35 
36   EXPECT_EQ(expect, str(got));
37 }
38 
TEST_F(VertexPullingTest,Error_InvalidEntryPoint)39 TEST_F(VertexPullingTest, Error_InvalidEntryPoint) {
40   auto* src = R"(
41 [[stage(vertex)]]
42 fn main() -> [[builtin(position)]] vec4<f32> {
43   return vec4<f32>();
44 }
45 )";
46 
47   auto* expect = "error: Vertex stage entry point not found";
48 
49   VertexPulling::Config cfg;
50   cfg.entry_point_name = "_";
51 
52   DataMap data;
53   data.Add<VertexPulling::Config>(cfg);
54   auto got = Run<VertexPulling>(src, data);
55 
56   EXPECT_EQ(expect, str(got));
57 }
58 
TEST_F(VertexPullingTest,Error_EntryPointWrongStage)59 TEST_F(VertexPullingTest, Error_EntryPointWrongStage) {
60   auto* src = R"(
61 [[stage(fragment)]]
62 fn main() {}
63 )";
64 
65   auto* expect = "error: Vertex stage entry point not found";
66 
67   VertexPulling::Config cfg;
68   cfg.entry_point_name = "main";
69 
70   DataMap data;
71   data.Add<VertexPulling::Config>(cfg);
72   auto got = Run<VertexPulling>(src, data);
73 
74   EXPECT_EQ(expect, str(got));
75 }
76 
TEST_F(VertexPullingTest,Error_BadStride)77 TEST_F(VertexPullingTest, Error_BadStride) {
78   auto* src = R"(
79 [[stage(vertex)]]
80 fn main([[location(0)]] var_a : f32) -> [[builtin(position)]] vec4<f32> {
81   return vec4<f32>(var_a, 0.0, 0.0, 1.0);
82 }
83 )";
84 
85   auto* expect =
86       "error: WebGPU requires that vertex stride must be a multiple of 4 "
87       "bytes, but VertexPulling array stride for buffer 0 was 15 bytes";
88 
89   VertexPulling::Config cfg;
90   cfg.vertex_state = {
91       {{15, VertexStepMode::kVertex, {{VertexFormat::kFloat32, 0, 0}}}}};
92   cfg.entry_point_name = "main";
93 
94   DataMap data;
95   data.Add<VertexPulling::Config>(cfg);
96   auto got = Run<VertexPulling>(src, data);
97 
98   EXPECT_EQ(expect, str(got));
99 }
100 
TEST_F(VertexPullingTest,BasicModule)101 TEST_F(VertexPullingTest, BasicModule) {
102   auto* src = R"(
103 [[stage(vertex)]]
104 fn main() -> [[builtin(position)]] vec4<f32> {
105   return vec4<f32>();
106 }
107 )";
108 
109   auto* expect = R"(
110 [[block]]
111 struct TintVertexData {
112   tint_vertex_data : [[stride(4)]] array<u32>;
113 };
114 
115 [[stage(vertex)]]
116 fn main() -> [[builtin(position)]] vec4<f32> {
117   return vec4<f32>();
118 }
119 )";
120 
121   VertexPulling::Config cfg;
122   cfg.entry_point_name = "main";
123 
124   DataMap data;
125   data.Add<VertexPulling::Config>(cfg);
126   auto got = Run<VertexPulling>(src, data);
127 
128   EXPECT_EQ(expect, str(got));
129 }
130 
TEST_F(VertexPullingTest,OneAttribute)131 TEST_F(VertexPullingTest, OneAttribute) {
132   auto* src = R"(
133 [[stage(vertex)]]
134 fn main([[location(0)]] var_a : f32) -> [[builtin(position)]] vec4<f32> {
135   return vec4<f32>(var_a, 0.0, 0.0, 1.0);
136 }
137 )";
138 
139   auto* expect = R"(
140 [[block]]
141 struct TintVertexData {
142   tint_vertex_data : [[stride(4)]] array<u32>;
143 };
144 
145 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
146 
147 [[stage(vertex)]]
148 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
149   var var_a : f32;
150   {
151     let buffer_array_base_0 = tint_pulling_vertex_index;
152     var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
153   }
154   return vec4<f32>(var_a, 0.0, 0.0, 1.0);
155 }
156 )";
157 
158   VertexPulling::Config cfg;
159   cfg.vertex_state = {
160       {{4, VertexStepMode::kVertex, {{VertexFormat::kFloat32, 0, 0}}}}};
161   cfg.entry_point_name = "main";
162 
163   DataMap data;
164   data.Add<VertexPulling::Config>(cfg);
165   auto got = Run<VertexPulling>(src, data);
166 
167   EXPECT_EQ(expect, str(got));
168 }
169 
TEST_F(VertexPullingTest,OneInstancedAttribute)170 TEST_F(VertexPullingTest, OneInstancedAttribute) {
171   auto* src = R"(
172 [[stage(vertex)]]
173 fn main([[location(0)]] var_a : f32) -> [[builtin(position)]] vec4<f32> {
174   return vec4<f32>(var_a, 0.0, 0.0, 1.0);
175 }
176 )";
177 
178   auto* expect = R"(
179 [[block]]
180 struct TintVertexData {
181   tint_vertex_data : [[stride(4)]] array<u32>;
182 };
183 
184 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
185 
186 [[stage(vertex)]]
187 fn main([[builtin(instance_index)]] tint_pulling_instance_index : u32) -> [[builtin(position)]] vec4<f32> {
188   var var_a : f32;
189   {
190     let buffer_array_base_0 = tint_pulling_instance_index;
191     var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
192   }
193   return vec4<f32>(var_a, 0.0, 0.0, 1.0);
194 }
195 )";
196 
197   VertexPulling::Config cfg;
198   cfg.vertex_state = {
199       {{4, VertexStepMode::kInstance, {{VertexFormat::kFloat32, 0, 0}}}}};
200   cfg.entry_point_name = "main";
201 
202   DataMap data;
203   data.Add<VertexPulling::Config>(cfg);
204   auto got = Run<VertexPulling>(src, data);
205 
206   EXPECT_EQ(expect, str(got));
207 }
208 
TEST_F(VertexPullingTest,OneAttributeDifferentOutputSet)209 TEST_F(VertexPullingTest, OneAttributeDifferentOutputSet) {
210   auto* src = R"(
211 [[stage(vertex)]]
212 fn main([[location(0)]] var_a : f32) -> [[builtin(position)]] vec4<f32> {
213   return vec4<f32>(var_a, 0.0, 0.0, 1.0);
214 }
215 )";
216 
217   auto* expect = R"(
218 [[block]]
219 struct TintVertexData {
220   tint_vertex_data : [[stride(4)]] array<u32>;
221 };
222 
223 [[binding(0), group(5)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
224 
225 [[stage(vertex)]]
226 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
227   var var_a : f32;
228   {
229     let buffer_array_base_0 = tint_pulling_vertex_index;
230     var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
231   }
232   return vec4<f32>(var_a, 0.0, 0.0, 1.0);
233 }
234 )";
235 
236   VertexPulling::Config cfg;
237   cfg.vertex_state = {
238       {{4, VertexStepMode::kVertex, {{VertexFormat::kFloat32, 0, 0}}}}};
239   cfg.pulling_group = 5;
240   cfg.entry_point_name = "main";
241 
242   DataMap data;
243   data.Add<VertexPulling::Config>(cfg);
244   auto got = Run<VertexPulling>(src, data);
245 
246   EXPECT_EQ(expect, str(got));
247 }
248 
TEST_F(VertexPullingTest,OneAttribute_Struct)249 TEST_F(VertexPullingTest, OneAttribute_Struct) {
250   auto* src = R"(
251 struct Inputs {
252   [[location(0)]] var_a : f32;
253 };
254 
255 [[stage(vertex)]]
256 fn main(inputs : Inputs) -> [[builtin(position)]] vec4<f32> {
257   return vec4<f32>(inputs.var_a, 0.0, 0.0, 1.0);
258 }
259 )";
260 
261   auto* expect = R"(
262 [[block]]
263 struct TintVertexData {
264   tint_vertex_data : [[stride(4)]] array<u32>;
265 };
266 
267 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
268 
269 struct Inputs {
270   [[location(0)]]
271   var_a : f32;
272 };
273 
274 [[stage(vertex)]]
275 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
276   var inputs : Inputs;
277   {
278     let buffer_array_base_0 = tint_pulling_vertex_index;
279     inputs.var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
280   }
281   return vec4<f32>(inputs.var_a, 0.0, 0.0, 1.0);
282 }
283 )";
284 
285   VertexPulling::Config cfg;
286   cfg.vertex_state = {
287       {{4, VertexStepMode::kVertex, {{VertexFormat::kFloat32, 0, 0}}}}};
288   cfg.entry_point_name = "main";
289 
290   DataMap data;
291   data.Add<VertexPulling::Config>(cfg);
292   auto got = Run<VertexPulling>(src, data);
293 
294   EXPECT_EQ(expect, str(got));
295 }
296 
297 // We expect the transform to use an existing builtin variables if it finds them
TEST_F(VertexPullingTest,ExistingVertexIndexAndInstanceIndex)298 TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) {
299   auto* src = R"(
300 [[stage(vertex)]]
301 fn main([[location(0)]] var_a : f32,
302         [[location(1)]] var_b : f32,
303         [[builtin(vertex_index)]] custom_vertex_index : u32,
304         [[builtin(instance_index)]] custom_instance_index : u32
305         ) -> [[builtin(position)]] vec4<f32> {
306   return vec4<f32>(var_a, var_b, 0.0, 1.0);
307 }
308 )";
309 
310   auto* expect = R"(
311 [[block]]
312 struct TintVertexData {
313   tint_vertex_data : [[stride(4)]] array<u32>;
314 };
315 
316 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
317 
318 [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
319 
320 [[stage(vertex)]]
321 fn main([[builtin(vertex_index)]] custom_vertex_index : u32, [[builtin(instance_index)]] custom_instance_index : u32) -> [[builtin(position)]] vec4<f32> {
322   var var_a : f32;
323   var var_b : f32;
324   {
325     let buffer_array_base_0 = custom_vertex_index;
326     var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
327     let buffer_array_base_1 = custom_instance_index;
328     var_b = bitcast<f32>(tint_pulling_vertex_buffer_1.tint_vertex_data[buffer_array_base_1]);
329   }
330   return vec4<f32>(var_a, var_b, 0.0, 1.0);
331 }
332 )";
333 
334   VertexPulling::Config cfg;
335   cfg.vertex_state = {{
336       {
337           4,
338           VertexStepMode::kVertex,
339           {{VertexFormat::kFloat32, 0, 0}},
340       },
341       {
342           4,
343           VertexStepMode::kInstance,
344           {{VertexFormat::kFloat32, 0, 1}},
345       },
346   }};
347   cfg.entry_point_name = "main";
348 
349   DataMap data;
350   data.Add<VertexPulling::Config>(cfg);
351   auto got = Run<VertexPulling>(src, data);
352 
353   EXPECT_EQ(expect, str(got));
354 }
355 
TEST_F(VertexPullingTest,ExistingVertexIndexAndInstanceIndex_Struct)356 TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex_Struct) {
357   auto* src = R"(
358 struct Inputs {
359   [[location(0)]] var_a : f32;
360   [[location(1)]] var_b : f32;
361   [[builtin(vertex_index)]] custom_vertex_index : u32;
362   [[builtin(instance_index)]] custom_instance_index : u32;
363 };
364 
365 [[stage(vertex)]]
366 fn main(inputs : Inputs) -> [[builtin(position)]] vec4<f32> {
367   return vec4<f32>(inputs.var_a, inputs.var_b, 0.0, 1.0);
368 }
369 )";
370 
371   auto* expect = R"(
372 [[block]]
373 struct TintVertexData {
374   tint_vertex_data : [[stride(4)]] array<u32>;
375 };
376 
377 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
378 
379 [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
380 
381 struct tint_symbol {
382   [[builtin(vertex_index)]]
383   custom_vertex_index : u32;
384   [[builtin(instance_index)]]
385   custom_instance_index : u32;
386 };
387 
388 struct Inputs {
389   [[location(0)]]
390   var_a : f32;
391   [[location(1)]]
392   var_b : f32;
393   [[builtin(vertex_index)]]
394   custom_vertex_index : u32;
395   [[builtin(instance_index)]]
396   custom_instance_index : u32;
397 };
398 
399 [[stage(vertex)]]
400 fn main(tint_symbol_1 : tint_symbol) -> [[builtin(position)]] vec4<f32> {
401   var inputs : Inputs;
402   inputs.custom_vertex_index = tint_symbol_1.custom_vertex_index;
403   inputs.custom_instance_index = tint_symbol_1.custom_instance_index;
404   {
405     let buffer_array_base_0 = inputs.custom_vertex_index;
406     inputs.var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
407     let buffer_array_base_1 = inputs.custom_instance_index;
408     inputs.var_b = bitcast<f32>(tint_pulling_vertex_buffer_1.tint_vertex_data[buffer_array_base_1]);
409   }
410   return vec4<f32>(inputs.var_a, inputs.var_b, 0.0, 1.0);
411 }
412 )";
413 
414   VertexPulling::Config cfg;
415   cfg.vertex_state = {{
416       {
417           4,
418           VertexStepMode::kVertex,
419           {{VertexFormat::kFloat32, 0, 0}},
420       },
421       {
422           4,
423           VertexStepMode::kInstance,
424           {{VertexFormat::kFloat32, 0, 1}},
425       },
426   }};
427   cfg.entry_point_name = "main";
428 
429   DataMap data;
430   data.Add<VertexPulling::Config>(cfg);
431   auto got = Run<VertexPulling>(src, data);
432 
433   EXPECT_EQ(expect, str(got));
434 }
435 
TEST_F(VertexPullingTest,ExistingVertexIndexAndInstanceIndex_SeparateStruct)436 TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex_SeparateStruct) {
437   auto* src = R"(
438 struct Inputs {
439   [[location(0)]] var_a : f32;
440   [[location(1)]] var_b : f32;
441 };
442 
443 struct Indices {
444   [[builtin(vertex_index)]] custom_vertex_index : u32;
445   [[builtin(instance_index)]] custom_instance_index : u32;
446 };
447 
448 [[stage(vertex)]]
449 fn main(inputs : Inputs, indices : Indices) -> [[builtin(position)]] vec4<f32> {
450   return vec4<f32>(inputs.var_a, inputs.var_b, 0.0, 1.0);
451 }
452 )";
453 
454   auto* expect = R"(
455 [[block]]
456 struct TintVertexData {
457   tint_vertex_data : [[stride(4)]] array<u32>;
458 };
459 
460 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
461 
462 [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
463 
464 struct Inputs {
465   [[location(0)]]
466   var_a : f32;
467   [[location(1)]]
468   var_b : f32;
469 };
470 
471 struct Indices {
472   [[builtin(vertex_index)]]
473   custom_vertex_index : u32;
474   [[builtin(instance_index)]]
475   custom_instance_index : u32;
476 };
477 
478 [[stage(vertex)]]
479 fn main(indices : Indices) -> [[builtin(position)]] vec4<f32> {
480   var inputs : Inputs;
481   {
482     let buffer_array_base_0 = indices.custom_vertex_index;
483     inputs.var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
484     let buffer_array_base_1 = indices.custom_instance_index;
485     inputs.var_b = bitcast<f32>(tint_pulling_vertex_buffer_1.tint_vertex_data[buffer_array_base_1]);
486   }
487   return vec4<f32>(inputs.var_a, inputs.var_b, 0.0, 1.0);
488 }
489 )";
490 
491   VertexPulling::Config cfg;
492   cfg.vertex_state = {{
493       {
494           4,
495           VertexStepMode::kVertex,
496           {{VertexFormat::kFloat32, 0, 0}},
497       },
498       {
499           4,
500           VertexStepMode::kInstance,
501           {{VertexFormat::kFloat32, 0, 1}},
502       },
503   }};
504   cfg.entry_point_name = "main";
505 
506   DataMap data;
507   data.Add<VertexPulling::Config>(cfg);
508   auto got = Run<VertexPulling>(src, data);
509 
510   EXPECT_EQ(expect, str(got));
511 }
512 
TEST_F(VertexPullingTest,TwoAttributesSameBuffer)513 TEST_F(VertexPullingTest, TwoAttributesSameBuffer) {
514   auto* src = R"(
515 [[stage(vertex)]]
516 fn main([[location(0)]] var_a : f32,
517         [[location(1)]] var_b : vec4<f32>) -> [[builtin(position)]] vec4<f32> {
518   return vec4<f32>();
519 }
520 )";
521 
522   auto* expect = R"(
523 [[block]]
524 struct TintVertexData {
525   tint_vertex_data : [[stride(4)]] array<u32>;
526 };
527 
528 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
529 
530 [[stage(vertex)]]
531 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
532   var var_a : f32;
533   var var_b : vec4<f32>;
534   {
535     let buffer_array_base_0 = (tint_pulling_vertex_index * 4u);
536     var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]);
537     var_b = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 1u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 2u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 3u)]));
538   }
539   return vec4<f32>();
540 }
541 )";
542 
543   VertexPulling::Config cfg;
544   cfg.vertex_state = {
545       {{16,
546         VertexStepMode::kVertex,
547         {{VertexFormat::kFloat32, 0, 0}, {VertexFormat::kFloat32x4, 0, 1}}}}};
548   cfg.entry_point_name = "main";
549 
550   DataMap data;
551   data.Add<VertexPulling::Config>(cfg);
552   auto got = Run<VertexPulling>(src, data);
553 
554   EXPECT_EQ(expect, str(got));
555 }
556 
TEST_F(VertexPullingTest,FloatVectorAttributes)557 TEST_F(VertexPullingTest, FloatVectorAttributes) {
558   auto* src = R"(
559 [[stage(vertex)]]
560 fn main([[location(0)]] var_a : vec2<f32>,
561         [[location(1)]] var_b : vec3<f32>,
562         [[location(2)]] var_c : vec4<f32>
563         ) -> [[builtin(position)]] vec4<f32> {
564   return vec4<f32>();
565 }
566 )";
567 
568   auto* expect = R"(
569 [[block]]
570 struct TintVertexData {
571   tint_vertex_data : [[stride(4)]] array<u32>;
572 };
573 
574 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
575 
576 [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
577 
578 [[binding(2), group(4)]] var<storage, read> tint_pulling_vertex_buffer_2 : TintVertexData;
579 
580 [[stage(vertex)]]
581 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
582   var var_a : vec2<f32>;
583   var var_b : vec3<f32>;
584   var var_c : vec4<f32>;
585   {
586     let buffer_array_base_0 = (tint_pulling_vertex_index * 2u);
587     var_a = vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[buffer_array_base_0]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 1u)]));
588     let buffer_array_base_1 = (tint_pulling_vertex_index * 3u);
589     var_b = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_1.tint_vertex_data[buffer_array_base_1]), bitcast<f32>(tint_pulling_vertex_buffer_1.tint_vertex_data[(buffer_array_base_1 + 1u)]), bitcast<f32>(tint_pulling_vertex_buffer_1.tint_vertex_data[(buffer_array_base_1 + 2u)]));
590     let buffer_array_base_2 = (tint_pulling_vertex_index * 4u);
591     var_c = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_2.tint_vertex_data[buffer_array_base_2]), bitcast<f32>(tint_pulling_vertex_buffer_2.tint_vertex_data[(buffer_array_base_2 + 1u)]), bitcast<f32>(tint_pulling_vertex_buffer_2.tint_vertex_data[(buffer_array_base_2 + 2u)]), bitcast<f32>(tint_pulling_vertex_buffer_2.tint_vertex_data[(buffer_array_base_2 + 3u)]));
592   }
593   return vec4<f32>();
594 }
595 )";
596 
597   VertexPulling::Config cfg;
598   cfg.vertex_state = {{
599       {8, VertexStepMode::kVertex, {{VertexFormat::kFloat32x2, 0, 0}}},
600       {12, VertexStepMode::kVertex, {{VertexFormat::kFloat32x3, 0, 1}}},
601       {16, VertexStepMode::kVertex, {{VertexFormat::kFloat32x4, 0, 2}}},
602   }};
603   cfg.entry_point_name = "main";
604 
605   DataMap data;
606   data.Add<VertexPulling::Config>(cfg);
607   auto got = Run<VertexPulling>(src, data);
608 
609   EXPECT_EQ(expect, str(got));
610 }
611 
TEST_F(VertexPullingTest,AttemptSymbolCollision)612 TEST_F(VertexPullingTest, AttemptSymbolCollision) {
613   auto* src = R"(
614 [[stage(vertex)]]
615 fn main([[location(0)]] var_a : f32,
616         [[location(1)]] var_b : vec4<f32>) -> [[builtin(position)]] vec4<f32> {
617   var tint_pulling_vertex_index : i32;
618   var tint_pulling_vertex_buffer_0 : i32;
619   var tint_vertex_data : i32;
620   var tint_pulling_pos : i32;
621   return vec4<f32>();
622 }
623 )";
624 
625   auto* expect = R"(
626 [[block]]
627 struct TintVertexData {
628   tint_vertex_data_1 : [[stride(4)]] array<u32>;
629 };
630 
631 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0_1 : TintVertexData;
632 
633 [[stage(vertex)]]
634 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index_1 : u32) -> [[builtin(position)]] vec4<f32> {
635   var var_a : f32;
636   var var_b : vec4<f32>;
637   {
638     let buffer_array_base_0 = (tint_pulling_vertex_index_1 * 4u);
639     var_a = bitcast<f32>(tint_pulling_vertex_buffer_0_1.tint_vertex_data_1[buffer_array_base_0]);
640     var_b = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0_1.tint_vertex_data_1[buffer_array_base_0]), bitcast<f32>(tint_pulling_vertex_buffer_0_1.tint_vertex_data_1[(buffer_array_base_0 + 1u)]), bitcast<f32>(tint_pulling_vertex_buffer_0_1.tint_vertex_data_1[(buffer_array_base_0 + 2u)]), bitcast<f32>(tint_pulling_vertex_buffer_0_1.tint_vertex_data_1[(buffer_array_base_0 + 3u)]));
641   }
642   var tint_pulling_vertex_index : i32;
643   var tint_pulling_vertex_buffer_0 : i32;
644   var tint_vertex_data : i32;
645   var tint_pulling_pos : i32;
646   return vec4<f32>();
647 }
648 )";
649 
650   VertexPulling::Config cfg;
651   cfg.vertex_state = {
652       {{16,
653         VertexStepMode::kVertex,
654         {{VertexFormat::kFloat32, 0, 0}, {VertexFormat::kFloat32x4, 0, 1}}}}};
655   cfg.entry_point_name = "main";
656 
657   DataMap data;
658   data.Add<VertexPulling::Config>(cfg);
659   auto got = Run<VertexPulling>(src, std::move(data));
660 
661   EXPECT_EQ(expect, str(got));
662 }
663 
TEST_F(VertexPullingTest,FormatsAligned)664 TEST_F(VertexPullingTest, FormatsAligned) {
665   auto* src = R"(
666 [[stage(vertex)]]
667 fn main(
668     [[location(0)]] uint8x2 : vec2<u32>,
669     [[location(1)]] uint8x4 : vec4<u32>,
670     [[location(2)]] sint8x2 : vec2<i32>,
671     [[location(3)]] sint8x4 : vec4<i32>,
672     [[location(4)]] unorm8x2 : vec2<f32>,
673     [[location(5)]] unorm8x4 : vec4<f32>,
674     [[location(6)]] snorm8x2 : vec2<f32>,
675     [[location(7)]] snorm8x4 : vec4<f32>,
676     [[location(8)]] uint16x2 : vec2<u32>,
677     [[location(9)]] uint16x4 : vec4<u32>,
678     [[location(10)]] sint16x2 : vec2<i32>,
679     [[location(11)]] sint16x4 : vec4<i32>,
680     [[location(12)]] unorm16x2 : vec2<f32>,
681     [[location(13)]] unorm16x4 : vec4<f32>,
682     [[location(14)]] snorm16x2 : vec2<f32>,
683     [[location(15)]] snorm16x4 : vec4<f32>,
684     [[location(16)]] float16x2 : vec2<f32>,
685     [[location(17)]] float16x4 : vec4<f32>,
686     [[location(18)]] float32 : f32,
687     [[location(19)]] float32x2 : vec2<f32>,
688     [[location(20)]] float32x3 : vec3<f32>,
689     [[location(21)]] float32x4 : vec4<f32>,
690     [[location(22)]] uint32 : u32,
691     [[location(23)]] uint32x2 : vec2<u32>,
692     [[location(24)]] uint32x3 : vec3<u32>,
693     [[location(25)]] uint32x4 : vec4<u32>,
694     [[location(26)]] sint32 : i32,
695     [[location(27)]] sint32x2 : vec2<i32>,
696     [[location(28)]] sint32x3 : vec3<i32>,
697     [[location(29)]] sint32x4 : vec4<i32>
698   ) -> [[builtin(position)]] vec4<f32> {
699   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
700 }
701 )";
702 
703   auto* expect = R"(
704 [[block]]
705 struct TintVertexData {
706   tint_vertex_data : [[stride(4)]] array<u32>;
707 };
708 
709 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
710 
711 [[stage(vertex)]]
712 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
713   var uint8x2 : vec2<u32>;
714   var uint8x4 : vec4<u32>;
715   var sint8x2 : vec2<i32>;
716   var sint8x4 : vec4<i32>;
717   var unorm8x2 : vec2<f32>;
718   var unorm8x4 : vec4<f32>;
719   var snorm8x2 : vec2<f32>;
720   var snorm8x4 : vec4<f32>;
721   var uint16x2 : vec2<u32>;
722   var uint16x4 : vec4<u32>;
723   var sint16x2 : vec2<i32>;
724   var sint16x4 : vec4<i32>;
725   var unorm16x2 : vec2<f32>;
726   var unorm16x4 : vec4<f32>;
727   var snorm16x2 : vec2<f32>;
728   var snorm16x4 : vec4<f32>;
729   var float16x2 : vec2<f32>;
730   var float16x4 : vec4<f32>;
731   var float32 : f32;
732   var float32x2 : vec2<f32>;
733   var float32x3 : vec3<f32>;
734   var float32x4 : vec4<f32>;
735   var uint32 : u32;
736   var uint32x2 : vec2<u32>;
737   var uint32x3 : vec3<u32>;
738   var uint32x4 : vec4<u32>;
739   var sint32 : i32;
740   var sint32x2 : vec2<i32>;
741   var sint32x3 : vec3<i32>;
742   var sint32x4 : vec4<i32>;
743   {
744     let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
745     uint8x2 = ((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
746     uint8x4 = ((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
747     sint8x2 = ((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
748     sint8x4 = ((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
749     unorm8x2 = unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy;
750     unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
751     snorm8x2 = unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy;
752     snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
753     uint16x2 = ((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
754     uint16x4 = ((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
755     sint16x2 = ((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
756     sint16x4 = ((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
757     unorm16x2 = unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
758     unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
759     snorm16x2 = unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
760     snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
761     float16x2 = unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
762     float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
763     float32 = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
764     float32x2 = vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
765     float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]));
766     float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]));
767     uint32 = tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)];
768     uint32x2 = vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]);
769     uint32x3 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]);
770     uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]);
771     sint32 = bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
772     sint32x2 = vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
773     sint32x3 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]));
774     sint32x4 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]));
775   }
776   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
777 }
778 )";
779 
780   VertexPulling::Config cfg;
781   cfg.vertex_state = {{{256,
782                         VertexStepMode::kVertex,
783                         {
784                             {VertexFormat::kUint8x2, 64, 0},
785                             {VertexFormat::kUint8x4, 64, 1},
786                             {VertexFormat::kSint8x2, 64, 2},
787                             {VertexFormat::kSint8x4, 64, 3},
788                             {VertexFormat::kUnorm8x2, 64, 4},
789                             {VertexFormat::kUnorm8x4, 64, 5},
790                             {VertexFormat::kSnorm8x2, 64, 6},
791                             {VertexFormat::kSnorm8x4, 64, 7},
792                             {VertexFormat::kUint16x2, 64, 8},
793                             {VertexFormat::kUint16x4, 64, 9},
794                             {VertexFormat::kSint16x2, 64, 10},
795                             {VertexFormat::kSint16x4, 64, 11},
796                             {VertexFormat::kUnorm16x2, 64, 12},
797                             {VertexFormat::kUnorm16x4, 64, 13},
798                             {VertexFormat::kSnorm16x2, 64, 14},
799                             {VertexFormat::kSnorm16x4, 64, 15},
800                             {VertexFormat::kFloat16x2, 64, 16},
801                             {VertexFormat::kFloat16x4, 64, 17},
802                             {VertexFormat::kFloat32, 64, 18},
803                             {VertexFormat::kFloat32x2, 64, 19},
804                             {VertexFormat::kFloat32x3, 64, 20},
805                             {VertexFormat::kFloat32x4, 64, 21},
806                             {VertexFormat::kUint32, 64, 22},
807                             {VertexFormat::kUint32x2, 64, 23},
808                             {VertexFormat::kUint32x3, 64, 24},
809                             {VertexFormat::kUint32x4, 64, 25},
810                             {VertexFormat::kSint32, 64, 26},
811                             {VertexFormat::kSint32x2, 64, 27},
812                             {VertexFormat::kSint32x3, 64, 28},
813                             {VertexFormat::kSint32x4, 64, 29},
814                         }}}};
815   cfg.entry_point_name = "main";
816 
817   DataMap data;
818   data.Add<VertexPulling::Config>(cfg);
819   auto got = Run<VertexPulling>(src, data);
820 
821   EXPECT_EQ(expect, str(got));
822 }
823 
TEST_F(VertexPullingTest,FormatsStrideUnaligned)824 TEST_F(VertexPullingTest, FormatsStrideUnaligned) {
825   auto* src = R"(
826 [[stage(vertex)]]
827 fn main(
828     [[location(0)]] uint8x2 : vec2<u32>,
829     [[location(1)]] uint8x4 : vec4<u32>,
830     [[location(2)]] sint8x2 : vec2<i32>,
831     [[location(3)]] sint8x4 : vec4<i32>,
832     [[location(4)]] unorm8x2 : vec2<f32>,
833     [[location(5)]] unorm8x4 : vec4<f32>,
834     [[location(6)]] snorm8x2 : vec2<f32>,
835     [[location(7)]] snorm8x4 : vec4<f32>,
836     [[location(8)]] uint16x2 : vec2<u32>,
837     [[location(9)]] uint16x4 : vec4<u32>,
838     [[location(10)]] sint16x2 : vec2<i32>,
839     [[location(11)]] sint16x4 : vec4<i32>,
840     [[location(12)]] unorm16x2 : vec2<f32>,
841     [[location(13)]] unorm16x4 : vec4<f32>,
842     [[location(14)]] snorm16x2 : vec2<f32>,
843     [[location(15)]] snorm16x4 : vec4<f32>,
844     [[location(16)]] float16x2 : vec2<f32>,
845     [[location(17)]] float16x4 : vec4<f32>,
846     [[location(18)]] float32 : f32,
847     [[location(19)]] float32x2 : vec2<f32>,
848     [[location(20)]] float32x3 : vec3<f32>,
849     [[location(21)]] float32x4 : vec4<f32>,
850     [[location(22)]] uint32 : u32,
851     [[location(23)]] uint32x2 : vec2<u32>,
852     [[location(24)]] uint32x3 : vec3<u32>,
853     [[location(25)]] uint32x4 : vec4<u32>,
854     [[location(26)]] sint32 : i32,
855     [[location(27)]] sint32x2 : vec2<i32>,
856     [[location(28)]] sint32x3 : vec3<i32>,
857     [[location(29)]] sint32x4 : vec4<i32>
858   ) -> [[builtin(position)]] vec4<f32> {
859   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
860 }
861 )";
862 
863   auto* expect =
864       R"(
865 [[block]]
866 struct TintVertexData {
867   tint_vertex_data : [[stride(4)]] array<u32>;
868 };
869 
870 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
871 
872 [[stage(vertex)]]
873 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
874   var uint8x2 : vec2<u32>;
875   var uint8x4 : vec4<u32>;
876   var sint8x2 : vec2<i32>;
877   var sint8x4 : vec4<i32>;
878   var unorm8x2 : vec2<f32>;
879   var unorm8x4 : vec4<f32>;
880   var snorm8x2 : vec2<f32>;
881   var snorm8x4 : vec4<f32>;
882   var uint16x2 : vec2<u32>;
883   var uint16x4 : vec4<u32>;
884   var sint16x2 : vec2<i32>;
885   var sint16x4 : vec4<i32>;
886   var unorm16x2 : vec2<f32>;
887   var unorm16x4 : vec4<f32>;
888   var snorm16x2 : vec2<f32>;
889   var snorm16x4 : vec4<f32>;
890   var float16x2 : vec2<f32>;
891   var float16x4 : vec4<f32>;
892   var float32 : f32;
893   var float32x2 : vec2<f32>;
894   var float32x3 : vec3<f32>;
895   var float32x4 : vec4<f32>;
896   var uint32 : u32;
897   var uint32x2 : vec2<u32>;
898   var uint32x3 : vec3<u32>;
899   var uint32x4 : vec4<u32>;
900   var sint32 : i32;
901   var sint32x2 : vec2<i32>;
902   var sint32x3 : vec3<i32>;
903   var sint32x4 : vec4<i32>;
904   {
905     let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
906     uint8x2 = ((vec2<u32>((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 8u)) & 4294901760u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
907     uint8x4 = ((vec4<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
908     sint8x2 = ((vec2<i32>(bitcast<i32>((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 8u)) & 4294901760u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
909     sint8x4 = ((vec4<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)))) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
910     unorm8x2 = unpack4x8unorm((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u)) & 65535u)).xy;
911     unorm8x4 = unpack4x8unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
912     snorm8x2 = unpack4x8snorm((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u)) & 65535u)).xy;
913     snorm8x4 = unpack4x8snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
914     uint16x2 = ((vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
915     uint16x4 = ((vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
916     sint16x2 = ((vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)))) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
917     sint16x4 = ((vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)))).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
918     unorm16x2 = unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
919     unorm16x4 = vec4<f32>(unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
920     snorm16x2 = unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
921     snorm16x4 = vec4<f32>(unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
922     float16x2 = unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
923     float16x4 = vec4<f32>(unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
924     float32 = bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
925     float32x2 = vec2<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
926     float32x3 = vec3<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))));
927     float32x4 = vec4<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u))));
928     uint32 = ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u));
929     uint32x2 = vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)));
930     uint32x3 = vec3<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u)));
931     uint32x4 = vec4<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u)));
932     sint32 = bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
933     sint32x2 = vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
934     sint32x3 = vec3<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))));
935     sint32x4 = vec4<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u))));
936   }
937   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
938 }
939 )";
940 
941   VertexPulling::Config cfg;
942   cfg.vertex_state = {{{256,
943                         VertexStepMode::kVertex,
944                         {
945                             {VertexFormat::kUint8x2, 63, 0},
946                             {VertexFormat::kUint8x4, 63, 1},
947                             {VertexFormat::kSint8x2, 63, 2},
948                             {VertexFormat::kSint8x4, 63, 3},
949                             {VertexFormat::kUnorm8x2, 63, 4},
950                             {VertexFormat::kUnorm8x4, 63, 5},
951                             {VertexFormat::kSnorm8x2, 63, 6},
952                             {VertexFormat::kSnorm8x4, 63, 7},
953                             {VertexFormat::kUint16x2, 63, 8},
954                             {VertexFormat::kUint16x4, 63, 9},
955                             {VertexFormat::kSint16x2, 63, 10},
956                             {VertexFormat::kSint16x4, 63, 11},
957                             {VertexFormat::kUnorm16x2, 63, 12},
958                             {VertexFormat::kUnorm16x4, 63, 13},
959                             {VertexFormat::kSnorm16x2, 63, 14},
960                             {VertexFormat::kSnorm16x4, 63, 15},
961                             {VertexFormat::kFloat16x2, 63, 16},
962                             {VertexFormat::kFloat16x4, 63, 17},
963                             {VertexFormat::kFloat32, 63, 18},
964                             {VertexFormat::kFloat32x2, 63, 19},
965                             {VertexFormat::kFloat32x3, 63, 20},
966                             {VertexFormat::kFloat32x4, 63, 21},
967                             {VertexFormat::kUint32, 63, 22},
968                             {VertexFormat::kUint32x2, 63, 23},
969                             {VertexFormat::kUint32x3, 63, 24},
970                             {VertexFormat::kUint32x4, 63, 25},
971                             {VertexFormat::kSint32, 63, 26},
972                             {VertexFormat::kSint32x2, 63, 27},
973                             {VertexFormat::kSint32x3, 63, 28},
974                             {VertexFormat::kSint32x4, 63, 29},
975                         }}}};
976   cfg.entry_point_name = "main";
977 
978   DataMap data;
979   data.Add<VertexPulling::Config>(cfg);
980   auto got = Run<VertexPulling>(src, data);
981 
982   EXPECT_EQ(expect, str(got));
983 }
984 
TEST_F(VertexPullingTest,FormatsWithVectorsResized)985 TEST_F(VertexPullingTest, FormatsWithVectorsResized) {
986   auto* src = R"(
987 [[stage(vertex)]]
988 fn main(
989     [[location(0)]] uint8x2 : vec3<u32>,
990     [[location(1)]] uint8x4 : vec2<u32>,
991     [[location(2)]] sint8x2 : i32,
992     [[location(3)]] sint8x4 : vec2<i32>,
993     [[location(4)]] unorm8x2 : vec4<f32>,
994     [[location(5)]] unorm8x4 : f32,
995     [[location(6)]] snorm8x2 : vec3<f32>,
996     [[location(7)]] snorm8x4 : f32,
997     [[location(8)]] uint16x2 : vec3<u32>,
998     [[location(9)]] uint16x4 : vec2<u32>,
999     [[location(10)]] sint16x2 : vec4<i32>,
1000     [[location(11)]] sint16x4 : i32,
1001     [[location(12)]] unorm16x2 : vec3<f32>,
1002     [[location(13)]] unorm16x4 : f32,
1003     [[location(14)]] snorm16x2 : vec4<f32>,
1004     [[location(15)]] snorm16x4 : vec3<f32>,
1005     [[location(16)]] float16x2 : vec4<f32>,
1006     [[location(17)]] float16x4 : f32,
1007     [[location(18)]] float32 : vec4<f32>,
1008     [[location(19)]] float32x2 : vec4<f32>,
1009     [[location(20)]] float32x3 : vec2<f32>,
1010     [[location(21)]] float32x4 : vec3<f32>,
1011     [[location(22)]] uint32 : vec3<u32>,
1012     [[location(23)]] uint32x2 : vec4<u32>,
1013     [[location(24)]] uint32x3 : vec4<u32>,
1014     [[location(25)]] uint32x4 : vec2<u32>,
1015     [[location(26)]] sint32 : vec4<i32>,
1016     [[location(27)]] sint32x2 : vec3<i32>,
1017     [[location(28)]] sint32x3 : i32,
1018     [[location(29)]] sint32x4 : vec2<i32>
1019   ) -> [[builtin(position)]] vec4<f32> {
1020   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
1021 }
1022 )";
1023 
1024   auto* expect = R"(
1025 [[block]]
1026 struct TintVertexData {
1027   tint_vertex_data : [[stride(4)]] array<u32>;
1028 };
1029 
1030 [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
1031 
1032 [[stage(vertex)]]
1033 fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
1034   var uint8x2 : vec3<u32>;
1035   var uint8x4 : vec2<u32>;
1036   var sint8x2 : i32;
1037   var sint8x4 : vec2<i32>;
1038   var unorm8x2 : vec4<f32>;
1039   var unorm8x4 : f32;
1040   var snorm8x2 : vec3<f32>;
1041   var snorm8x4 : f32;
1042   var uint16x2 : vec3<u32>;
1043   var uint16x4 : vec2<u32>;
1044   var sint16x2 : vec4<i32>;
1045   var sint16x4 : i32;
1046   var unorm16x2 : vec3<f32>;
1047   var unorm16x4 : f32;
1048   var snorm16x2 : vec4<f32>;
1049   var snorm16x4 : vec3<f32>;
1050   var float16x2 : vec4<f32>;
1051   var float16x4 : f32;
1052   var float32 : vec4<f32>;
1053   var float32x2 : vec4<f32>;
1054   var float32x3 : vec2<f32>;
1055   var float32x4 : vec3<f32>;
1056   var uint32 : vec3<u32>;
1057   var uint32x2 : vec4<u32>;
1058   var uint32x3 : vec4<u32>;
1059   var uint32x4 : vec2<u32>;
1060   var sint32 : vec4<i32>;
1061   var sint32x2 : vec3<i32>;
1062   var sint32x3 : i32;
1063   var sint32x4 : vec2<i32>;
1064   {
1065     let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
1066     uint8x2 = vec3<u32>(((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u)), 0u);
1067     uint8x4 = (((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy;
1068     sint8x2 = (((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u))).x;
1069     sint8x4 = (((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy;
1070     unorm8x2 = vec4<f32>(unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0, 1.0);
1071     unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
1072     snorm8x2 = vec3<f32>(unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0);
1073     snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
1074     uint16x2 = vec3<u32>(((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0u);
1075     uint16x4 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xy;
1076     sint16x2 = vec4<i32>(((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0, 1);
1077     sint16x4 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).x;
1078     unorm16x2 = vec3<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0);
1079     unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
1080     snorm16x2 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 1.0);
1081     snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xyz;
1082     float16x2 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 1.0);
1083     float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
1084     float32 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 0.0, 1.0);
1085     float32x2 = vec4<f32>(vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0.0, 1.0);
1086     float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).xy;
1087     float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xyz;
1088     uint32 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], 0u, 0u);
1089     uint32x2 = vec4<u32>(vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), 0u, 1u);
1090     uint32x3 = vec4<u32>(vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), 1u);
1091     uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]).xy;
1092     sint32 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0, 0, 1);
1093     sint32x2 = vec3<i32>(vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0);
1094     sint32x3 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).x;
1095     sint32x4 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xy;
1096   }
1097   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
1098 }
1099 )";
1100 
1101   VertexPulling::Config cfg;
1102   cfg.vertex_state = {{{256,
1103                         VertexStepMode::kVertex,
1104                         {
1105                             {VertexFormat::kUint8x2, 64, 0},
1106                             {VertexFormat::kUint8x4, 64, 1},
1107                             {VertexFormat::kSint8x2, 64, 2},
1108                             {VertexFormat::kSint8x4, 64, 3},
1109                             {VertexFormat::kUnorm8x2, 64, 4},
1110                             {VertexFormat::kUnorm8x4, 64, 5},
1111                             {VertexFormat::kSnorm8x2, 64, 6},
1112                             {VertexFormat::kSnorm8x4, 64, 7},
1113                             {VertexFormat::kUint16x2, 64, 8},
1114                             {VertexFormat::kUint16x4, 64, 9},
1115                             {VertexFormat::kSint16x2, 64, 10},
1116                             {VertexFormat::kSint16x4, 64, 11},
1117                             {VertexFormat::kUnorm16x2, 64, 12},
1118                             {VertexFormat::kUnorm16x4, 64, 13},
1119                             {VertexFormat::kSnorm16x2, 64, 14},
1120                             {VertexFormat::kSnorm16x4, 64, 15},
1121                             {VertexFormat::kFloat16x2, 64, 16},
1122                             {VertexFormat::kFloat16x4, 64, 17},
1123                             {VertexFormat::kFloat32, 64, 18},
1124                             {VertexFormat::kFloat32x2, 64, 19},
1125                             {VertexFormat::kFloat32x3, 64, 20},
1126                             {VertexFormat::kFloat32x4, 64, 21},
1127                             {VertexFormat::kUint32, 64, 22},
1128                             {VertexFormat::kUint32x2, 64, 23},
1129                             {VertexFormat::kUint32x3, 64, 24},
1130                             {VertexFormat::kUint32x4, 64, 25},
1131                             {VertexFormat::kSint32, 64, 26},
1132                             {VertexFormat::kSint32x2, 64, 27},
1133                             {VertexFormat::kSint32x3, 64, 28},
1134                             {VertexFormat::kSint32x4, 64, 29},
1135                         }}}};
1136   cfg.entry_point_name = "main";
1137 
1138   DataMap data;
1139   data.Add<VertexPulling::Config>(cfg);
1140   auto got = Run<VertexPulling>(src, data);
1141 
1142   EXPECT_EQ(expect, str(got));
1143 }
1144 
1145 }  // namespace
1146 }  // namespace transform
1147 }  // namespace tint
1148