• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Dawn 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 "tests/DawnTest.h"
16 
17 #include "common/Assert.h"
18 #include "common/Math.h"
19 #include "utils/ComboRenderPipelineDescriptor.h"
20 #include "utils/WGPUHelpers.h"
21 
22 // Vertex format tests all work the same way: the test will render a triangle.
23 // Each test will set up a vertex buffer, and the vertex shader will check that
24 // the vertex content is the same as what we expected. On success it outputs green,
25 // otherwise red.
26 
27 constexpr uint32_t kRTSize = 1;
28 constexpr uint32_t kVertexNum = 3;
29 
Float32ToFloat16(std::vector<float> data)30 std::vector<uint16_t> Float32ToFloat16(std::vector<float> data) {
31     std::vector<uint16_t> expectedData;
32     for (auto& element : data) {
33         expectedData.push_back(Float32ToFloat16(element));
34     }
35     return expectedData;
36 }
37 
38 template <typename destType, typename srcType>
BitCast(std::vector<srcType> data)39 std::vector<destType> BitCast(std::vector<srcType> data) {
40     std::vector<destType> expectedData;
41     for (auto& element : data) {
42         expectedData.push_back(BitCast(element));
43     }
44     return expectedData;
45 }
46 
47 class VertexFormatTest : public DawnTest {
48   protected:
SetUp()49     void SetUp() override {
50         DawnTest::SetUp();
51 
52         // TODO(crbug.com/dawn/259): Failing because of a SPIRV-Cross issue.
53         DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel());
54 
55         renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
56     }
57 
58     utils::BasicRenderPass renderPass;
59 
IsNormalizedFormat(wgpu::VertexFormat format)60     bool IsNormalizedFormat(wgpu::VertexFormat format) {
61         switch (format) {
62             case wgpu::VertexFormat::Unorm8x2:
63             case wgpu::VertexFormat::Unorm8x4:
64             case wgpu::VertexFormat::Snorm8x2:
65             case wgpu::VertexFormat::Snorm8x4:
66             case wgpu::VertexFormat::Unorm16x2:
67             case wgpu::VertexFormat::Unorm16x4:
68             case wgpu::VertexFormat::Snorm16x2:
69             case wgpu::VertexFormat::Snorm16x4:
70                 return true;
71             default:
72                 return false;
73         }
74     }
75 
IsUnsignedFormat(wgpu::VertexFormat format)76     bool IsUnsignedFormat(wgpu::VertexFormat format) {
77         switch (format) {
78             case wgpu::VertexFormat::Uint32:
79             case wgpu::VertexFormat::Uint8x2:
80             case wgpu::VertexFormat::Uint8x4:
81             case wgpu::VertexFormat::Uint16x2:
82             case wgpu::VertexFormat::Uint16x4:
83             case wgpu::VertexFormat::Uint32x2:
84             case wgpu::VertexFormat::Uint32x3:
85             case wgpu::VertexFormat::Uint32x4:
86             case wgpu::VertexFormat::Unorm8x2:
87             case wgpu::VertexFormat::Unorm8x4:
88             case wgpu::VertexFormat::Unorm16x2:
89             case wgpu::VertexFormat::Unorm16x4:
90                 return true;
91             default:
92                 return false;
93         }
94     }
95 
IsFloatFormat(wgpu::VertexFormat format)96     bool IsFloatFormat(wgpu::VertexFormat format) {
97         switch (format) {
98             case wgpu::VertexFormat::Float16x2:
99             case wgpu::VertexFormat::Float16x4:
100             case wgpu::VertexFormat::Float32:
101             case wgpu::VertexFormat::Float32x2:
102             case wgpu::VertexFormat::Float32x3:
103             case wgpu::VertexFormat::Float32x4:
104                 return true;
105             default:
106                 return false;
107         }
108     }
109 
IsHalfFormat(wgpu::VertexFormat format)110     bool IsHalfFormat(wgpu::VertexFormat format) {
111         switch (format) {
112             case wgpu::VertexFormat::Float16x2:
113             case wgpu::VertexFormat::Float16x4:
114                 return true;
115             default:
116                 return false;
117         }
118     }
119 
BytesPerComponents(wgpu::VertexFormat format)120     uint32_t BytesPerComponents(wgpu::VertexFormat format) {
121         switch (format) {
122             case wgpu::VertexFormat::Uint8x2:
123             case wgpu::VertexFormat::Uint8x4:
124             case wgpu::VertexFormat::Sint8x2:
125             case wgpu::VertexFormat::Sint8x4:
126             case wgpu::VertexFormat::Unorm8x2:
127             case wgpu::VertexFormat::Unorm8x4:
128             case wgpu::VertexFormat::Snorm8x2:
129             case wgpu::VertexFormat::Snorm8x4:
130                 return 1;
131             case wgpu::VertexFormat::Uint16x2:
132             case wgpu::VertexFormat::Uint16x4:
133             case wgpu::VertexFormat::Unorm16x2:
134             case wgpu::VertexFormat::Unorm16x4:
135             case wgpu::VertexFormat::Sint16x2:
136             case wgpu::VertexFormat::Sint16x4:
137             case wgpu::VertexFormat::Snorm16x2:
138             case wgpu::VertexFormat::Snorm16x4:
139             case wgpu::VertexFormat::Float16x2:
140             case wgpu::VertexFormat::Float16x4:
141                 return 2;
142             case wgpu::VertexFormat::Float32:
143             case wgpu::VertexFormat::Float32x2:
144             case wgpu::VertexFormat::Float32x3:
145             case wgpu::VertexFormat::Float32x4:
146             case wgpu::VertexFormat::Uint32:
147             case wgpu::VertexFormat::Uint32x2:
148             case wgpu::VertexFormat::Uint32x3:
149             case wgpu::VertexFormat::Uint32x4:
150             case wgpu::VertexFormat::Sint32:
151             case wgpu::VertexFormat::Sint32x2:
152             case wgpu::VertexFormat::Sint32x3:
153             case wgpu::VertexFormat::Sint32x4:
154                 return 4;
155             default:
156                 DAWN_UNREACHABLE();
157         }
158     }
159 
ComponentCount(wgpu::VertexFormat format)160     uint32_t ComponentCount(wgpu::VertexFormat format) {
161         switch (format) {
162             case wgpu::VertexFormat::Float32:
163             case wgpu::VertexFormat::Uint32:
164             case wgpu::VertexFormat::Sint32:
165                 return 1;
166             case wgpu::VertexFormat::Uint8x2:
167             case wgpu::VertexFormat::Sint8x2:
168             case wgpu::VertexFormat::Unorm8x2:
169             case wgpu::VertexFormat::Snorm8x2:
170             case wgpu::VertexFormat::Uint16x2:
171             case wgpu::VertexFormat::Sint16x2:
172             case wgpu::VertexFormat::Unorm16x2:
173             case wgpu::VertexFormat::Snorm16x2:
174             case wgpu::VertexFormat::Float16x2:
175             case wgpu::VertexFormat::Float32x2:
176             case wgpu::VertexFormat::Uint32x2:
177             case wgpu::VertexFormat::Sint32x2:
178                 return 2;
179             case wgpu::VertexFormat::Float32x3:
180             case wgpu::VertexFormat::Uint32x3:
181             case wgpu::VertexFormat::Sint32x3:
182                 return 3;
183             case wgpu::VertexFormat::Uint8x4:
184             case wgpu::VertexFormat::Sint8x4:
185             case wgpu::VertexFormat::Unorm8x4:
186             case wgpu::VertexFormat::Snorm8x4:
187             case wgpu::VertexFormat::Uint16x4:
188             case wgpu::VertexFormat::Sint16x4:
189             case wgpu::VertexFormat::Unorm16x4:
190             case wgpu::VertexFormat::Snorm16x4:
191             case wgpu::VertexFormat::Float16x4:
192             case wgpu::VertexFormat::Float32x4:
193             case wgpu::VertexFormat::Uint32x4:
194             case wgpu::VertexFormat::Sint32x4:
195                 return 4;
196             default:
197                 DAWN_UNREACHABLE();
198         }
199     }
200 
ShaderTypeGenerator(bool isFloat,bool isNormalized,bool isUnsigned,uint32_t componentCount)201     std::string ShaderTypeGenerator(bool isFloat,
202                                     bool isNormalized,
203                                     bool isUnsigned,
204                                     uint32_t componentCount) {
205         std::string base;
206         if (isFloat || isNormalized) {
207             base = "f32";
208         } else if (isUnsigned) {
209             base = "u32";
210         } else {
211             base = "i32";
212         }
213 
214         if (componentCount == 1) {
215             return base;
216         }
217 
218         return "vec" + std::to_string(componentCount) + "<" + base + ">";
219     }
220 
221     // The length of vertexData is fixed to 3, it aligns to triangle vertex number
222     template <typename T>
MakeTestPipeline(wgpu::VertexFormat format,std::vector<T> & expectedData)223     wgpu::RenderPipeline MakeTestPipeline(wgpu::VertexFormat format, std::vector<T>& expectedData) {
224         bool isFloat = IsFloatFormat(format);
225         bool isNormalized = IsNormalizedFormat(format);
226         bool isUnsigned = IsUnsignedFormat(format);
227         bool isInputTypeFloat = isFloat || isNormalized;
228         bool isHalf = IsHalfFormat(format);
229         const uint16_t kNegativeZeroInHalf = 0x8000;
230 
231         uint32_t componentCount = ComponentCount(format);
232 
233         std::string variableType =
234             ShaderTypeGenerator(isFloat, isNormalized, isUnsigned, componentCount);
235         std::string expectedDataType = ShaderTypeGenerator(isFloat, isNormalized, isUnsigned, 1);
236 
237         std::ostringstream vs;
238         vs << "struct VertexIn {\n";
239         vs << "    [[location(0)]] test : " << variableType << ";\n";
240         vs << "    [[builtin(vertex_index)]] VertexIndex : u32;\n";
241         vs << "};\n";
242 
243         // Because x86 CPU using "extended
244         // precision"(https://en.wikipedia.org/wiki/Extended_precision) during float
245         // math(https://developer.nvidia.com/sites/default/files/akamai/cuda/files/NVIDIA-CUDA-Floating-Point.pdf),
246         // move normalization and Float16ToFloat32 into shader to generate
247         // expected value.
248         vs << R"(
249             fn Float16ToFloat32(fp16 : u32) -> f32 {
250                 let magic : u32 = (254u - 15u) << 23u;
251                 let was_inf_nan : u32 = (127u + 16u) << 23u;
252                 var fp32u : u32 = (fp16 & 0x7FFFu) << 13u;
253                 let fp32 : f32 = bitcast<f32>(fp32u) * bitcast<f32>(magic);
254                 fp32u = bitcast<u32>(fp32);
255                 if (fp32 >= bitcast<f32>(was_inf_nan)) {
256                     fp32u = fp32u | (255u << 23u);
257                 }
258                 fp32u = fp32u | ((fp16 & 0x8000u) << 16u);
259                 return bitcast<f32>(fp32u);
260             }
261 
262             struct VertexOut {
263                 [[location(0)]] color : vec4<f32>;
264                 [[builtin(position)]] position : vec4<f32>;
265             };
266 
267             [[stage(vertex)]]
268             fn main(input : VertexIn) -> VertexOut {
269                 var pos = array<vec2<f32>, 3>(
270                     vec2<f32>(-1.0, -1.0),
271                     vec2<f32>( 2.0,  0.0),
272                     vec2<f32>( 0.0,  2.0));
273                 var output : VertexOut;
274                 output.position = vec4<f32>(pos[input.VertexIndex], 0.0, 1.0);
275         )";
276 
277         // Declare expected values.
278         vs << "var expected : array<array<" << expectedDataType << ", "
279            << std::to_string(componentCount) << ">, " << std::to_string(kVertexNum) << ">;";
280         // Assign each elements in expected values
281         // e.g. expected[0][0] = u32(1u);
282         //      expected[0][1] = u32(2u);
283         for (uint32_t i = 0; i < kVertexNum; ++i) {
284             for (uint32_t j = 0; j < componentCount; ++j) {
285                 vs << "    expected[" + std::to_string(i) + "][" + std::to_string(j) + "] = "
286                    << expectedDataType << "(";
287                 if (isInputTypeFloat &&
288                     std::isnan(static_cast<float>(expectedData[i * componentCount + j]))) {
289                     // Set NaN.
290                     vs << "0.0 / 0.0);\n";
291                 } else if (isNormalized) {
292                     // Move normalize operation into shader because of CPU and GPU precision
293                     // different on float math.
294                     vs << "max(f32(" << std::to_string(expectedData[i * componentCount + j])
295                        << ") / " << std::to_string(std::numeric_limits<T>::max())
296                        << ".0 , -1.0));\n";
297                 } else if (isHalf) {
298                     // Becasue Vulkan and D3D12 handle -0.0f through bitcast have different
299                     // result (Vulkan take -0.0f as -0.0 but D3D12 take -0.0f as 0), add workaround
300                     // for -0.0f.
301                     if (static_cast<uint16_t>(expectedData[i * componentCount + j]) ==
302                         kNegativeZeroInHalf) {
303                         vs << "-0.0);\n";
304                     } else {
305                         vs << "Float16ToFloat32(u32("
306                            << std::to_string(expectedData[i * componentCount + j]) << ")));\n";
307                     }
308                 } else if (isUnsigned) {
309                     vs << std::to_string(expectedData[i * componentCount + j]) << "u);\n";
310                 } else {
311                     vs << std::to_string(expectedData[i * componentCount + j]) << ");\n";
312                 }
313             }
314         }
315 
316         vs << "    var success : bool = true;\n";
317         // Perform the checks by successively ANDing a boolean
318         for (uint32_t component = 0; component < componentCount; ++component) {
319             std::string suffix = componentCount == 1 ? "" : "[" + std::to_string(component) + "]";
320             std::string testVal = "testVal" + std::to_string(component);
321             std::string expectedVal = "expectedVal" + std::to_string(component);
322             vs << "    var " << testVal << " : " << expectedDataType << ";\n";
323             vs << "    var " << expectedVal << " : " << expectedDataType << ";\n";
324             vs << "    " << testVal << " = input.test" << suffix << ";\n";
325             vs << "    " << expectedVal << " = expected[input.VertexIndex]"
326                << "[" << component << "];\n";
327             if (!isInputTypeFloat) {  // Integer / unsigned integer need to match exactly.
328                 vs << "    success = success && (" << testVal << " == " << expectedVal << ");\n";
329             } else {
330                 // TODO(shaobo.yan@intel.com) : a difference of 8 ULPs is allowed in this test
331                 // because it is required on MacbookPro 11.5,AMD Radeon HD 8870M(on macOS 10.13.6),
332                 // but that it might be possible to tighten.
333                 vs << "    if (isNan(" << expectedVal << ")) {\n";
334                 vs << "       success = success && isNan(" << testVal << ");\n";
335                 vs << "    } else {\n";
336                 vs << "        let testValFloatToUint : u32 = bitcast<u32>(" << testVal << ");\n";
337                 vs << "        let expectedValFloatToUint : u32 = bitcast<u32>(" << expectedVal
338                    << ");\n";
339                 vs << "        success = success && max(testValFloatToUint, "
340                       "expectedValFloatToUint)";
341                 vs << "        - min(testValFloatToUint, expectedValFloatToUint) < 8u;\n";
342                 vs << "    }\n";
343             }
344         }
345         vs << R"(
346             if (success) {
347                 output.color = vec4<f32>(0.0, 1.0, 0.0, 1.0);
348             } else {
349                 output.color = vec4<f32>(1.0, 0.0, 0.0, 1.0);
350             }
351             return output;
352         })";
353 
354         wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, vs.str().c_str());
355         wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
356                 [[stage(fragment)]]
357                 fn main([[location(0)]] color : vec4<f32>) -> [[location(0)]] vec4<f32> {
358                     return color;
359                 })");
360 
361         uint32_t bytesPerComponents = BytesPerComponents(format);
362         uint32_t strideBytes = bytesPerComponents * componentCount;
363         // Stride size must be multiple of 4 bytes.
364         if (strideBytes % 4 != 0) {
365             strideBytes += (4 - strideBytes % 4);
366         }
367 
368         utils::ComboRenderPipelineDescriptor descriptor;
369         descriptor.vertex.module = vsModule;
370         descriptor.cFragment.module = fsModule;
371         descriptor.vertex.bufferCount = 1;
372         descriptor.cBuffers[0].arrayStride = strideBytes;
373         descriptor.cBuffers[0].attributeCount = 1;
374         descriptor.cAttributes[0].format = format;
375         descriptor.cTargets[0].format = renderPass.colorFormat;
376 
377         return device.CreateRenderPipeline(&descriptor);
378     }
379 
380     template <typename VertexType, typename ExpectedType>
DoVertexFormatTest(wgpu::VertexFormat format,std::vector<VertexType> vertex,std::vector<ExpectedType> expectedData)381     void DoVertexFormatTest(wgpu::VertexFormat format,
382                             std::vector<VertexType> vertex,
383                             std::vector<ExpectedType> expectedData) {
384         wgpu::RenderPipeline pipeline = MakeTestPipeline(format, expectedData);
385         wgpu::Buffer vertexBuffer = utils::CreateBufferFromData(
386             device, vertex.data(), vertex.size() * sizeof(VertexType), wgpu::BufferUsage::Vertex);
387         wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
388         {
389             wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
390             pass.SetPipeline(pipeline);
391             pass.SetVertexBuffer(0, vertexBuffer);
392             pass.Draw(3);
393             pass.EndPass();
394         }
395 
396         wgpu::CommandBuffer commands = encoder.Finish();
397         queue.Submit(1, &commands);
398 
399         EXPECT_PIXEL_RGBA8_EQ(RGBA8::kGreen, renderPass.color, 0, 0);
400     }
401 };
402 
TEST_P(VertexFormatTest,Uint8x2)403 TEST_P(VertexFormatTest, Uint8x2) {
404     std::vector<uint8_t> vertexData = {
405         std::numeric_limits<uint8_t>::max(),
406         0,
407         0,  // padding two bytes for stride
408         0,
409         std::numeric_limits<uint8_t>::min(),
410         2,
411         0,
412         0,  // padding two bytes for stride
413         200,
414         201,
415         0,
416         0  // padding two bytes for buffer copy
417     };
418 
419     std::vector<uint8_t> expectedData = {
420         std::numeric_limits<uint8_t>::max(), 0, std::numeric_limits<uint8_t>::min(), 2, 200, 201,
421     };
422 
423     DoVertexFormatTest(wgpu::VertexFormat::Uint8x2, vertexData, expectedData);
424 }
425 
TEST_P(VertexFormatTest,Uint8x4)426 TEST_P(VertexFormatTest, Uint8x4) {
427     std::vector<uint8_t> vertexData = {
428         std::numeric_limits<uint8_t>::max(),
429         0,
430         1,
431         2,
432         std::numeric_limits<uint8_t>::min(),
433         2,
434         3,
435         4,
436         200,
437         201,
438         202,
439         203,
440     };
441 
442     DoVertexFormatTest(wgpu::VertexFormat::Uint8x4, vertexData, vertexData);
443 }
444 
TEST_P(VertexFormatTest,Sint8x2)445 TEST_P(VertexFormatTest, Sint8x2) {
446     std::vector<int8_t> vertexData = {
447         std::numeric_limits<int8_t>::max(),
448         0,
449         0,  // padding two bytes for stride
450         0,
451         std::numeric_limits<int8_t>::min(),
452         -2,
453         0,  // padding two bytes for stride
454         0,
455         120,
456         -121,
457         0,
458         0  // padding two bytes for buffer copy
459     };
460 
461     std::vector<int8_t> expectedData = {
462         std::numeric_limits<int8_t>::max(), 0, std::numeric_limits<int8_t>::min(), -2, 120, -121,
463     };
464 
465     DoVertexFormatTest(wgpu::VertexFormat::Sint8x2, vertexData, expectedData);
466 }
467 
TEST_P(VertexFormatTest,Sint8x4)468 TEST_P(VertexFormatTest, Sint8x4) {
469     std::vector<int8_t> vertexData = {
470         std::numeric_limits<int8_t>::max(),
471         0,
472         -1,
473         2,
474         std::numeric_limits<int8_t>::min(),
475         -2,
476         3,
477         4,
478         120,
479         -121,
480         122,
481         -123,
482     };
483 
484     DoVertexFormatTest(wgpu::VertexFormat::Sint8x4, vertexData, vertexData);
485 }
486 
TEST_P(VertexFormatTest,Unorm8x2)487 TEST_P(VertexFormatTest, Unorm8x2) {
488     std::vector<uint8_t> vertexData = {
489         std::numeric_limits<uint8_t>::max(),
490         std::numeric_limits<uint8_t>::min(),
491         0,  // padding two bytes for stride
492         0,
493         std::numeric_limits<uint8_t>::max() / 2u,
494         std::numeric_limits<uint8_t>::min() / 2u,
495         0,  // padding two bytes for stride
496         0,
497         200,
498         201,
499         0,
500         0  // padding two bytes for buffer copy
501     };
502 
503     std::vector<uint8_t> expectedData = {std::numeric_limits<uint8_t>::max(),
504                                          std::numeric_limits<uint8_t>::min(),
505                                          std::numeric_limits<uint8_t>::max() / 2u,
506                                          std::numeric_limits<uint8_t>::min() / 2u,
507                                          200,
508                                          201};
509 
510     DoVertexFormatTest(wgpu::VertexFormat::Unorm8x2, vertexData, expectedData);
511 }
512 
TEST_P(VertexFormatTest,Unorm8x4)513 TEST_P(VertexFormatTest, Unorm8x4) {
514     std::vector<uint8_t> vertexData = {std::numeric_limits<uint8_t>::max(),
515                                        std::numeric_limits<uint8_t>::min(),
516                                        0,
517                                        0,
518                                        std::numeric_limits<uint8_t>::max() / 2u,
519                                        std::numeric_limits<uint8_t>::min() / 2u,
520                                        0,
521                                        0,
522                                        200,
523                                        201,
524                                        202,
525                                        203};
526 
527     DoVertexFormatTest(wgpu::VertexFormat::Unorm8x4, vertexData, vertexData);
528 }
529 
TEST_P(VertexFormatTest,Snorm8x2)530 TEST_P(VertexFormatTest, Snorm8x2) {
531     std::vector<int8_t> vertexData = {
532         std::numeric_limits<int8_t>::max(),
533         std::numeric_limits<int8_t>::min(),
534         0,  // padding two bytes for stride
535         0,
536         std::numeric_limits<int8_t>::max() / 2,
537         std::numeric_limits<int8_t>::min() / 2,
538         0,  // padding two bytes for stride
539         0,
540         120,
541         -121,
542         0,
543         0  // padding two bytes for buffer copy
544     };
545 
546     std::vector<int8_t> expectedData = {
547         std::numeric_limits<int8_t>::max(),
548         std::numeric_limits<int8_t>::min(),
549         std::numeric_limits<int8_t>::max() / 2,
550         std::numeric_limits<int8_t>::min() / 2,
551         120,
552         -121,
553     };
554 
555     DoVertexFormatTest(wgpu::VertexFormat::Snorm8x2, vertexData, expectedData);
556 }
557 
TEST_P(VertexFormatTest,Snorm8x4)558 TEST_P(VertexFormatTest, Snorm8x4) {
559     std::vector<int8_t> vertexData = {std::numeric_limits<int8_t>::max(),
560                                       std::numeric_limits<int8_t>::min(),
561                                       0,
562                                       0,
563                                       std::numeric_limits<int8_t>::max() / 2,
564                                       std::numeric_limits<int8_t>::min() / 2,
565                                       -2,
566                                       2,
567                                       120,
568                                       -120,
569                                       102,
570                                       -123};
571 
572     DoVertexFormatTest(wgpu::VertexFormat::Snorm8x4, vertexData, vertexData);
573 }
574 
TEST_P(VertexFormatTest,Uint16x2)575 TEST_P(VertexFormatTest, Uint16x2) {
576     std::vector<uint16_t> vertexData = {std::numeric_limits<uint16_t>::max(),
577                                         0,
578                                         std::numeric_limits<uint16_t>::min(),
579                                         2,
580                                         65432,
581                                         4890};
582 
583     DoVertexFormatTest(wgpu::VertexFormat::Uint16x2, vertexData, vertexData);
584 }
585 
TEST_P(VertexFormatTest,Uint16x4)586 TEST_P(VertexFormatTest, Uint16x4) {
587     std::vector<uint16_t> vertexData = {
588         std::numeric_limits<uint16_t>::max(),
589         std::numeric_limits<uint8_t>::max(),
590         1,
591         2,
592         std::numeric_limits<uint16_t>::min(),
593         2,
594         3,
595         4,
596         65520,
597         65521,
598         3435,
599         3467,
600     };
601 
602     DoVertexFormatTest(wgpu::VertexFormat::Uint16x4, vertexData, vertexData);
603 }
604 
TEST_P(VertexFormatTest,Sint16x2)605 TEST_P(VertexFormatTest, Sint16x2) {
606     std::vector<int16_t> vertexData = {std::numeric_limits<int16_t>::max(),
607                                        0,
608                                        std::numeric_limits<int16_t>::min(),
609                                        -2,
610                                        3876,
611                                        -3948};
612 
613     DoVertexFormatTest(wgpu::VertexFormat::Sint16x2, vertexData, vertexData);
614 }
615 
TEST_P(VertexFormatTest,Sint16x4)616 TEST_P(VertexFormatTest, Sint16x4) {
617     std::vector<int16_t> vertexData = {
618         std::numeric_limits<int16_t>::max(),
619         0,
620         -1,
621         2,
622         std::numeric_limits<int16_t>::min(),
623         -2,
624         3,
625         4,
626         24567,
627         -23545,
628         4350,
629         -2987,
630     };
631 
632     DoVertexFormatTest(wgpu::VertexFormat::Sint16x4, vertexData, vertexData);
633 }
634 
TEST_P(VertexFormatTest,Unorm16x2)635 TEST_P(VertexFormatTest, Unorm16x2) {
636     std::vector<uint16_t> vertexData = {std::numeric_limits<uint16_t>::max(),
637                                         std::numeric_limits<uint16_t>::min(),
638                                         std::numeric_limits<uint16_t>::max() / 2u,
639                                         std::numeric_limits<uint16_t>::min() / 2u,
640                                         3456,
641                                         6543};
642 
643     DoVertexFormatTest(wgpu::VertexFormat::Unorm16x2, vertexData, vertexData);
644 }
645 
TEST_P(VertexFormatTest,Unorm16x4)646 TEST_P(VertexFormatTest, Unorm16x4) {
647     std::vector<uint16_t> vertexData = {std::numeric_limits<uint16_t>::max(),
648                                         std::numeric_limits<uint16_t>::min(),
649                                         0,
650                                         0,
651                                         std::numeric_limits<uint16_t>::max() / 2u,
652                                         std::numeric_limits<uint16_t>::min() / 2u,
653                                         0,
654                                         0,
655                                         2987,
656                                         3055,
657                                         2987,
658                                         2987};
659 
660     DoVertexFormatTest(wgpu::VertexFormat::Unorm16x4, vertexData, vertexData);
661 }
662 
TEST_P(VertexFormatTest,Snorm16x2)663 TEST_P(VertexFormatTest, Snorm16x2) {
664     std::vector<int16_t> vertexData = {std::numeric_limits<int16_t>::max(),
665                                        std::numeric_limits<int16_t>::min(),
666                                        std::numeric_limits<int16_t>::max() / 2,
667                                        std::numeric_limits<int16_t>::min() / 2,
668                                        4987,
669                                        -6789};
670 
671     DoVertexFormatTest(wgpu::VertexFormat::Snorm16x2, vertexData, vertexData);
672 }
673 
TEST_P(VertexFormatTest,Snorm16x4)674 TEST_P(VertexFormatTest, Snorm16x4) {
675     std::vector<int16_t> vertexData = {std::numeric_limits<int16_t>::max(),
676                                        std::numeric_limits<int16_t>::min(),
677                                        0,
678                                        0,
679                                        std::numeric_limits<int16_t>::max() / 2,
680                                        std::numeric_limits<int16_t>::min() / 2,
681                                        -2,
682                                        2,
683                                        2890,
684                                        -29011,
685                                        20432,
686                                        -2083};
687 
688     DoVertexFormatTest(wgpu::VertexFormat::Snorm16x4, vertexData, vertexData);
689 }
690 
TEST_P(VertexFormatTest,Float16x2)691 TEST_P(VertexFormatTest, Float16x2) {
692     // Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
693     DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
694 
695     std::vector<uint16_t> vertexData =
696         Float32ToFloat16(std::vector<float>({14.8f, -0.0f, 22.5f, 1.3f, +0.0f, -24.8f}));
697 
698     DoVertexFormatTest(wgpu::VertexFormat::Float16x2, vertexData, vertexData);
699 }
700 
TEST_P(VertexFormatTest,Float16x4)701 TEST_P(VertexFormatTest, Float16x4) {
702     // Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
703     DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
704 
705     std::vector<uint16_t> vertexData = Float32ToFloat16(std::vector<float>(
706         {+0.0f, -16.8f, 18.2f, -0.0f, 12.5f, 1.3f, 14.8f, -12.4f, 22.5f, -48.8f, 47.4f, -24.8f}));
707 
708     DoVertexFormatTest(wgpu::VertexFormat::Float16x4, vertexData, vertexData);
709 }
710 
TEST_P(VertexFormatTest,Float32)711 TEST_P(VertexFormatTest, Float32) {
712     std::vector<float> vertexData = {1.3f, +0.0f, -0.0f};
713 
714     DoVertexFormatTest(wgpu::VertexFormat::Float32, vertexData, vertexData);
715 
716     vertexData = std::vector<float>{+1.0f, -1.0f, 18.23f};
717 
718     DoVertexFormatTest(wgpu::VertexFormat::Float32, vertexData, vertexData);
719 }
720 
TEST_P(VertexFormatTest,Float32x2)721 TEST_P(VertexFormatTest, Float32x2) {
722     // Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
723     DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
724 
725     std::vector<float> vertexData = {18.23f, -0.0f, +0.0f, +1.0f, 1.3f, -1.0f};
726 
727     DoVertexFormatTest(wgpu::VertexFormat::Float32x2, vertexData, vertexData);
728 }
729 
TEST_P(VertexFormatTest,Float32x3)730 TEST_P(VertexFormatTest, Float32x3) {
731     // Fails on NVIDIA's Vulkan drivers on CQ but passes locally.
732     DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
733 
734     std::vector<float> vertexData = {
735         +0.0f, -1.0f, -0.0f, 1.0f, 1.3f, 99.45f, 23.6f, -81.2f, 55.0f,
736     };
737 
738     DoVertexFormatTest(wgpu::VertexFormat::Float32x3, vertexData, vertexData);
739 }
740 
TEST_P(VertexFormatTest,Float32x4)741 TEST_P(VertexFormatTest, Float32x4) {
742     std::vector<float> vertexData = {
743         19.2f, -19.3f, +0.0f, 1.0f, -0.0f, 1.0f, 1.3f, -1.0f, 13.078f, 21.1965f, -1.1f, -1.2f,
744     };
745 
746     DoVertexFormatTest(wgpu::VertexFormat::Float32x4, vertexData, vertexData);
747 }
748 
TEST_P(VertexFormatTest,Uint32)749 TEST_P(VertexFormatTest, Uint32) {
750     std::vector<uint32_t> vertexData = {std::numeric_limits<uint32_t>::max(),
751                                         std::numeric_limits<uint16_t>::max(),
752                                         std::numeric_limits<uint8_t>::max()};
753 
754     DoVertexFormatTest(wgpu::VertexFormat::Uint32, vertexData, vertexData);
755 }
756 
TEST_P(VertexFormatTest,Uint32x2)757 TEST_P(VertexFormatTest, Uint32x2) {
758     std::vector<uint32_t> vertexData = {std::numeric_limits<uint32_t>::max(), 32,
759                                         std::numeric_limits<uint16_t>::max(), 64,
760                                         std::numeric_limits<uint8_t>::max(),  128};
761 
762     DoVertexFormatTest(wgpu::VertexFormat::Uint32x2, vertexData, vertexData);
763 }
764 
TEST_P(VertexFormatTest,Uint32x3)765 TEST_P(VertexFormatTest, Uint32x3) {
766     std::vector<uint32_t> vertexData = {std::numeric_limits<uint32_t>::max(), 32,   64,
767                                         std::numeric_limits<uint16_t>::max(), 164,  128,
768                                         std::numeric_limits<uint8_t>::max(),  1283, 256};
769 
770     DoVertexFormatTest(wgpu::VertexFormat::Uint32x3, vertexData, vertexData);
771 }
772 
TEST_P(VertexFormatTest,Uint32x4)773 TEST_P(VertexFormatTest, Uint32x4) {
774     std::vector<uint32_t> vertexData = {std::numeric_limits<uint32_t>::max(), 32,   64,  5460,
775                                         std::numeric_limits<uint16_t>::max(), 164,  128, 0,
776                                         std::numeric_limits<uint8_t>::max(),  1283, 256, 4567};
777 
778     DoVertexFormatTest(wgpu::VertexFormat::Uint32x4, vertexData, vertexData);
779 }
780 
TEST_P(VertexFormatTest,Sint32)781 TEST_P(VertexFormatTest, Sint32) {
782     std::vector<int32_t> vertexData = {std::numeric_limits<int32_t>::max(),
783                                        std::numeric_limits<int32_t>::min(),
784                                        std::numeric_limits<int8_t>::max()};
785 
786     DoVertexFormatTest(wgpu::VertexFormat::Sint32, vertexData, vertexData);
787 }
788 
TEST_P(VertexFormatTest,Sint32x2)789 TEST_P(VertexFormatTest, Sint32x2) {
790     std::vector<int32_t> vertexData = {
791         std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::min(),
792         std::numeric_limits<int16_t>::max(), std::numeric_limits<int16_t>::min(),
793         std::numeric_limits<int8_t>::max(),  std::numeric_limits<int8_t>::min()};
794 
795     DoVertexFormatTest(wgpu::VertexFormat::Sint32x2, vertexData, vertexData);
796 }
797 
TEST_P(VertexFormatTest,Sint32x3)798 TEST_P(VertexFormatTest, Sint32x3) {
799     std::vector<int32_t> vertexData = {
800         std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::min(), 64,
801         std::numeric_limits<int16_t>::max(), std::numeric_limits<int16_t>::min(), 128,
802         std::numeric_limits<int8_t>::max(),  std::numeric_limits<int8_t>::min(),  256};
803 
804     DoVertexFormatTest(wgpu::VertexFormat::Sint32x3, vertexData, vertexData);
805 }
806 
TEST_P(VertexFormatTest,Sint32x4)807 TEST_P(VertexFormatTest, Sint32x4) {
808     std::vector<int32_t> vertexData = {
809         std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::min(), 64,   -5460,
810         std::numeric_limits<int16_t>::max(), std::numeric_limits<int16_t>::min(), -128, 0,
811         std::numeric_limits<int8_t>::max(),  std::numeric_limits<int8_t>::min(),  256,  -4567};
812 
813     DoVertexFormatTest(wgpu::VertexFormat::Sint32x4, vertexData, vertexData);
814 }
815 
816 DAWN_INSTANTIATE_TEST(VertexFormatTest,
817                       D3D12Backend(),
818                       MetalBackend(),
819                       OpenGLBackend(),
820                       OpenGLESBackend(),
821                       VulkanBackend());
822