1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2022 The Khronos Group Inc.
6 * Copyright (c) 2022 Valve Corporation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Mesh Shader In Out Tests for VK_EXT_mesh_shader
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktMeshShaderInOutTestsEXT.hpp"
26 #include "vktTestCase.hpp"
27 #include "vktMeshShaderUtil.hpp"
28
29 #include "vkBufferWithMemory.hpp"
30 #include "vkImageWithMemory.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37
38 #include "tcuVector.hpp"
39 #include "tcuMaybe.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuImageCompare.hpp"
42
43 #include "deRandom.hpp"
44
45 #include <limits>
46 #include <vector>
47 #include <sstream>
48 #include <memory>
49
50 namespace vkt
51 {
52 namespace MeshShader
53 {
54
55 namespace
56 {
57
58 using GroupPtr = de::MovePtr<tcu::TestCaseGroup>;
59
60 using namespace vk;
61
62 // Tests checking varied interfaces between task, mesh and frag.
63
64 // Output images will use this format.
getOutputFormat()65 VkFormat getOutputFormat ()
66 {
67 return VK_FORMAT_R8G8B8A8_UNORM;
68 }
69
70 // Threshold that's reasonable for the previous format.
getCompareThreshold()71 float getCompareThreshold ()
72 {
73 return 0.005f; // 1/256 < 0.005 < 2/256
74 }
75
76 enum class Owner
77 {
78 VERTEX = 0,
79 PRIMITIVE,
80 };
81
82 enum class DataType
83 {
84 INTEGER = 0,
85 FLOAT,
86 };
87
88 // Note: 8-bit variables not available for Input/Output.
89 enum class BitWidth
90 {
91 B64 = 64,
92 B32 = 32,
93 B16 = 16,
94 };
95
96 enum class DataDim
97 {
98 SCALAR = 1,
99 VEC2 = 2,
100 VEC3 = 3,
101 VEC4 = 4,
102 };
103
104 enum class Interpolation
105 {
106 NORMAL = 0,
107 FLAT,
108 };
109
110 enum class Direction
111 {
112 IN = 0,
113 OUT,
114 };
115
116 // Interface variable.
117 struct IfaceVar
118 {
119 static constexpr uint32_t kNumVertices = 4u;
120 static constexpr uint32_t kNumPrimitives = 2u;
121 static constexpr uint32_t kVarsPerType = 2u;
122
IfaceVarvkt::MeshShader::__anon29329::IfaceVar123 IfaceVar (Owner owner_, DataType dataType_, BitWidth bitWidth_, DataDim dataDim_, Interpolation interpolation_, uint32_t index_)
124 : owner (owner_)
125 , dataType (dataType_)
126 , bitWidth (bitWidth_)
127 , dataDim (dataDim_)
128 , interpolation (interpolation_)
129 , index (index_)
130 {
131 DE_ASSERT(!(dataType == DataType::INTEGER && interpolation == Interpolation::NORMAL));
132 DE_ASSERT(!(owner == Owner::PRIMITIVE && interpolation == Interpolation::NORMAL));
133 DE_ASSERT(!(dataType == DataType::FLOAT && bitWidth == BitWidth::B64 && interpolation == Interpolation::NORMAL));
134 DE_ASSERT(index < kVarsPerType);
135 }
136
137 // This constructor needs to be defined for the code to compile, but it should never be actually called.
138 // To make sure it's not used, the index is defined to be very large, which should trigger the assertion in getName() below.
139 IfaceVar ()
140 : owner (Owner::VERTEX)
141 , dataType (DataType::FLOAT)
142 , bitWidth (BitWidth::B32)
143 , dataDim (DataDim::VEC4)
144 , interpolation (Interpolation::NORMAL)
145 , index (std::numeric_limits<uint32_t>::max())
146 {
147 }
148
149 Owner owner;
150 DataType dataType;
151 BitWidth bitWidth;
152 DataDim dataDim;
153 Interpolation interpolation;
154 uint32_t index; // In case there are several variables matching this type.
155
156 // The variable name will be unique and depend on its type.
157 std::string getName () const
158 {
159 DE_ASSERT(index < kVarsPerType);
160
161 std::ostringstream name;
162 name
163 << ((owner == Owner::VERTEX) ? "vert" : "prim") << "_"
164 << ((dataType == DataType::INTEGER) ? "i" : "f") << static_cast<int>(bitWidth)
165 << "d" << static_cast<int>(dataDim) << "_"
166 << ((interpolation == Interpolation::NORMAL) ? "inter" : "flat") << "_"
167 << index
168 ;
169 return name.str();
170 }
171
172 // Get location size according to the type.
173 uint32_t getLocationSize () const
174 {
175 return ((bitWidth == BitWidth::B64 && dataDim >= DataDim::VEC3) ? 2u : 1u);
176 }
177
178 // Get the variable type in GLSL.
179 std::string getGLSLType () const
180 {
181 const auto widthStr = std::to_string(static_cast<int>(bitWidth));
182 const auto dimStr = std::to_string(static_cast<int>(dataDim));
183 const auto shortTypeStr = ((dataType == DataType::INTEGER) ? "i" : "f");
184 const auto typeStr = ((dataType == DataType::INTEGER) ? "int" : "float");
185
186 if (dataDim == DataDim::SCALAR)
187 return typeStr + widthStr + "_t"; // e.g. int32_t or float16_t
188 return shortTypeStr + widthStr + "vec" + dimStr; // e.g. i16vec2 or f64vec4.
189 }
190
191 // Get a simple declaration of type and name. This can be reused for several things.
192 std::string getTypeAndName () const
193 {
194 return getGLSLType() + " " + getName();
195 }
196
197 std::string getTypeAndNameDecl (bool arrayDecl = false) const
198 {
199 std::ostringstream decl;
200 decl << " " << getTypeAndName();
201 if (arrayDecl)
202 decl << "[" << ((owner == Owner::PRIMITIVE) ? IfaceVar::kNumPrimitives : IfaceVar::kNumVertices) << "]";
203 decl << ";\n";
204 return decl.str();
205 }
206
207 // Variable declaration statement given its location and direction.
208 std::string getLocationDecl (size_t location, Direction direction) const
209 {
210 std::ostringstream decl;
211 decl
212 << "layout (location=" << location << ") "
213 << ((direction == Direction::IN) ? "in" : "out") << " "
214 << ((owner == Owner::PRIMITIVE) ? "perprimitiveEXT " : "")
215 << ((interpolation == Interpolation::FLAT) ? "flat " : "")
216 << getTypeAndName()
217 << ((direction == Direction::OUT) ? "[]" : "") << ";\n"
218 ;
219 return decl.str();
220 }
221
222 // Get the name of the source data for this variable. Tests will use a storage buffer for the per-vertex data and a uniform
223 // buffer for the per-primitive data. The names in those will match.
224 std::string getDataSourceName () const
225 {
226 // per-primitive data or per-vertex data buffers.
227 return ((owner == Owner::PRIMITIVE) ? "ppd" : "pvd") + ("." + getName());
228 }
229
230 // Get the boolean check variable name (see below).
231 std::string getCheckName () const
232 {
233 return "good_" + getName();
234 }
235
236 // Get the check statement that would be used in the fragment shader.
237 std::string getCheckStatement () const
238 {
239 std::ostringstream check;
240 const auto sourceName = getDataSourceName();
241 const auto glslType = getGLSLType();
242 const auto name = getName();
243
244 check << " bool " << getCheckName() << " = ";
245 if (owner == Owner::VERTEX)
246 {
247 // There will be 4 values in the buffers.
248 std::ostringstream maxElem;
249 std::ostringstream minElem;
250
251 maxElem << glslType << "(max(max(max(" << sourceName << "[0], " << sourceName << "[1]), " << sourceName << "[2]), " << sourceName << "[3]))";
252 minElem << glslType << "(min(min(min(" << sourceName << "[0], " << sourceName << "[1]), " << sourceName << "[2]), " << sourceName << "[3]))";
253
254 if (dataDim == DataDim::SCALAR)
255 {
256 check << "(" << name << " <= " << maxElem.str() << ") && (" << name << " >= " << minElem.str() << ")";
257 }
258 else
259 {
260 check << "all(lessThanEqual(" << name << ", " << maxElem.str() << ")) && "
261 << "all(greaterThanEqual(" << name << ", " << minElem.str() << "))";
262 }
263 }
264 else if (owner == Owner::PRIMITIVE)
265 {
266 // There will be 2 values in the buffers.
267 check << "((gl_PrimitiveID == 0 || gl_PrimitiveID == 1) && ("
268 << "(gl_PrimitiveID == 0 && " << name << " == " << sourceName << "[0]) || "
269 << "(gl_PrimitiveID == 1 && " << name << " == " << sourceName << "[1])))";
270 }
271 check << ";\n";
272
273 return check.str();
274 }
275
276 // Get an assignment statement for an out variable.
277 std::string getAssignmentStatement (size_t arrayIndex, const std::string& leftPrefix, const std::string& rightPrefix) const
278 {
279 const auto name = getName();
280 const auto typeStr = getGLSLType();
281 std::ostringstream stmt;
282
283 stmt << " " << leftPrefix << (leftPrefix.empty() ? "" : ".") << name << "[" << arrayIndex << "] = " << typeStr << "(" << rightPrefix << (rightPrefix.empty() ? "" : ".") << name << "[" << arrayIndex << "]);\n";
284 return stmt.str();
285 }
286
287 // Get the corresponding array size based on the owner (vertex or primitive)
288 uint32_t getArraySize () const
289 {
290 return ((owner == Owner::PRIMITIVE) ? IfaceVar::kNumPrimitives : IfaceVar::kNumVertices);
291 }
292
293 };
294
295 using IfaceVarVec = std::vector<IfaceVar>;
296 using IfaceVarVecPtr = std::unique_ptr<IfaceVarVec>;
297
298 struct InterfaceVariableParams
299 {
300 InterfaceVariableParams (const tcu::Maybe<tcu::UVec3>& taskCount_, const tcu::UVec3& meshCount_, uint32_t width_, uint32_t height_,
301 bool useInt64_, bool useFloat64_, bool useInt16_, bool useFloat16_, IfaceVarVecPtr vars_)
302 : taskCount (taskCount_)
303 , meshCount (meshCount_)
304 , width (width_)
305 , height (height_)
306 , useInt64 (useInt64_)
307 , useFloat64 (useFloat64_)
308 , useInt16 (useInt16_)
309 , useFloat16 (useFloat16_)
310 , ifaceVars (std::move(vars_))
311 {}
312
313 bool needsTaskShader () const
314 {
315 return static_cast<bool>(taskCount);
316 }
317
318 tcu::UVec3 drawCount () const
319 {
320 if (needsTaskShader())
321 return taskCount.get();
322 return meshCount;
323 }
324
325 tcu::Maybe<tcu::UVec3> taskCount;
326 tcu::UVec3 meshCount;
327
328 uint32_t width;
329 uint32_t height;
330
331 // These need to match the list of interface variables.
332 bool useInt64;
333 bool useFloat64;
334 bool useInt16;
335 bool useFloat16;
336
337 IfaceVarVecPtr ifaceVars;
338 };
339
340 using ParamsPtr = std::unique_ptr<InterfaceVariableParams>;
341
342 class InterfaceVariablesCase : public vkt::TestCase
343 {
344 public:
345 InterfaceVariablesCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
346 : vkt::TestCase (testCtx, name, description)
347 , m_params (std::move(params))
348 {}
349 virtual ~InterfaceVariablesCase (void) {}
350
351 TestInstance* createInstance (Context& context) const override;
352 void checkSupport (Context& context) const override;
353 void initPrograms (vk::SourceCollections& programCollection) const override;
354
355 // Note data types in the input buffers are always plain floats or ints. They will be converted to the appropriate type when
356 // copying them in or out of output variables. Note we have two variables per type, as per IfaceVar::kVarsPerType.
357
358 struct PerVertexData
359 {
360 // Interpolated floats.
361
362 tcu::Vec4 vert_f64d4_inter_0[IfaceVar::kNumVertices];
363 tcu::Vec4 vert_f64d4_inter_1[IfaceVar::kNumVertices];
364
365 tcu::Vec3 vert_f64d3_inter_0[IfaceVar::kNumVertices];
366 tcu::Vec3 vert_f64d3_inter_1[IfaceVar::kNumVertices];
367
368 tcu::Vec2 vert_f64d2_inter_0[IfaceVar::kNumVertices];
369 tcu::Vec2 vert_f64d2_inter_1[IfaceVar::kNumVertices];
370
371 float vert_f64d1_inter_0[IfaceVar::kNumVertices];
372 float vert_f64d1_inter_1[IfaceVar::kNumVertices];
373
374 tcu::Vec4 vert_f32d4_inter_0[IfaceVar::kNumVertices];
375 tcu::Vec4 vert_f32d4_inter_1[IfaceVar::kNumVertices];
376
377 tcu::Vec3 vert_f32d3_inter_0[IfaceVar::kNumVertices];
378 tcu::Vec3 vert_f32d3_inter_1[IfaceVar::kNumVertices];
379
380 tcu::Vec2 vert_f32d2_inter_0[IfaceVar::kNumVertices];
381 tcu::Vec2 vert_f32d2_inter_1[IfaceVar::kNumVertices];
382
383 float vert_f32d1_inter_0[IfaceVar::kNumVertices];
384 float vert_f32d1_inter_1[IfaceVar::kNumVertices];
385
386 tcu::Vec4 vert_f16d4_inter_0[IfaceVar::kNumVertices];
387 tcu::Vec4 vert_f16d4_inter_1[IfaceVar::kNumVertices];
388
389 tcu::Vec3 vert_f16d3_inter_0[IfaceVar::kNumVertices];
390 tcu::Vec3 vert_f16d3_inter_1[IfaceVar::kNumVertices];
391
392 tcu::Vec2 vert_f16d2_inter_0[IfaceVar::kNumVertices];
393 tcu::Vec2 vert_f16d2_inter_1[IfaceVar::kNumVertices];
394
395 float vert_f16d1_inter_0[IfaceVar::kNumVertices];
396 float vert_f16d1_inter_1[IfaceVar::kNumVertices];
397
398 // Flat floats.
399
400 tcu::Vec4 vert_f64d4_flat_0[IfaceVar::kNumVertices];
401 tcu::Vec4 vert_f64d4_flat_1[IfaceVar::kNumVertices];
402
403 tcu::Vec3 vert_f64d3_flat_0[IfaceVar::kNumVertices];
404 tcu::Vec3 vert_f64d3_flat_1[IfaceVar::kNumVertices];
405
406 tcu::Vec2 vert_f64d2_flat_0[IfaceVar::kNumVertices];
407 tcu::Vec2 vert_f64d2_flat_1[IfaceVar::kNumVertices];
408
409 float vert_f64d1_flat_0[IfaceVar::kNumVertices];
410 float vert_f64d1_flat_1[IfaceVar::kNumVertices];
411
412 tcu::Vec4 vert_f32d4_flat_0[IfaceVar::kNumVertices];
413 tcu::Vec4 vert_f32d4_flat_1[IfaceVar::kNumVertices];
414
415 tcu::Vec3 vert_f32d3_flat_0[IfaceVar::kNumVertices];
416 tcu::Vec3 vert_f32d3_flat_1[IfaceVar::kNumVertices];
417
418 tcu::Vec2 vert_f32d2_flat_0[IfaceVar::kNumVertices];
419 tcu::Vec2 vert_f32d2_flat_1[IfaceVar::kNumVertices];
420
421 float vert_f32d1_flat_0[IfaceVar::kNumVertices];
422 float vert_f32d1_flat_1[IfaceVar::kNumVertices];
423
424 tcu::Vec4 vert_f16d4_flat_0[IfaceVar::kNumVertices];
425 tcu::Vec4 vert_f16d4_flat_1[IfaceVar::kNumVertices];
426
427 tcu::Vec3 vert_f16d3_flat_0[IfaceVar::kNumVertices];
428 tcu::Vec3 vert_f16d3_flat_1[IfaceVar::kNumVertices];
429
430 tcu::Vec2 vert_f16d2_flat_0[IfaceVar::kNumVertices];
431 tcu::Vec2 vert_f16d2_flat_1[IfaceVar::kNumVertices];
432
433 float vert_f16d1_flat_0[IfaceVar::kNumVertices];
434 float vert_f16d1_flat_1[IfaceVar::kNumVertices];
435
436 // Flat ints.
437
438 tcu::IVec4 vert_i64d4_flat_0[IfaceVar::kNumVertices];
439 tcu::IVec4 vert_i64d4_flat_1[IfaceVar::kNumVertices];
440
441 tcu::IVec3 vert_i64d3_flat_0[IfaceVar::kNumVertices];
442 tcu::IVec3 vert_i64d3_flat_1[IfaceVar::kNumVertices];
443
444 tcu::IVec2 vert_i64d2_flat_0[IfaceVar::kNumVertices];
445 tcu::IVec2 vert_i64d2_flat_1[IfaceVar::kNumVertices];
446
447 int32_t vert_i64d1_flat_0[IfaceVar::kNumVertices];
448 int32_t vert_i64d1_flat_1[IfaceVar::kNumVertices];
449
450 tcu::IVec4 vert_i32d4_flat_0[IfaceVar::kNumVertices];
451 tcu::IVec4 vert_i32d4_flat_1[IfaceVar::kNumVertices];
452
453 tcu::IVec3 vert_i32d3_flat_0[IfaceVar::kNumVertices];
454 tcu::IVec3 vert_i32d3_flat_1[IfaceVar::kNumVertices];
455
456 tcu::IVec2 vert_i32d2_flat_0[IfaceVar::kNumVertices];
457 tcu::IVec2 vert_i32d2_flat_1[IfaceVar::kNumVertices];
458
459 int32_t vert_i32d1_flat_0[IfaceVar::kNumVertices];
460 int32_t vert_i32d1_flat_1[IfaceVar::kNumVertices];
461
462 tcu::IVec4 vert_i16d4_flat_0[IfaceVar::kNumVertices];
463 tcu::IVec4 vert_i16d4_flat_1[IfaceVar::kNumVertices];
464
465 tcu::IVec3 vert_i16d3_flat_0[IfaceVar::kNumVertices];
466 tcu::IVec3 vert_i16d3_flat_1[IfaceVar::kNumVertices];
467
468 tcu::IVec2 vert_i16d2_flat_0[IfaceVar::kNumVertices];
469 tcu::IVec2 vert_i16d2_flat_1[IfaceVar::kNumVertices];
470
471 int32_t vert_i16d1_flat_0[IfaceVar::kNumVertices];
472 int32_t vert_i16d1_flat_1[IfaceVar::kNumVertices];
473
474 };
475
476 struct PerPrimitiveData
477 {
478 // Flat floats.
479
480 tcu::Vec4 prim_f64d4_flat_0[IfaceVar::kNumPrimitives];
481 tcu::Vec4 prim_f64d4_flat_1[IfaceVar::kNumPrimitives];
482
483 tcu::Vec3 prim_f64d3_flat_0[IfaceVar::kNumPrimitives];
484 tcu::Vec3 prim_f64d3_flat_1[IfaceVar::kNumPrimitives];
485
486 tcu::Vec2 prim_f64d2_flat_0[IfaceVar::kNumPrimitives];
487 tcu::Vec2 prim_f64d2_flat_1[IfaceVar::kNumPrimitives];
488
489 float prim_f64d1_flat_0[IfaceVar::kNumPrimitives];
490 float prim_f64d1_flat_1[IfaceVar::kNumPrimitives];
491
492 tcu::Vec4 prim_f32d4_flat_0[IfaceVar::kNumPrimitives];
493 tcu::Vec4 prim_f32d4_flat_1[IfaceVar::kNumPrimitives];
494
495 tcu::Vec3 prim_f32d3_flat_0[IfaceVar::kNumPrimitives];
496 tcu::Vec3 prim_f32d3_flat_1[IfaceVar::kNumPrimitives];
497
498 tcu::Vec2 prim_f32d2_flat_0[IfaceVar::kNumPrimitives];
499 tcu::Vec2 prim_f32d2_flat_1[IfaceVar::kNumPrimitives];
500
501 float prim_f32d1_flat_0[IfaceVar::kNumPrimitives];
502 float prim_f32d1_flat_1[IfaceVar::kNumPrimitives];
503
504 tcu::Vec4 prim_f16d4_flat_0[IfaceVar::kNumPrimitives];
505 tcu::Vec4 prim_f16d4_flat_1[IfaceVar::kNumPrimitives];
506
507 tcu::Vec3 prim_f16d3_flat_0[IfaceVar::kNumPrimitives];
508 tcu::Vec3 prim_f16d3_flat_1[IfaceVar::kNumPrimitives];
509
510 tcu::Vec2 prim_f16d2_flat_0[IfaceVar::kNumPrimitives];
511 tcu::Vec2 prim_f16d2_flat_1[IfaceVar::kNumPrimitives];
512
513 float prim_f16d1_flat_0[IfaceVar::kNumPrimitives];
514 float prim_f16d1_flat_1[IfaceVar::kNumPrimitives];
515
516 // Flat ints.
517
518 tcu::IVec4 prim_i64d4_flat_0[IfaceVar::kNumPrimitives];
519 tcu::IVec4 prim_i64d4_flat_1[IfaceVar::kNumPrimitives];
520
521 tcu::IVec3 prim_i64d3_flat_0[IfaceVar::kNumPrimitives];
522 tcu::IVec3 prim_i64d3_flat_1[IfaceVar::kNumPrimitives];
523
524 tcu::IVec2 prim_i64d2_flat_0[IfaceVar::kNumPrimitives];
525 tcu::IVec2 prim_i64d2_flat_1[IfaceVar::kNumPrimitives];
526
527 int32_t prim_i64d1_flat_0[IfaceVar::kNumPrimitives];
528 int32_t prim_i64d1_flat_1[IfaceVar::kNumPrimitives];
529
530 tcu::IVec4 prim_i32d4_flat_0[IfaceVar::kNumPrimitives];
531 tcu::IVec4 prim_i32d4_flat_1[IfaceVar::kNumPrimitives];
532
533 tcu::IVec3 prim_i32d3_flat_0[IfaceVar::kNumPrimitives];
534 tcu::IVec3 prim_i32d3_flat_1[IfaceVar::kNumPrimitives];
535
536 tcu::IVec2 prim_i32d2_flat_0[IfaceVar::kNumPrimitives];
537 tcu::IVec2 prim_i32d2_flat_1[IfaceVar::kNumPrimitives];
538
539 int32_t prim_i32d1_flat_0[IfaceVar::kNumPrimitives];
540 int32_t prim_i32d1_flat_1[IfaceVar::kNumPrimitives];
541
542 tcu::IVec4 prim_i16d4_flat_0[IfaceVar::kNumPrimitives];
543 tcu::IVec4 prim_i16d4_flat_1[IfaceVar::kNumPrimitives];
544
545 tcu::IVec3 prim_i16d3_flat_0[IfaceVar::kNumPrimitives];
546 tcu::IVec3 prim_i16d3_flat_1[IfaceVar::kNumPrimitives];
547
548 tcu::IVec2 prim_i16d2_flat_0[IfaceVar::kNumPrimitives];
549 tcu::IVec2 prim_i16d2_flat_1[IfaceVar::kNumPrimitives];
550
551 int32_t prim_i16d1_flat_0[IfaceVar::kNumPrimitives];
552 int32_t prim_i16d1_flat_1[IfaceVar::kNumPrimitives];
553
554 };
555
556 static constexpr uint32_t kGlslangBuiltInCount = 4u;
557 static constexpr uint32_t kMaxLocations = 16u;
558
559 protected:
560 ParamsPtr m_params;
561 };
562
563 class InterfaceVariablesInstance : public vkt::TestInstance
564 {
565 public:
566 InterfaceVariablesInstance (Context& context, const InterfaceVariableParams* params)
567 : vkt::TestInstance (context)
568 , m_params (params)
569 {}
570 virtual ~InterfaceVariablesInstance (void) {}
571
572 void generateReferenceLevel ();
573 tcu::TestStatus iterate (void) override;
574 bool verifyResult (const tcu::ConstPixelBufferAccess& referenceAccess) const;
575
576 protected:
577 const InterfaceVariableParams* m_params;
578 std::unique_ptr<tcu::TextureLevel> m_referenceLevel;
579 };
580
581 TestInstance* InterfaceVariablesCase::createInstance (Context& context) const
582 {
583 return new InterfaceVariablesInstance(context, m_params.get());
584 }
585
586 void InterfaceVariablesCase::checkSupport (Context& context) const
587 {
588 const auto params = dynamic_cast<InterfaceVariableParams*>(m_params.get());
589 DE_ASSERT(params);
590
591 checkTaskMeshShaderSupportEXT(context, m_params->needsTaskShader(), true);
592
593 if (params->useFloat64)
594 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_FLOAT64);
595
596 if (params->useInt64)
597 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_INT64);
598
599 if (params->useInt16)
600 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_INT16);
601
602 if (params->useFloat16)
603 {
604 const auto& features = context.getShaderFloat16Int8Features();
605 if (!features.shaderFloat16)
606 TCU_THROW(NotSupportedError, "shaderFloat16 feature not supported");
607 }
608
609 if (params->useInt16 || params->useFloat16)
610 {
611 const auto& features = context.get16BitStorageFeatures();
612 if (!features.storageInputOutput16)
613 TCU_THROW(NotSupportedError, "storageInputOutput16 feature not supported");
614 }
615
616 // glslang will use several built-ins in the generated mesh code, which count against the location and component limits.
617 {
618 const auto neededComponents = (kGlslangBuiltInCount + kMaxLocations) * 4u;
619 const auto& properties = context.getMeshShaderPropertiesEXT();
620
621 // Making this a TCU_FAIL since the minimum maxMeshOutputComponents is 128, which should allow us to use 32 locations and we
622 // use only 16 plus a few built-ins.
623 if (neededComponents > properties.maxMeshOutputComponents)
624 TCU_FAIL("maxMeshOutputComponents too low to run this test");
625 }
626 }
627
628 void InterfaceVariablesCase::initPrograms (vk::SourceCollections& programCollection) const
629 {
630 const auto buildOptions = getMinMeshEXTBuildOptions(programCollection.usedVulkanVersion);
631
632 // Bindings needs to match the PerVertexData and PerPrimitiveData structures.
633 std::ostringstream bindings;
634 bindings
635 << "layout(set=0, binding=0, std430) readonly buffer PerVertexBlock {\n"
636 << " vec4 vert_f64d4_inter_0[" << IfaceVar::kNumVertices << "];\n"
637 << " vec4 vert_f64d4_inter_1[" << IfaceVar::kNumVertices << "];\n"
638 << " vec3 vert_f64d3_inter_0[" << IfaceVar::kNumVertices << "];\n"
639 << " vec3 vert_f64d3_inter_1[" << IfaceVar::kNumVertices << "];\n"
640 << " vec2 vert_f64d2_inter_0[" << IfaceVar::kNumVertices << "];\n"
641 << " vec2 vert_f64d2_inter_1[" << IfaceVar::kNumVertices << "];\n"
642 << " float vert_f64d1_inter_0[" << IfaceVar::kNumVertices << "];\n"
643 << " float vert_f64d1_inter_1[" << IfaceVar::kNumVertices << "];\n"
644 << " vec4 vert_f32d4_inter_0[" << IfaceVar::kNumVertices << "];\n"
645 << " vec4 vert_f32d4_inter_1[" << IfaceVar::kNumVertices << "];\n"
646 << " vec3 vert_f32d3_inter_0[" << IfaceVar::kNumVertices << "];\n"
647 << " vec3 vert_f32d3_inter_1[" << IfaceVar::kNumVertices << "];\n"
648 << " vec2 vert_f32d2_inter_0[" << IfaceVar::kNumVertices << "];\n"
649 << " vec2 vert_f32d2_inter_1[" << IfaceVar::kNumVertices << "];\n"
650 << " float vert_f32d1_inter_0[" << IfaceVar::kNumVertices << "];\n"
651 << " float vert_f32d1_inter_1[" << IfaceVar::kNumVertices << "];\n"
652 << " vec4 vert_f16d4_inter_0[" << IfaceVar::kNumVertices << "];\n"
653 << " vec4 vert_f16d4_inter_1[" << IfaceVar::kNumVertices << "];\n"
654 << " vec3 vert_f16d3_inter_0[" << IfaceVar::kNumVertices << "];\n"
655 << " vec3 vert_f16d3_inter_1[" << IfaceVar::kNumVertices << "];\n"
656 << " vec2 vert_f16d2_inter_0[" << IfaceVar::kNumVertices << "];\n"
657 << " vec2 vert_f16d2_inter_1[" << IfaceVar::kNumVertices << "];\n"
658 << " float vert_f16d1_inter_0[" << IfaceVar::kNumVertices << "];\n"
659 << " float vert_f16d1_inter_1[" << IfaceVar::kNumVertices << "];\n"
660 << " vec4 vert_f64d4_flat_0[" << IfaceVar::kNumVertices << "];\n"
661 << " vec4 vert_f64d4_flat_1[" << IfaceVar::kNumVertices << "];\n"
662 << " vec3 vert_f64d3_flat_0[" << IfaceVar::kNumVertices << "];\n"
663 << " vec3 vert_f64d3_flat_1[" << IfaceVar::kNumVertices << "];\n"
664 << " vec2 vert_f64d2_flat_0[" << IfaceVar::kNumVertices << "];\n"
665 << " vec2 vert_f64d2_flat_1[" << IfaceVar::kNumVertices << "];\n"
666 << " float vert_f64d1_flat_0[" << IfaceVar::kNumVertices << "];\n"
667 << " float vert_f64d1_flat_1[" << IfaceVar::kNumVertices << "];\n"
668 << " vec4 vert_f32d4_flat_0[" << IfaceVar::kNumVertices << "];\n"
669 << " vec4 vert_f32d4_flat_1[" << IfaceVar::kNumVertices << "];\n"
670 << " vec3 vert_f32d3_flat_0[" << IfaceVar::kNumVertices << "];\n"
671 << " vec3 vert_f32d3_flat_1[" << IfaceVar::kNumVertices << "];\n"
672 << " vec2 vert_f32d2_flat_0[" << IfaceVar::kNumVertices << "];\n"
673 << " vec2 vert_f32d2_flat_1[" << IfaceVar::kNumVertices << "];\n"
674 << " float vert_f32d1_flat_0[" << IfaceVar::kNumVertices << "];\n"
675 << " float vert_f32d1_flat_1[" << IfaceVar::kNumVertices << "];\n"
676 << " vec4 vert_f16d4_flat_0[" << IfaceVar::kNumVertices << "];\n"
677 << " vec4 vert_f16d4_flat_1[" << IfaceVar::kNumVertices << "];\n"
678 << " vec3 vert_f16d3_flat_0[" << IfaceVar::kNumVertices << "];\n"
679 << " vec3 vert_f16d3_flat_1[" << IfaceVar::kNumVertices << "];\n"
680 << " vec2 vert_f16d2_flat_0[" << IfaceVar::kNumVertices << "];\n"
681 << " vec2 vert_f16d2_flat_1[" << IfaceVar::kNumVertices << "];\n"
682 << " float vert_f16d1_flat_0[" << IfaceVar::kNumVertices << "];\n"
683 << " float vert_f16d1_flat_1[" << IfaceVar::kNumVertices << "];\n"
684 << " ivec4 vert_i64d4_flat_0[" << IfaceVar::kNumVertices << "];\n"
685 << " ivec4 vert_i64d4_flat_1[" << IfaceVar::kNumVertices << "];\n"
686 << " ivec3 vert_i64d3_flat_0[" << IfaceVar::kNumVertices << "];\n"
687 << " ivec3 vert_i64d3_flat_1[" << IfaceVar::kNumVertices << "];\n"
688 << " ivec2 vert_i64d2_flat_0[" << IfaceVar::kNumVertices << "];\n"
689 << " ivec2 vert_i64d2_flat_1[" << IfaceVar::kNumVertices << "];\n"
690 << " int vert_i64d1_flat_0[" << IfaceVar::kNumVertices << "];\n"
691 << " int vert_i64d1_flat_1[" << IfaceVar::kNumVertices << "];\n"
692 << " ivec4 vert_i32d4_flat_0[" << IfaceVar::kNumVertices << "];\n"
693 << " ivec4 vert_i32d4_flat_1[" << IfaceVar::kNumVertices << "];\n"
694 << " ivec3 vert_i32d3_flat_0[" << IfaceVar::kNumVertices << "];\n"
695 << " ivec3 vert_i32d3_flat_1[" << IfaceVar::kNumVertices << "];\n"
696 << " ivec2 vert_i32d2_flat_0[" << IfaceVar::kNumVertices << "];\n"
697 << " ivec2 vert_i32d2_flat_1[" << IfaceVar::kNumVertices << "];\n"
698 << " int vert_i32d1_flat_0[" << IfaceVar::kNumVertices << "];\n"
699 << " int vert_i32d1_flat_1[" << IfaceVar::kNumVertices << "];\n"
700 << " ivec4 vert_i16d4_flat_0[" << IfaceVar::kNumVertices << "];\n"
701 << " ivec4 vert_i16d4_flat_1[" << IfaceVar::kNumVertices << "];\n"
702 << " ivec3 vert_i16d3_flat_0[" << IfaceVar::kNumVertices << "];\n"
703 << " ivec3 vert_i16d3_flat_1[" << IfaceVar::kNumVertices << "];\n"
704 << " ivec2 vert_i16d2_flat_0[" << IfaceVar::kNumVertices << "];\n"
705 << " ivec2 vert_i16d2_flat_1[" << IfaceVar::kNumVertices << "];\n"
706 << " int vert_i16d1_flat_0[" << IfaceVar::kNumVertices << "];\n"
707 << " int vert_i16d1_flat_1[" << IfaceVar::kNumVertices << "];\n"
708 << " } pvd;\n"
709 << "\n"
710 << "layout(set=0, binding=1, std430) readonly buffer PerPrimitiveBlock {\n"
711 << " vec4 prim_f64d4_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
712 << " vec4 prim_f64d4_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
713 << " vec3 prim_f64d3_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
714 << " vec3 prim_f64d3_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
715 << " vec2 prim_f64d2_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
716 << " vec2 prim_f64d2_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
717 << " float prim_f64d1_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
718 << " float prim_f64d1_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
719 << " vec4 prim_f32d4_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
720 << " vec4 prim_f32d4_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
721 << " vec3 prim_f32d3_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
722 << " vec3 prim_f32d3_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
723 << " vec2 prim_f32d2_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
724 << " vec2 prim_f32d2_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
725 << " float prim_f32d1_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
726 << " float prim_f32d1_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
727 << " vec4 prim_f16d4_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
728 << " vec4 prim_f16d4_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
729 << " vec3 prim_f16d3_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
730 << " vec3 prim_f16d3_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
731 << " vec2 prim_f16d2_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
732 << " vec2 prim_f16d2_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
733 << " float prim_f16d1_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
734 << " float prim_f16d1_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
735 << " ivec4 prim_i64d4_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
736 << " ivec4 prim_i64d4_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
737 << " ivec3 prim_i64d3_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
738 << " ivec3 prim_i64d3_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
739 << " ivec2 prim_i64d2_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
740 << " ivec2 prim_i64d2_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
741 << " int prim_i64d1_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
742 << " int prim_i64d1_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
743 << " ivec4 prim_i32d4_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
744 << " ivec4 prim_i32d4_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
745 << " ivec3 prim_i32d3_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
746 << " ivec3 prim_i32d3_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
747 << " ivec2 prim_i32d2_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
748 << " ivec2 prim_i32d2_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
749 << " int prim_i32d1_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
750 << " int prim_i32d1_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
751 << " ivec4 prim_i16d4_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
752 << " ivec4 prim_i16d4_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
753 << " ivec3 prim_i16d3_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
754 << " ivec3 prim_i16d3_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
755 << " ivec2 prim_i16d2_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
756 << " ivec2 prim_i16d2_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
757 << " int prim_i16d1_flat_0[" << IfaceVar::kNumPrimitives << "];\n"
758 << " int prim_i16d1_flat_1[" << IfaceVar::kNumPrimitives << "];\n"
759 << " } ppd;\n"
760 << "\n"
761 ;
762 const auto bindingsDecl = bindings.str();
763
764 const auto params = dynamic_cast<InterfaceVariableParams*>(m_params.get());
765 DE_ASSERT(params);
766 const auto& varVec = *(params->ifaceVars);
767
768 std::ostringstream frag;
769 frag
770 << "#version 450\n"
771 << "#extension GL_EXT_mesh_shader : enable\n"
772 << "#extension GL_EXT_shader_explicit_arithmetic_types : enable\n"
773 << "\n"
774 << bindingsDecl
775 ;
776
777 // Declare interface variables as Input in the fragment shader.
778 {
779 uint32_t usedLocations = 0u;
780 for (const auto& var : varVec)
781 {
782 frag << var.getLocationDecl(usedLocations, Direction::IN);
783 usedLocations += var.getLocationSize();
784 }
785 }
786
787 frag
788 << "\n"
789 << "layout (location=0) out vec4 outColor;\n"
790 << "\n"
791 << "void main ()\n"
792 << "{\n"
793 ;
794
795 // Emit checks for each variable value in the fragment shader.
796 std::ostringstream allConditions;
797
798 for (size_t i = 0; i < varVec.size(); ++i)
799 {
800 frag << varVec[i].getCheckStatement();
801 allConditions << ((i == 0) ? "" : " && ") << varVec[i].getCheckName();
802 }
803
804 // Emit final check.
805 frag
806 << " if (" << allConditions.str() << ") {\n"
807 << " outColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
808 << " } else {\n"
809 << " outColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
810 << " }\n"
811 << "}\n"
812 ;
813 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str()) << buildOptions;
814
815 std::ostringstream pvdDataDeclStream;
816 pvdDataDeclStream
817 << " vec4 positions[4];\n"
818 << " float pointSizes[4];\n"
819 << " float clipDistances[4];\n"
820 << " vec4 custom1[4];\n"
821 << " float custom2[4];\n"
822 << " int custom3[4];\n"
823 ;
824 const auto pvdDataDecl = pvdDataDeclStream.str();
825
826 std::ostringstream ppdDataDeclStream;
827 ppdDataDeclStream
828 << " int primitiveIds[2];\n"
829 << " int viewportIndices[2];\n"
830 << " uvec4 custom4[2];\n"
831 << " float custom5[2];\n"
832 ;
833 const auto ppdDataDecl = ppdDataDeclStream.str();
834
835 std::ostringstream taskDataStream;
836 taskDataStream << "struct TaskData {\n";
837 for (size_t i = 0; i < varVec.size(); ++i)
838 taskDataStream << varVec[i].getTypeAndNameDecl(/*arrayDecl*/true);
839 taskDataStream << "};\n\n";
840 taskDataStream << "taskPayloadSharedEXT TaskData td;\n";
841
842 const auto taskShader = m_params->needsTaskShader();
843 const auto taskDataDecl = taskDataStream.str();
844 const auto meshPvdPrefix = (taskShader ? "td" : "pvd");
845 const auto meshPpdPrefix = (taskShader ? "td" : "ppd");
846
847 std::ostringstream mesh;
848 mesh
849 << "#version 450\n"
850 << "#extension GL_EXT_mesh_shader : enable\n"
851 << "#extension GL_EXT_shader_explicit_arithmetic_types : enable\n"
852 << "\n"
853 << "layout (local_size_x=1) in;\n"
854 << "layout (max_primitives=" << IfaceVar::kNumPrimitives << ", max_vertices=" << IfaceVar::kNumVertices << ") out;\n"
855 << "layout (triangles) out;\n"
856 << "\n"
857 ;
858
859 // Declare interface variables as Output variables.
860 {
861 uint32_t usedLocations = 0u;
862 for (const auto& var : varVec)
863 {
864 mesh << var.getLocationDecl(usedLocations, Direction::OUT);
865 usedLocations += var.getLocationSize();
866 }
867 }
868
869 mesh
870 << "out gl_MeshPerVertexEXT {\n"
871 << " vec4 gl_Position;\n"
872 << "} gl_MeshVerticesEXT[];\n"
873 << "out perprimitiveEXT gl_MeshPerPrimitiveEXT {\n"
874 << " int gl_PrimitiveID;\n"
875 << "} gl_MeshPrimitivesEXT[];\n"
876 << "\n"
877 << (taskShader ? taskDataDecl : bindingsDecl)
878 << "vec4 positions[" << IfaceVar::kNumVertices << "] = vec4[](\n"
879 << " vec4(-1.0, -1.0, 0.0, 1.0),\n"
880 << " vec4( 1.0, -1.0, 0.0, 1.0),\n"
881 << " vec4(-1.0, 1.0, 0.0, 1.0),\n"
882 << " vec4( 1.0, 1.0, 0.0, 1.0)\n"
883 << ");\n"
884 << "\n"
885 << "uvec3 indices[" << IfaceVar::kNumPrimitives << "] = uvec3[](\n"
886 << " uvec3(0, 1, 2),\n"
887 << " uvec3(2, 3, 1)\n"
888 << ");\n"
889 << "\n"
890 << "void main ()\n"
891 << "{\n"
892 << " SetMeshOutputsEXT(" << IfaceVar::kNumVertices << ", " << IfaceVar::kNumPrimitives << ");\n"
893 << "\n"
894 ;
895
896 // Emit positions, indices and primitive IDs.
897 for (uint32_t i = 0; i < IfaceVar::kNumVertices; ++i)
898 mesh << " gl_MeshVerticesEXT[" << i << "].gl_Position = positions[" << i << "];\n";
899 mesh << "\n";
900
901 for (uint32_t i = 0; i < IfaceVar::kNumPrimitives; ++i)
902 mesh << " gl_PrimitiveTriangleIndicesEXT[" << i << "] = indices[" << i << "];\n";
903 mesh << "\n";
904
905 for (uint32_t i = 0; i < IfaceVar::kNumPrimitives; ++i)
906 mesh << " gl_MeshPrimitivesEXT[" << i << "].gl_PrimitiveID = " << i << ";\n";
907 mesh << "\n";
908
909 // Copy data to output variables, either from the task data or the bindings.
910 for (size_t i = 0; i < varVec.size(); ++i)
911 {
912 const auto arraySize = varVec[i].getArraySize();
913 const auto prefix = ((varVec[i].owner == Owner::VERTEX) ? meshPvdPrefix : meshPpdPrefix);
914 for (uint32_t arrayIndex = 0u; arrayIndex < arraySize; ++arrayIndex)
915 mesh << varVec[i].getAssignmentStatement(arrayIndex, "", prefix);
916 }
917
918 mesh
919 << "\n"
920 << "}\n"
921 ;
922
923 programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str()) << buildOptions;
924
925 // Task shader if needed.
926 if (taskShader)
927 {
928 const auto& meshCount = m_params->meshCount;
929 const auto taskPvdPrefix = "pvd";
930 const auto taskPpdPrefix = "ppd";
931
932 std::ostringstream task;
933 task
934 << "#version 450\n"
935 << "#extension GL_EXT_mesh_shader : enable\n"
936 << "#extension GL_EXT_shader_explicit_arithmetic_types : enable\n"
937 << "\n"
938 << taskDataDecl
939 << bindingsDecl
940 << "void main ()\n"
941 << "{\n"
942 ;
943
944 // Copy data from bindings to the task data structure.
945 for (size_t i = 0; i < varVec.size(); ++i)
946 {
947 const auto arraySize = varVec[i].getArraySize();
948 const auto prefix = ((varVec[i].owner == Owner::VERTEX) ? taskPvdPrefix : taskPpdPrefix);
949
950 for (uint32_t arrayIndex = 0u; arrayIndex < arraySize; ++arrayIndex)
951 task << varVec[i].getAssignmentStatement(arrayIndex, "td", prefix);
952 }
953
954 task
955 << "\n"
956 << " EmitMeshTasksEXT(" << meshCount.x() << ", " << meshCount.y() << ", " << meshCount.z() << ");\n"
957 << "}\n"
958 ;
959 programCollection.glslSources.add("task") << glu::TaskSource(task.str()) << buildOptions;
960 }
961 }
962
963 void InterfaceVariablesInstance::generateReferenceLevel ()
964 {
965 const auto format = getOutputFormat();
966 const auto tcuFormat = mapVkFormat(format);
967
968 const auto iWidth = static_cast<int>(m_params->width);
969 const auto iHeight = static_cast<int>(m_params->height);
970
971 m_referenceLevel.reset(new tcu::TextureLevel(tcuFormat, iWidth, iHeight));
972
973 const auto access = m_referenceLevel->getAccess();
974 const auto blueColor = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
975
976 tcu::clear(access, blueColor);
977 }
978
979 bool InterfaceVariablesInstance::verifyResult (const tcu::ConstPixelBufferAccess& resultAccess) const
980 {
981 const auto& referenceLevel = *m_referenceLevel.get();
982 const auto referenceAccess = referenceLevel.getAccess();
983
984 const auto refWidth = referenceAccess.getWidth();
985 const auto refHeight = referenceAccess.getHeight();
986 const auto refDepth = referenceAccess.getDepth();
987
988 const auto resWidth = resultAccess.getWidth();
989 const auto resHeight = resultAccess.getHeight();
990 const auto resDepth = resultAccess.getDepth();
991
992 DE_ASSERT(resWidth == refWidth || resHeight == refHeight || resDepth == refDepth);
993
994 // For release builds.
995 DE_UNREF(refWidth);
996 DE_UNREF(refHeight);
997 DE_UNREF(refDepth);
998 DE_UNREF(resWidth);
999 DE_UNREF(resHeight);
1000 DE_UNREF(resDepth);
1001
1002 const auto outputFormat = getOutputFormat();
1003 const auto expectedFormat = mapVkFormat(outputFormat);
1004 const auto resFormat = resultAccess.getFormat();
1005 const auto refFormat = referenceAccess.getFormat();
1006
1007 DE_ASSERT(resFormat == expectedFormat && refFormat == expectedFormat);
1008
1009 // For release builds
1010 DE_UNREF(expectedFormat);
1011 DE_UNREF(resFormat);
1012 DE_UNREF(refFormat);
1013
1014 auto& log = m_context.getTestContext().getLog();
1015 const auto threshold = getCompareThreshold();
1016 const tcu::Vec4 thresholdVec (threshold, threshold, threshold, threshold);
1017
1018 return tcu::floatThresholdCompare(log, "Result", "", referenceAccess, resultAccess, thresholdVec, tcu::COMPARE_LOG_ON_ERROR);
1019 }
1020
1021 tcu::TestStatus InterfaceVariablesInstance::iterate ()
1022 {
1023 const auto& vkd = m_context.getDeviceInterface();
1024 const auto device = m_context.getDevice();
1025 auto& alloc = m_context.getDefaultAllocator();
1026 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
1027 const auto queue = m_context.getUniversalQueue();
1028
1029 const auto imageFormat = getOutputFormat();
1030 const auto tcuFormat = mapVkFormat(imageFormat);
1031 const auto imageExtent = makeExtent3D(m_params->width, m_params->height, 1u);
1032 const auto imageUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1033
1034 const auto& binaries = m_context.getBinaryCollection();
1035 const auto hasTask = binaries.contains("task");
1036 const auto bufStages = (VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_MESH_BIT_EXT | (hasTask ? VK_SHADER_STAGE_TASK_BIT_EXT : 0));
1037
1038 const VkImageCreateInfo colorBufferInfo =
1039 {
1040 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1041 nullptr, // const void* pNext;
1042 0u, // VkImageCreateFlags flags;
1043 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1044 imageFormat, // VkFormat format;
1045 imageExtent, // VkExtent3D extent;
1046 1u, // uint32_t mipLevels;
1047 1u, // uint32_t arrayLayers;
1048 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1049 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1050 imageUsage, // VkImageUsageFlags usage;
1051 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1052 0u, // uint32_t queueFamilyIndexCount;
1053 nullptr, // const uint32_t* pQueueFamilyIndices;
1054 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1055 };
1056
1057 // Create color image and view.
1058 ImageWithMemory colorImage (vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
1059 const auto colorSRR = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1060 const auto colorSRL = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1061 const auto colorView = makeImageView(vkd, device, colorImage.get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, colorSRR);
1062
1063 // Create a memory buffer for verification.
1064 const auto verificationBufferSize = static_cast<VkDeviceSize>(imageExtent.width * imageExtent.height * tcu::getPixelSize(tcuFormat));
1065 const auto verificationBufferUsage = (VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1066 const auto verificationBufferInfo = makeBufferCreateInfo(verificationBufferSize, verificationBufferUsage);
1067
1068 BufferWithMemory verificationBuffer (vkd, device, alloc, verificationBufferInfo, MemoryRequirement::HostVisible);
1069 auto& verificationBufferAlloc = verificationBuffer.getAllocation();
1070 void* verificationBufferData = verificationBufferAlloc.getHostPtr();
1071
1072 // Bindings data.
1073 // The initialization statements below were generated automatically with a Python script.
1074 // Note: it works with stdin/stdout.
1075 #if 0
1076 import re
1077 import sys
1078
1079 # Lines look like: tcu::Vec4 vert_f64d4_inter_0[IfaceVar::kNumVertices];
1080 lineRE = re.compile(r'^\s*(\S+)\s+(\w+)\[(\S+)\];.*$')
1081 vecRE = re.compile(r'^.*Vec(\d)$')
1082 floatSuffixes = (
1083 (0.25, 0.50, 0.875, 0.0),
1084 (0.25, 0.75, 0.875, 0.0),
1085 (0.50, 0.50, 0.875, 0.0),
1086 (0.50, 0.75, 0.875, 0.0),
1087 )
1088 lineCounter = 0
1089
1090 for line in sys.stdin:
1091 match = lineRE.search(line)
1092 if not match:
1093 continue
1094
1095 varType = match.group(1)
1096 varName = match.group(2)
1097 varSize = match.group(3)
1098
1099 arraySize = (4 if varSize == 'IfaceVar::kNumVertices' else 2)
1100 vecMatch = vecRE.match(varType)
1101 numComponents = (1 if not vecMatch else vecMatch.group(1))
1102 isFlat = '_flat_' in varName
1103
1104 lineCounter += 1
1105 varBaseVal = 1000 + 10 * lineCounter
1106 valueTemplate = ('%s' if numComponents == 1 else '%s(%%s)' % (varType,))
1107
1108 for index in range(arraySize):
1109 valueStr = ''
1110 for comp in range(numComponents):
1111 compValue = varBaseVal + comp + 1
1112 if not isFlat:
1113 compValue += floatSuffixes[index][comp]
1114 valueStr += ('' if comp == 0 else ', ') + str(compValue)
1115 value = valueTemplate % (valueStr,)
1116 statement = '%s[%s] = %s;' % (varName, index, value)
1117 print('%s' % (statement,))
1118 #endif
1119 InterfaceVariablesCase::PerVertexData perVertexData;
1120 {
1121 perVertexData.vert_f64d4_inter_0[0] = tcu::Vec4(1011.25, 1012.5, 1013.875, 1014.0);
1122 perVertexData.vert_f64d4_inter_0[1] = tcu::Vec4(1011.25, 1012.75, 1013.875, 1014.0);
1123 perVertexData.vert_f64d4_inter_0[2] = tcu::Vec4(1011.5, 1012.5, 1013.875, 1014.0);
1124 perVertexData.vert_f64d4_inter_0[3] = tcu::Vec4(1011.5, 1012.75, 1013.875, 1014.0);
1125 perVertexData.vert_f64d4_inter_1[0] = tcu::Vec4(1021.25, 1022.5, 1023.875, 1024.0);
1126 perVertexData.vert_f64d4_inter_1[1] = tcu::Vec4(1021.25, 1022.75, 1023.875, 1024.0);
1127 perVertexData.vert_f64d4_inter_1[2] = tcu::Vec4(1021.5, 1022.5, 1023.875, 1024.0);
1128 perVertexData.vert_f64d4_inter_1[3] = tcu::Vec4(1021.5, 1022.75, 1023.875, 1024.0);
1129 perVertexData.vert_f64d3_inter_0[0] = tcu::Vec3(1031.25, 1032.5, 1033.875);
1130 perVertexData.vert_f64d3_inter_0[1] = tcu::Vec3(1031.25, 1032.75, 1033.875);
1131 perVertexData.vert_f64d3_inter_0[2] = tcu::Vec3(1031.5, 1032.5, 1033.875);
1132 perVertexData.vert_f64d3_inter_0[3] = tcu::Vec3(1031.5, 1032.75, 1033.875);
1133 perVertexData.vert_f64d3_inter_1[0] = tcu::Vec3(1041.25, 1042.5, 1043.875);
1134 perVertexData.vert_f64d3_inter_1[1] = tcu::Vec3(1041.25, 1042.75, 1043.875);
1135 perVertexData.vert_f64d3_inter_1[2] = tcu::Vec3(1041.5, 1042.5, 1043.875);
1136 perVertexData.vert_f64d3_inter_1[3] = tcu::Vec3(1041.5, 1042.75, 1043.875);
1137 perVertexData.vert_f64d2_inter_0[0] = tcu::Vec2(1051.25, 1052.5);
1138 perVertexData.vert_f64d2_inter_0[1] = tcu::Vec2(1051.25, 1052.75);
1139 perVertexData.vert_f64d2_inter_0[2] = tcu::Vec2(1051.5, 1052.5);
1140 perVertexData.vert_f64d2_inter_0[3] = tcu::Vec2(1051.5, 1052.75);
1141 perVertexData.vert_f64d2_inter_1[0] = tcu::Vec2(1061.25, 1062.5);
1142 perVertexData.vert_f64d2_inter_1[1] = tcu::Vec2(1061.25, 1062.75);
1143 perVertexData.vert_f64d2_inter_1[2] = tcu::Vec2(1061.5, 1062.5);
1144 perVertexData.vert_f64d2_inter_1[3] = tcu::Vec2(1061.5, 1062.75);
1145 perVertexData.vert_f64d1_inter_0[0] = 1071.25;
1146 perVertexData.vert_f64d1_inter_0[1] = 1071.25;
1147 perVertexData.vert_f64d1_inter_0[2] = 1071.5;
1148 perVertexData.vert_f64d1_inter_0[3] = 1071.5;
1149 perVertexData.vert_f64d1_inter_1[0] = 1081.25;
1150 perVertexData.vert_f64d1_inter_1[1] = 1081.25;
1151 perVertexData.vert_f64d1_inter_1[2] = 1081.5;
1152 perVertexData.vert_f64d1_inter_1[3] = 1081.5;
1153 perVertexData.vert_f32d4_inter_0[0] = tcu::Vec4(1091.25, 1092.5, 1093.875, 1094.0);
1154 perVertexData.vert_f32d4_inter_0[1] = tcu::Vec4(1091.25, 1092.75, 1093.875, 1094.0);
1155 perVertexData.vert_f32d4_inter_0[2] = tcu::Vec4(1091.5, 1092.5, 1093.875, 1094.0);
1156 perVertexData.vert_f32d4_inter_0[3] = tcu::Vec4(1091.5, 1092.75, 1093.875, 1094.0);
1157 perVertexData.vert_f32d4_inter_1[0] = tcu::Vec4(1101.25, 1102.5, 1103.875, 1104.0);
1158 perVertexData.vert_f32d4_inter_1[1] = tcu::Vec4(1101.25, 1102.75, 1103.875, 1104.0);
1159 perVertexData.vert_f32d4_inter_1[2] = tcu::Vec4(1101.5, 1102.5, 1103.875, 1104.0);
1160 perVertexData.vert_f32d4_inter_1[3] = tcu::Vec4(1101.5, 1102.75, 1103.875, 1104.0);
1161 perVertexData.vert_f32d3_inter_0[0] = tcu::Vec3(1111.25, 1112.5, 1113.875);
1162 perVertexData.vert_f32d3_inter_0[1] = tcu::Vec3(1111.25, 1112.75, 1113.875);
1163 perVertexData.vert_f32d3_inter_0[2] = tcu::Vec3(1111.5, 1112.5, 1113.875);
1164 perVertexData.vert_f32d3_inter_0[3] = tcu::Vec3(1111.5, 1112.75, 1113.875);
1165 perVertexData.vert_f32d3_inter_1[0] = tcu::Vec3(1121.25, 1122.5, 1123.875);
1166 perVertexData.vert_f32d3_inter_1[1] = tcu::Vec3(1121.25, 1122.75, 1123.875);
1167 perVertexData.vert_f32d3_inter_1[2] = tcu::Vec3(1121.5, 1122.5, 1123.875);
1168 perVertexData.vert_f32d3_inter_1[3] = tcu::Vec3(1121.5, 1122.75, 1123.875);
1169 perVertexData.vert_f32d2_inter_0[0] = tcu::Vec2(1131.25, 1132.5);
1170 perVertexData.vert_f32d2_inter_0[1] = tcu::Vec2(1131.25, 1132.75);
1171 perVertexData.vert_f32d2_inter_0[2] = tcu::Vec2(1131.5, 1132.5);
1172 perVertexData.vert_f32d2_inter_0[3] = tcu::Vec2(1131.5, 1132.75);
1173 perVertexData.vert_f32d2_inter_1[0] = tcu::Vec2(1141.25, 1142.5);
1174 perVertexData.vert_f32d2_inter_1[1] = tcu::Vec2(1141.25, 1142.75);
1175 perVertexData.vert_f32d2_inter_1[2] = tcu::Vec2(1141.5, 1142.5);
1176 perVertexData.vert_f32d2_inter_1[3] = tcu::Vec2(1141.5, 1142.75);
1177 perVertexData.vert_f32d1_inter_0[0] = 1151.25;
1178 perVertexData.vert_f32d1_inter_0[1] = 1151.25;
1179 perVertexData.vert_f32d1_inter_0[2] = 1151.5;
1180 perVertexData.vert_f32d1_inter_0[3] = 1151.5;
1181 perVertexData.vert_f32d1_inter_1[0] = 1161.25;
1182 perVertexData.vert_f32d1_inter_1[1] = 1161.25;
1183 perVertexData.vert_f32d1_inter_1[2] = 1161.5;
1184 perVertexData.vert_f32d1_inter_1[3] = 1161.5;
1185 perVertexData.vert_f16d4_inter_0[0] = tcu::Vec4(1171.25, 1172.5, 1173.875, 1174.0);
1186 perVertexData.vert_f16d4_inter_0[1] = tcu::Vec4(1171.25, 1172.75, 1173.875, 1174.0);
1187 perVertexData.vert_f16d4_inter_0[2] = tcu::Vec4(1171.5, 1172.5, 1173.875, 1174.0);
1188 perVertexData.vert_f16d4_inter_0[3] = tcu::Vec4(1171.5, 1172.75, 1173.875, 1174.0);
1189 perVertexData.vert_f16d4_inter_1[0] = tcu::Vec4(1181.25, 1182.5, 1183.875, 1184.0);
1190 perVertexData.vert_f16d4_inter_1[1] = tcu::Vec4(1181.25, 1182.75, 1183.875, 1184.0);
1191 perVertexData.vert_f16d4_inter_1[2] = tcu::Vec4(1181.5, 1182.5, 1183.875, 1184.0);
1192 perVertexData.vert_f16d4_inter_1[3] = tcu::Vec4(1181.5, 1182.75, 1183.875, 1184.0);
1193 perVertexData.vert_f16d3_inter_0[0] = tcu::Vec3(1191.25, 1192.5, 1193.875);
1194 perVertexData.vert_f16d3_inter_0[1] = tcu::Vec3(1191.25, 1192.75, 1193.875);
1195 perVertexData.vert_f16d3_inter_0[2] = tcu::Vec3(1191.5, 1192.5, 1193.875);
1196 perVertexData.vert_f16d3_inter_0[3] = tcu::Vec3(1191.5, 1192.75, 1193.875);
1197 perVertexData.vert_f16d3_inter_1[0] = tcu::Vec3(1201.25, 1202.5, 1203.875);
1198 perVertexData.vert_f16d3_inter_1[1] = tcu::Vec3(1201.25, 1202.75, 1203.875);
1199 perVertexData.vert_f16d3_inter_1[2] = tcu::Vec3(1201.5, 1202.5, 1203.875);
1200 perVertexData.vert_f16d3_inter_1[3] = tcu::Vec3(1201.5, 1202.75, 1203.875);
1201 perVertexData.vert_f16d2_inter_0[0] = tcu::Vec2(1211.25, 1212.5);
1202 perVertexData.vert_f16d2_inter_0[1] = tcu::Vec2(1211.25, 1212.75);
1203 perVertexData.vert_f16d2_inter_0[2] = tcu::Vec2(1211.5, 1212.5);
1204 perVertexData.vert_f16d2_inter_0[3] = tcu::Vec2(1211.5, 1212.75);
1205 perVertexData.vert_f16d2_inter_1[0] = tcu::Vec2(1221.25, 1222.5);
1206 perVertexData.vert_f16d2_inter_1[1] = tcu::Vec2(1221.25, 1222.75);
1207 perVertexData.vert_f16d2_inter_1[2] = tcu::Vec2(1221.5, 1222.5);
1208 perVertexData.vert_f16d2_inter_1[3] = tcu::Vec2(1221.5, 1222.75);
1209 perVertexData.vert_f16d1_inter_0[0] = 1231.25;
1210 perVertexData.vert_f16d1_inter_0[1] = 1231.25;
1211 perVertexData.vert_f16d1_inter_0[2] = 1231.5;
1212 perVertexData.vert_f16d1_inter_0[3] = 1231.5;
1213 perVertexData.vert_f16d1_inter_1[0] = 1241.25;
1214 perVertexData.vert_f16d1_inter_1[1] = 1241.25;
1215 perVertexData.vert_f16d1_inter_1[2] = 1241.5;
1216 perVertexData.vert_f16d1_inter_1[3] = 1241.5;
1217 perVertexData.vert_f64d4_flat_0[0] = tcu::Vec4(1251, 1252, 1253, 1254);
1218 perVertexData.vert_f64d4_flat_0[1] = tcu::Vec4(1251, 1252, 1253, 1254);
1219 perVertexData.vert_f64d4_flat_0[2] = tcu::Vec4(1251, 1252, 1253, 1254);
1220 perVertexData.vert_f64d4_flat_0[3] = tcu::Vec4(1251, 1252, 1253, 1254);
1221 perVertexData.vert_f64d4_flat_1[0] = tcu::Vec4(1261, 1262, 1263, 1264);
1222 perVertexData.vert_f64d4_flat_1[1] = tcu::Vec4(1261, 1262, 1263, 1264);
1223 perVertexData.vert_f64d4_flat_1[2] = tcu::Vec4(1261, 1262, 1263, 1264);
1224 perVertexData.vert_f64d4_flat_1[3] = tcu::Vec4(1261, 1262, 1263, 1264);
1225 perVertexData.vert_f64d3_flat_0[0] = tcu::Vec3(1271, 1272, 1273);
1226 perVertexData.vert_f64d3_flat_0[1] = tcu::Vec3(1271, 1272, 1273);
1227 perVertexData.vert_f64d3_flat_0[2] = tcu::Vec3(1271, 1272, 1273);
1228 perVertexData.vert_f64d3_flat_0[3] = tcu::Vec3(1271, 1272, 1273);
1229 perVertexData.vert_f64d3_flat_1[0] = tcu::Vec3(1281, 1282, 1283);
1230 perVertexData.vert_f64d3_flat_1[1] = tcu::Vec3(1281, 1282, 1283);
1231 perVertexData.vert_f64d3_flat_1[2] = tcu::Vec3(1281, 1282, 1283);
1232 perVertexData.vert_f64d3_flat_1[3] = tcu::Vec3(1281, 1282, 1283);
1233 perVertexData.vert_f64d2_flat_0[0] = tcu::Vec2(1291, 1292);
1234 perVertexData.vert_f64d2_flat_0[1] = tcu::Vec2(1291, 1292);
1235 perVertexData.vert_f64d2_flat_0[2] = tcu::Vec2(1291, 1292);
1236 perVertexData.vert_f64d2_flat_0[3] = tcu::Vec2(1291, 1292);
1237 perVertexData.vert_f64d2_flat_1[0] = tcu::Vec2(1301, 1302);
1238 perVertexData.vert_f64d2_flat_1[1] = tcu::Vec2(1301, 1302);
1239 perVertexData.vert_f64d2_flat_1[2] = tcu::Vec2(1301, 1302);
1240 perVertexData.vert_f64d2_flat_1[3] = tcu::Vec2(1301, 1302);
1241 perVertexData.vert_f64d1_flat_0[0] = 1311;
1242 perVertexData.vert_f64d1_flat_0[1] = 1311;
1243 perVertexData.vert_f64d1_flat_0[2] = 1311;
1244 perVertexData.vert_f64d1_flat_0[3] = 1311;
1245 perVertexData.vert_f64d1_flat_1[0] = 1321;
1246 perVertexData.vert_f64d1_flat_1[1] = 1321;
1247 perVertexData.vert_f64d1_flat_1[2] = 1321;
1248 perVertexData.vert_f64d1_flat_1[3] = 1321;
1249 perVertexData.vert_f32d4_flat_0[0] = tcu::Vec4(1331, 1332, 1333, 1334);
1250 perVertexData.vert_f32d4_flat_0[1] = tcu::Vec4(1331, 1332, 1333, 1334);
1251 perVertexData.vert_f32d4_flat_0[2] = tcu::Vec4(1331, 1332, 1333, 1334);
1252 perVertexData.vert_f32d4_flat_0[3] = tcu::Vec4(1331, 1332, 1333, 1334);
1253 perVertexData.vert_f32d4_flat_1[0] = tcu::Vec4(1341, 1342, 1343, 1344);
1254 perVertexData.vert_f32d4_flat_1[1] = tcu::Vec4(1341, 1342, 1343, 1344);
1255 perVertexData.vert_f32d4_flat_1[2] = tcu::Vec4(1341, 1342, 1343, 1344);
1256 perVertexData.vert_f32d4_flat_1[3] = tcu::Vec4(1341, 1342, 1343, 1344);
1257 perVertexData.vert_f32d3_flat_0[0] = tcu::Vec3(1351, 1352, 1353);
1258 perVertexData.vert_f32d3_flat_0[1] = tcu::Vec3(1351, 1352, 1353);
1259 perVertexData.vert_f32d3_flat_0[2] = tcu::Vec3(1351, 1352, 1353);
1260 perVertexData.vert_f32d3_flat_0[3] = tcu::Vec3(1351, 1352, 1353);
1261 perVertexData.vert_f32d3_flat_1[0] = tcu::Vec3(1361, 1362, 1363);
1262 perVertexData.vert_f32d3_flat_1[1] = tcu::Vec3(1361, 1362, 1363);
1263 perVertexData.vert_f32d3_flat_1[2] = tcu::Vec3(1361, 1362, 1363);
1264 perVertexData.vert_f32d3_flat_1[3] = tcu::Vec3(1361, 1362, 1363);
1265 perVertexData.vert_f32d2_flat_0[0] = tcu::Vec2(1371, 1372);
1266 perVertexData.vert_f32d2_flat_0[1] = tcu::Vec2(1371, 1372);
1267 perVertexData.vert_f32d2_flat_0[2] = tcu::Vec2(1371, 1372);
1268 perVertexData.vert_f32d2_flat_0[3] = tcu::Vec2(1371, 1372);
1269 perVertexData.vert_f32d2_flat_1[0] = tcu::Vec2(1381, 1382);
1270 perVertexData.vert_f32d2_flat_1[1] = tcu::Vec2(1381, 1382);
1271 perVertexData.vert_f32d2_flat_1[2] = tcu::Vec2(1381, 1382);
1272 perVertexData.vert_f32d2_flat_1[3] = tcu::Vec2(1381, 1382);
1273 perVertexData.vert_f32d1_flat_0[0] = 1391;
1274 perVertexData.vert_f32d1_flat_0[1] = 1391;
1275 perVertexData.vert_f32d1_flat_0[2] = 1391;
1276 perVertexData.vert_f32d1_flat_0[3] = 1391;
1277 perVertexData.vert_f32d1_flat_1[0] = 1401;
1278 perVertexData.vert_f32d1_flat_1[1] = 1401;
1279 perVertexData.vert_f32d1_flat_1[2] = 1401;
1280 perVertexData.vert_f32d1_flat_1[3] = 1401;
1281 perVertexData.vert_f16d4_flat_0[0] = tcu::Vec4(1411, 1412, 1413, 1414);
1282 perVertexData.vert_f16d4_flat_0[1] = tcu::Vec4(1411, 1412, 1413, 1414);
1283 perVertexData.vert_f16d4_flat_0[2] = tcu::Vec4(1411, 1412, 1413, 1414);
1284 perVertexData.vert_f16d4_flat_0[3] = tcu::Vec4(1411, 1412, 1413, 1414);
1285 perVertexData.vert_f16d4_flat_1[0] = tcu::Vec4(1421, 1422, 1423, 1424);
1286 perVertexData.vert_f16d4_flat_1[1] = tcu::Vec4(1421, 1422, 1423, 1424);
1287 perVertexData.vert_f16d4_flat_1[2] = tcu::Vec4(1421, 1422, 1423, 1424);
1288 perVertexData.vert_f16d4_flat_1[3] = tcu::Vec4(1421, 1422, 1423, 1424);
1289 perVertexData.vert_f16d3_flat_0[0] = tcu::Vec3(1431, 1432, 1433);
1290 perVertexData.vert_f16d3_flat_0[1] = tcu::Vec3(1431, 1432, 1433);
1291 perVertexData.vert_f16d3_flat_0[2] = tcu::Vec3(1431, 1432, 1433);
1292 perVertexData.vert_f16d3_flat_0[3] = tcu::Vec3(1431, 1432, 1433);
1293 perVertexData.vert_f16d3_flat_1[0] = tcu::Vec3(1441, 1442, 1443);
1294 perVertexData.vert_f16d3_flat_1[1] = tcu::Vec3(1441, 1442, 1443);
1295 perVertexData.vert_f16d3_flat_1[2] = tcu::Vec3(1441, 1442, 1443);
1296 perVertexData.vert_f16d3_flat_1[3] = tcu::Vec3(1441, 1442, 1443);
1297 perVertexData.vert_f16d2_flat_0[0] = tcu::Vec2(1451, 1452);
1298 perVertexData.vert_f16d2_flat_0[1] = tcu::Vec2(1451, 1452);
1299 perVertexData.vert_f16d2_flat_0[2] = tcu::Vec2(1451, 1452);
1300 perVertexData.vert_f16d2_flat_0[3] = tcu::Vec2(1451, 1452);
1301 perVertexData.vert_f16d2_flat_1[0] = tcu::Vec2(1461, 1462);
1302 perVertexData.vert_f16d2_flat_1[1] = tcu::Vec2(1461, 1462);
1303 perVertexData.vert_f16d2_flat_1[2] = tcu::Vec2(1461, 1462);
1304 perVertexData.vert_f16d2_flat_1[3] = tcu::Vec2(1461, 1462);
1305 perVertexData.vert_f16d1_flat_0[0] = 1471;
1306 perVertexData.vert_f16d1_flat_0[1] = 1471;
1307 perVertexData.vert_f16d1_flat_0[2] = 1471;
1308 perVertexData.vert_f16d1_flat_0[3] = 1471;
1309 perVertexData.vert_f16d1_flat_1[0] = 1481;
1310 perVertexData.vert_f16d1_flat_1[1] = 1481;
1311 perVertexData.vert_f16d1_flat_1[2] = 1481;
1312 perVertexData.vert_f16d1_flat_1[3] = 1481;
1313 perVertexData.vert_i64d4_flat_0[0] = tcu::IVec4(1491, 1492, 1493, 1494);
1314 perVertexData.vert_i64d4_flat_0[1] = tcu::IVec4(1491, 1492, 1493, 1494);
1315 perVertexData.vert_i64d4_flat_0[2] = tcu::IVec4(1491, 1492, 1493, 1494);
1316 perVertexData.vert_i64d4_flat_0[3] = tcu::IVec4(1491, 1492, 1493, 1494);
1317 perVertexData.vert_i64d4_flat_1[0] = tcu::IVec4(1501, 1502, 1503, 1504);
1318 perVertexData.vert_i64d4_flat_1[1] = tcu::IVec4(1501, 1502, 1503, 1504);
1319 perVertexData.vert_i64d4_flat_1[2] = tcu::IVec4(1501, 1502, 1503, 1504);
1320 perVertexData.vert_i64d4_flat_1[3] = tcu::IVec4(1501, 1502, 1503, 1504);
1321 perVertexData.vert_i64d3_flat_0[0] = tcu::IVec3(1511, 1512, 1513);
1322 perVertexData.vert_i64d3_flat_0[1] = tcu::IVec3(1511, 1512, 1513);
1323 perVertexData.vert_i64d3_flat_0[2] = tcu::IVec3(1511, 1512, 1513);
1324 perVertexData.vert_i64d3_flat_0[3] = tcu::IVec3(1511, 1512, 1513);
1325 perVertexData.vert_i64d3_flat_1[0] = tcu::IVec3(1521, 1522, 1523);
1326 perVertexData.vert_i64d3_flat_1[1] = tcu::IVec3(1521, 1522, 1523);
1327 perVertexData.vert_i64d3_flat_1[2] = tcu::IVec3(1521, 1522, 1523);
1328 perVertexData.vert_i64d3_flat_1[3] = tcu::IVec3(1521, 1522, 1523);
1329 perVertexData.vert_i64d2_flat_0[0] = tcu::IVec2(1531, 1532);
1330 perVertexData.vert_i64d2_flat_0[1] = tcu::IVec2(1531, 1532);
1331 perVertexData.vert_i64d2_flat_0[2] = tcu::IVec2(1531, 1532);
1332 perVertexData.vert_i64d2_flat_0[3] = tcu::IVec2(1531, 1532);
1333 perVertexData.vert_i64d2_flat_1[0] = tcu::IVec2(1541, 1542);
1334 perVertexData.vert_i64d2_flat_1[1] = tcu::IVec2(1541, 1542);
1335 perVertexData.vert_i64d2_flat_1[2] = tcu::IVec2(1541, 1542);
1336 perVertexData.vert_i64d2_flat_1[3] = tcu::IVec2(1541, 1542);
1337 perVertexData.vert_i64d1_flat_0[0] = 1551;
1338 perVertexData.vert_i64d1_flat_0[1] = 1551;
1339 perVertexData.vert_i64d1_flat_0[2] = 1551;
1340 perVertexData.vert_i64d1_flat_0[3] = 1551;
1341 perVertexData.vert_i64d1_flat_1[0] = 1561;
1342 perVertexData.vert_i64d1_flat_1[1] = 1561;
1343 perVertexData.vert_i64d1_flat_1[2] = 1561;
1344 perVertexData.vert_i64d1_flat_1[3] = 1561;
1345 perVertexData.vert_i32d4_flat_0[0] = tcu::IVec4(1571, 1572, 1573, 1574);
1346 perVertexData.vert_i32d4_flat_0[1] = tcu::IVec4(1571, 1572, 1573, 1574);
1347 perVertexData.vert_i32d4_flat_0[2] = tcu::IVec4(1571, 1572, 1573, 1574);
1348 perVertexData.vert_i32d4_flat_0[3] = tcu::IVec4(1571, 1572, 1573, 1574);
1349 perVertexData.vert_i32d4_flat_1[0] = tcu::IVec4(1581, 1582, 1583, 1584);
1350 perVertexData.vert_i32d4_flat_1[1] = tcu::IVec4(1581, 1582, 1583, 1584);
1351 perVertexData.vert_i32d4_flat_1[2] = tcu::IVec4(1581, 1582, 1583, 1584);
1352 perVertexData.vert_i32d4_flat_1[3] = tcu::IVec4(1581, 1582, 1583, 1584);
1353 perVertexData.vert_i32d3_flat_0[0] = tcu::IVec3(1591, 1592, 1593);
1354 perVertexData.vert_i32d3_flat_0[1] = tcu::IVec3(1591, 1592, 1593);
1355 perVertexData.vert_i32d3_flat_0[2] = tcu::IVec3(1591, 1592, 1593);
1356 perVertexData.vert_i32d3_flat_0[3] = tcu::IVec3(1591, 1592, 1593);
1357 perVertexData.vert_i32d3_flat_1[0] = tcu::IVec3(1601, 1602, 1603);
1358 perVertexData.vert_i32d3_flat_1[1] = tcu::IVec3(1601, 1602, 1603);
1359 perVertexData.vert_i32d3_flat_1[2] = tcu::IVec3(1601, 1602, 1603);
1360 perVertexData.vert_i32d3_flat_1[3] = tcu::IVec3(1601, 1602, 1603);
1361 perVertexData.vert_i32d2_flat_0[0] = tcu::IVec2(1611, 1612);
1362 perVertexData.vert_i32d2_flat_0[1] = tcu::IVec2(1611, 1612);
1363 perVertexData.vert_i32d2_flat_0[2] = tcu::IVec2(1611, 1612);
1364 perVertexData.vert_i32d2_flat_0[3] = tcu::IVec2(1611, 1612);
1365 perVertexData.vert_i32d2_flat_1[0] = tcu::IVec2(1621, 1622);
1366 perVertexData.vert_i32d2_flat_1[1] = tcu::IVec2(1621, 1622);
1367 perVertexData.vert_i32d2_flat_1[2] = tcu::IVec2(1621, 1622);
1368 perVertexData.vert_i32d2_flat_1[3] = tcu::IVec2(1621, 1622);
1369 perVertexData.vert_i32d1_flat_0[0] = 1631;
1370 perVertexData.vert_i32d1_flat_0[1] = 1631;
1371 perVertexData.vert_i32d1_flat_0[2] = 1631;
1372 perVertexData.vert_i32d1_flat_0[3] = 1631;
1373 perVertexData.vert_i32d1_flat_1[0] = 1641;
1374 perVertexData.vert_i32d1_flat_1[1] = 1641;
1375 perVertexData.vert_i32d1_flat_1[2] = 1641;
1376 perVertexData.vert_i32d1_flat_1[3] = 1641;
1377 perVertexData.vert_i16d4_flat_0[0] = tcu::IVec4(1651, 1652, 1653, 1654);
1378 perVertexData.vert_i16d4_flat_0[1] = tcu::IVec4(1651, 1652, 1653, 1654);
1379 perVertexData.vert_i16d4_flat_0[2] = tcu::IVec4(1651, 1652, 1653, 1654);
1380 perVertexData.vert_i16d4_flat_0[3] = tcu::IVec4(1651, 1652, 1653, 1654);
1381 perVertexData.vert_i16d4_flat_1[0] = tcu::IVec4(1661, 1662, 1663, 1664);
1382 perVertexData.vert_i16d4_flat_1[1] = tcu::IVec4(1661, 1662, 1663, 1664);
1383 perVertexData.vert_i16d4_flat_1[2] = tcu::IVec4(1661, 1662, 1663, 1664);
1384 perVertexData.vert_i16d4_flat_1[3] = tcu::IVec4(1661, 1662, 1663, 1664);
1385 perVertexData.vert_i16d3_flat_0[0] = tcu::IVec3(1671, 1672, 1673);
1386 perVertexData.vert_i16d3_flat_0[1] = tcu::IVec3(1671, 1672, 1673);
1387 perVertexData.vert_i16d3_flat_0[2] = tcu::IVec3(1671, 1672, 1673);
1388 perVertexData.vert_i16d3_flat_0[3] = tcu::IVec3(1671, 1672, 1673);
1389 perVertexData.vert_i16d3_flat_1[0] = tcu::IVec3(1681, 1682, 1683);
1390 perVertexData.vert_i16d3_flat_1[1] = tcu::IVec3(1681, 1682, 1683);
1391 perVertexData.vert_i16d3_flat_1[2] = tcu::IVec3(1681, 1682, 1683);
1392 perVertexData.vert_i16d3_flat_1[3] = tcu::IVec3(1681, 1682, 1683);
1393 perVertexData.vert_i16d2_flat_0[0] = tcu::IVec2(1691, 1692);
1394 perVertexData.vert_i16d2_flat_0[1] = tcu::IVec2(1691, 1692);
1395 perVertexData.vert_i16d2_flat_0[2] = tcu::IVec2(1691, 1692);
1396 perVertexData.vert_i16d2_flat_0[3] = tcu::IVec2(1691, 1692);
1397 perVertexData.vert_i16d2_flat_1[0] = tcu::IVec2(1701, 1702);
1398 perVertexData.vert_i16d2_flat_1[1] = tcu::IVec2(1701, 1702);
1399 perVertexData.vert_i16d2_flat_1[2] = tcu::IVec2(1701, 1702);
1400 perVertexData.vert_i16d2_flat_1[3] = tcu::IVec2(1701, 1702);
1401 perVertexData.vert_i16d1_flat_0[0] = 1711;
1402 perVertexData.vert_i16d1_flat_0[1] = 1711;
1403 perVertexData.vert_i16d1_flat_0[2] = 1711;
1404 perVertexData.vert_i16d1_flat_0[3] = 1711;
1405 perVertexData.vert_i16d1_flat_1[0] = 1721;
1406 perVertexData.vert_i16d1_flat_1[1] = 1721;
1407 perVertexData.vert_i16d1_flat_1[2] = 1721;
1408 perVertexData.vert_i16d1_flat_1[3] = 1721;
1409 }
1410
1411 InterfaceVariablesCase::PerPrimitiveData perPrimitiveData;
1412 {
1413 perPrimitiveData.prim_f64d4_flat_0[0] = tcu::Vec4(1011, 1012, 1013, 1014);
1414 perPrimitiveData.prim_f64d4_flat_0[1] = tcu::Vec4(1011, 1012, 1013, 1014);
1415 perPrimitiveData.prim_f64d4_flat_1[0] = tcu::Vec4(1021, 1022, 1023, 1024);
1416 perPrimitiveData.prim_f64d4_flat_1[1] = tcu::Vec4(1021, 1022, 1023, 1024);
1417 perPrimitiveData.prim_f64d3_flat_0[0] = tcu::Vec3(1031, 1032, 1033);
1418 perPrimitiveData.prim_f64d3_flat_0[1] = tcu::Vec3(1031, 1032, 1033);
1419 perPrimitiveData.prim_f64d3_flat_1[0] = tcu::Vec3(1041, 1042, 1043);
1420 perPrimitiveData.prim_f64d3_flat_1[1] = tcu::Vec3(1041, 1042, 1043);
1421 perPrimitiveData.prim_f64d2_flat_0[0] = tcu::Vec2(1051, 1052);
1422 perPrimitiveData.prim_f64d2_flat_0[1] = tcu::Vec2(1051, 1052);
1423 perPrimitiveData.prim_f64d2_flat_1[0] = tcu::Vec2(1061, 1062);
1424 perPrimitiveData.prim_f64d2_flat_1[1] = tcu::Vec2(1061, 1062);
1425 perPrimitiveData.prim_f64d1_flat_0[0] = 1071;
1426 perPrimitiveData.prim_f64d1_flat_0[1] = 1071;
1427 perPrimitiveData.prim_f64d1_flat_1[0] = 1081;
1428 perPrimitiveData.prim_f64d1_flat_1[1] = 1081;
1429 perPrimitiveData.prim_f32d4_flat_0[0] = tcu::Vec4(1091, 1092, 1093, 1094);
1430 perPrimitiveData.prim_f32d4_flat_0[1] = tcu::Vec4(1091, 1092, 1093, 1094);
1431 perPrimitiveData.prim_f32d4_flat_1[0] = tcu::Vec4(1101, 1102, 1103, 1104);
1432 perPrimitiveData.prim_f32d4_flat_1[1] = tcu::Vec4(1101, 1102, 1103, 1104);
1433 perPrimitiveData.prim_f32d3_flat_0[0] = tcu::Vec3(1111, 1112, 1113);
1434 perPrimitiveData.prim_f32d3_flat_0[1] = tcu::Vec3(1111, 1112, 1113);
1435 perPrimitiveData.prim_f32d3_flat_1[0] = tcu::Vec3(1121, 1122, 1123);
1436 perPrimitiveData.prim_f32d3_flat_1[1] = tcu::Vec3(1121, 1122, 1123);
1437 perPrimitiveData.prim_f32d2_flat_0[0] = tcu::Vec2(1131, 1132);
1438 perPrimitiveData.prim_f32d2_flat_0[1] = tcu::Vec2(1131, 1132);
1439 perPrimitiveData.prim_f32d2_flat_1[0] = tcu::Vec2(1141, 1142);
1440 perPrimitiveData.prim_f32d2_flat_1[1] = tcu::Vec2(1141, 1142);
1441 perPrimitiveData.prim_f32d1_flat_0[0] = 1151;
1442 perPrimitiveData.prim_f32d1_flat_0[1] = 1151;
1443 perPrimitiveData.prim_f32d1_flat_1[0] = 1161;
1444 perPrimitiveData.prim_f32d1_flat_1[1] = 1161;
1445 perPrimitiveData.prim_f16d4_flat_0[0] = tcu::Vec4(1171, 1172, 1173, 1174);
1446 perPrimitiveData.prim_f16d4_flat_0[1] = tcu::Vec4(1171, 1172, 1173, 1174);
1447 perPrimitiveData.prim_f16d4_flat_1[0] = tcu::Vec4(1181, 1182, 1183, 1184);
1448 perPrimitiveData.prim_f16d4_flat_1[1] = tcu::Vec4(1181, 1182, 1183, 1184);
1449 perPrimitiveData.prim_f16d3_flat_0[0] = tcu::Vec3(1191, 1192, 1193);
1450 perPrimitiveData.prim_f16d3_flat_0[1] = tcu::Vec3(1191, 1192, 1193);
1451 perPrimitiveData.prim_f16d3_flat_1[0] = tcu::Vec3(1201, 1202, 1203);
1452 perPrimitiveData.prim_f16d3_flat_1[1] = tcu::Vec3(1201, 1202, 1203);
1453 perPrimitiveData.prim_f16d2_flat_0[0] = tcu::Vec2(1211, 1212);
1454 perPrimitiveData.prim_f16d2_flat_0[1] = tcu::Vec2(1211, 1212);
1455 perPrimitiveData.prim_f16d2_flat_1[0] = tcu::Vec2(1221, 1222);
1456 perPrimitiveData.prim_f16d2_flat_1[1] = tcu::Vec2(1221, 1222);
1457 perPrimitiveData.prim_f16d1_flat_0[0] = 1231;
1458 perPrimitiveData.prim_f16d1_flat_0[1] = 1231;
1459 perPrimitiveData.prim_f16d1_flat_1[0] = 1241;
1460 perPrimitiveData.prim_f16d1_flat_1[1] = 1241;
1461 perPrimitiveData.prim_i64d4_flat_0[0] = tcu::IVec4(1251, 1252, 1253, 1254);
1462 perPrimitiveData.prim_i64d4_flat_0[1] = tcu::IVec4(1251, 1252, 1253, 1254);
1463 perPrimitiveData.prim_i64d4_flat_1[0] = tcu::IVec4(1261, 1262, 1263, 1264);
1464 perPrimitiveData.prim_i64d4_flat_1[1] = tcu::IVec4(1261, 1262, 1263, 1264);
1465 perPrimitiveData.prim_i64d3_flat_0[0] = tcu::IVec3(1271, 1272, 1273);
1466 perPrimitiveData.prim_i64d3_flat_0[1] = tcu::IVec3(1271, 1272, 1273);
1467 perPrimitiveData.prim_i64d3_flat_1[0] = tcu::IVec3(1281, 1282, 1283);
1468 perPrimitiveData.prim_i64d3_flat_1[1] = tcu::IVec3(1281, 1282, 1283);
1469 perPrimitiveData.prim_i64d2_flat_0[0] = tcu::IVec2(1291, 1292);
1470 perPrimitiveData.prim_i64d2_flat_0[1] = tcu::IVec2(1291, 1292);
1471 perPrimitiveData.prim_i64d2_flat_1[0] = tcu::IVec2(1301, 1302);
1472 perPrimitiveData.prim_i64d2_flat_1[1] = tcu::IVec2(1301, 1302);
1473 perPrimitiveData.prim_i64d1_flat_0[0] = 1311;
1474 perPrimitiveData.prim_i64d1_flat_0[1] = 1311;
1475 perPrimitiveData.prim_i64d1_flat_1[0] = 1321;
1476 perPrimitiveData.prim_i64d1_flat_1[1] = 1321;
1477 perPrimitiveData.prim_i32d4_flat_0[0] = tcu::IVec4(1331, 1332, 1333, 1334);
1478 perPrimitiveData.prim_i32d4_flat_0[1] = tcu::IVec4(1331, 1332, 1333, 1334);
1479 perPrimitiveData.prim_i32d4_flat_1[0] = tcu::IVec4(1341, 1342, 1343, 1344);
1480 perPrimitiveData.prim_i32d4_flat_1[1] = tcu::IVec4(1341, 1342, 1343, 1344);
1481 perPrimitiveData.prim_i32d3_flat_0[0] = tcu::IVec3(1351, 1352, 1353);
1482 perPrimitiveData.prim_i32d3_flat_0[1] = tcu::IVec3(1351, 1352, 1353);
1483 perPrimitiveData.prim_i32d3_flat_1[0] = tcu::IVec3(1361, 1362, 1363);
1484 perPrimitiveData.prim_i32d3_flat_1[1] = tcu::IVec3(1361, 1362, 1363);
1485 perPrimitiveData.prim_i32d2_flat_0[0] = tcu::IVec2(1371, 1372);
1486 perPrimitiveData.prim_i32d2_flat_0[1] = tcu::IVec2(1371, 1372);
1487 perPrimitiveData.prim_i32d2_flat_1[0] = tcu::IVec2(1381, 1382);
1488 perPrimitiveData.prim_i32d2_flat_1[1] = tcu::IVec2(1381, 1382);
1489 perPrimitiveData.prim_i32d1_flat_0[0] = 1391;
1490 perPrimitiveData.prim_i32d1_flat_0[1] = 1391;
1491 perPrimitiveData.prim_i32d1_flat_1[0] = 1401;
1492 perPrimitiveData.prim_i32d1_flat_1[1] = 1401;
1493 perPrimitiveData.prim_i16d4_flat_0[0] = tcu::IVec4(1411, 1412, 1413, 1414);
1494 perPrimitiveData.prim_i16d4_flat_0[1] = tcu::IVec4(1411, 1412, 1413, 1414);
1495 perPrimitiveData.prim_i16d4_flat_1[0] = tcu::IVec4(1421, 1422, 1423, 1424);
1496 perPrimitiveData.prim_i16d4_flat_1[1] = tcu::IVec4(1421, 1422, 1423, 1424);
1497 perPrimitiveData.prim_i16d3_flat_0[0] = tcu::IVec3(1431, 1432, 1433);
1498 perPrimitiveData.prim_i16d3_flat_0[1] = tcu::IVec3(1431, 1432, 1433);
1499 perPrimitiveData.prim_i16d3_flat_1[0] = tcu::IVec3(1441, 1442, 1443);
1500 perPrimitiveData.prim_i16d3_flat_1[1] = tcu::IVec3(1441, 1442, 1443);
1501 perPrimitiveData.prim_i16d2_flat_0[0] = tcu::IVec2(1451, 1452);
1502 perPrimitiveData.prim_i16d2_flat_0[1] = tcu::IVec2(1451, 1452);
1503 perPrimitiveData.prim_i16d2_flat_1[0] = tcu::IVec2(1461, 1462);
1504 perPrimitiveData.prim_i16d2_flat_1[1] = tcu::IVec2(1461, 1462);
1505 perPrimitiveData.prim_i16d1_flat_0[0] = 1471;
1506 perPrimitiveData.prim_i16d1_flat_0[1] = 1471;
1507 perPrimitiveData.prim_i16d1_flat_1[0] = 1481;
1508 perPrimitiveData.prim_i16d1_flat_1[1] = 1481;
1509 }
1510
1511 // Create and fill buffers with this data.
1512 const auto pvdSize = static_cast<VkDeviceSize>(sizeof(perVertexData));
1513 const auto pvdInfo = makeBufferCreateInfo(pvdSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1514 BufferWithMemory pvdData (vkd, device, alloc, pvdInfo, MemoryRequirement::HostVisible);
1515 auto& pvdAlloc = pvdData.getAllocation();
1516 void* pvdPtr = pvdAlloc.getHostPtr();
1517
1518 const auto ppdSize = static_cast<VkDeviceSize>(sizeof(perPrimitiveData));
1519 const auto ppdInfo = makeBufferCreateInfo(ppdSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1520 BufferWithMemory ppdData (vkd, device, alloc, ppdInfo, MemoryRequirement::HostVisible);
1521 auto& ppdAlloc = ppdData.getAllocation();
1522 void* ppdPtr = ppdAlloc.getHostPtr();
1523
1524 deMemcpy(pvdPtr, &perVertexData, sizeof(perVertexData));
1525 deMemcpy(ppdPtr, &perPrimitiveData, sizeof(perPrimitiveData));
1526
1527 flushAlloc(vkd, device, pvdAlloc);
1528 flushAlloc(vkd, device, ppdAlloc);
1529
1530 // Descriptor set layout.
1531 DescriptorSetLayoutBuilder setLayoutBuilder;
1532 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, bufStages);
1533 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, bufStages);
1534 const auto setLayout = setLayoutBuilder.build(vkd, device);
1535
1536 // Create and update descriptor set.
1537 DescriptorPoolBuilder descriptorPoolBuilder;
1538 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u);
1539 const auto descriptorPool = descriptorPoolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1540 const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get());
1541
1542 DescriptorSetUpdateBuilder updateBuilder;
1543 const auto pvdBufferInfo = makeDescriptorBufferInfo(pvdData.get(), 0ull, pvdSize);
1544 const auto ppdBufferInfo = makeDescriptorBufferInfo(ppdData.get(), 0ull, ppdSize);
1545 updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &pvdBufferInfo);
1546 updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &ppdBufferInfo);
1547 updateBuilder.update(vkd, device);
1548
1549 // Pipeline layout.
1550 const auto pipelineLayout = makePipelineLayout(vkd, device, setLayout.get());
1551
1552 // Shader modules.
1553 const auto meshShader = createShaderModule(vkd, device, binaries.get("mesh"));
1554 const auto fragShader = createShaderModule(vkd, device, binaries.get("frag"));
1555
1556 Move<VkShaderModule> taskShader;
1557 if (hasTask)
1558 taskShader = createShaderModule(vkd, device, binaries.get("task"));
1559
1560 // Render pass.
1561 const auto renderPass = makeRenderPass(vkd, device, imageFormat);
1562
1563 // Framebuffer.
1564 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorView.get(), imageExtent.width, imageExtent.height);
1565
1566 // Viewport and scissor.
1567 const auto topHalf = makeViewport(imageExtent.width, imageExtent.height / 2u);
1568 const std::vector<VkViewport> viewports { makeViewport(imageExtent), topHalf };
1569 const std::vector<VkRect2D> scissors (2u, makeRect2D(imageExtent));
1570
1571 const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
1572 taskShader.get(), meshShader.get(), fragShader.get(),
1573 renderPass.get(), viewports, scissors);
1574
1575 // Command pool and buffer.
1576 const auto cmdPool = makeCommandPool(vkd, device, queueIndex);
1577 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1578 const auto cmdBuffer = cmdBufferPtr.get();
1579
1580 beginCommandBuffer(vkd, cmdBuffer);
1581
1582 // Run pipeline.
1583 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 0.0f);
1584 const auto drawCount = m_params->drawCount();
1585 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0u), clearColor);
1586 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
1587 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
1588 vkd.cmdDrawMeshTasksEXT(cmdBuffer, drawCount.x(), drawCount.y(), drawCount.z());
1589 endRenderPass(vkd, cmdBuffer);
1590
1591 // Copy color buffer to verification buffer.
1592 const auto colorAccess = (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
1593 const auto transferRead = VK_ACCESS_TRANSFER_READ_BIT;
1594 const auto transferWrite = VK_ACCESS_TRANSFER_WRITE_BIT;
1595 const auto hostRead = VK_ACCESS_HOST_READ_BIT;
1596
1597 const auto preCopyBarrier = makeImageMemoryBarrier(colorAccess, transferRead, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorImage.get(), colorSRR);
1598 const auto postCopyBarrier = makeMemoryBarrier(transferWrite, hostRead);
1599 const auto copyRegion = makeBufferImageCopy(imageExtent, colorSRL);
1600
1601 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &preCopyBarrier);
1602 vkd.cmdCopyImageToBuffer(cmdBuffer, colorImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verificationBuffer.get(), 1u, ©Region);
1603 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &postCopyBarrier, 0u, nullptr, 0u, nullptr);
1604
1605 endCommandBuffer(vkd, cmdBuffer);
1606 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1607
1608 // Generate reference image and compare results.
1609 const tcu::IVec3 iExtent (static_cast<int>(imageExtent.width), static_cast<int>(imageExtent.height), 1);
1610 const tcu::ConstPixelBufferAccess verificationAccess (tcuFormat, iExtent, verificationBufferData);
1611
1612 generateReferenceLevel();
1613 invalidateAlloc(vkd, device, verificationBufferAlloc);
1614 if (!verifyResult(verificationAccess))
1615 TCU_FAIL("Result does not match reference; check log for details");
1616
1617 return tcu::TestStatus::pass("Pass");
1618 }
1619
1620 } // anonymous namespace
1621
1622 tcu::TestCaseGroup* createMeshShaderInOutTestsEXT (tcu::TestContext& testCtx)
1623 {
1624 GroupPtr inOutTests (new tcu::TestCaseGroup(testCtx, "in_out", "Mesh Shader Tests checking Input/Output interfaces"));
1625
1626 const struct
1627 {
1628 bool i64; bool f64; bool i16; bool f16;
1629 const char* name;
1630 } requiredFeatures[] =
1631 {
1632 // Restrict the number of combinations to avoid creating too many tests.
1633 // i64 f64 i16 f16 name
1634 { false, false, false, false, "32_bits_only" },
1635 { true, false, false, false, "with_i64" },
1636 { false, true, false, false, "with_f64" },
1637 { true, true, false, false, "all_but_16_bits" },
1638 { false, false, true, false, "with_i16" },
1639 { false, false, false, true, "with_f16" },
1640 { true, true, true, true, "all_types" },
1641 };
1642
1643 Owner ownerCases[] = { Owner::VERTEX, Owner::PRIMITIVE };
1644 DataType dataTypeCases[] = { DataType::FLOAT, DataType::INTEGER };
1645 BitWidth bitWidthCases[] = { BitWidth::B64, BitWidth::B32, BitWidth::B16 };
1646 DataDim dataDimCases[] = { DataDim::SCALAR, DataDim::VEC2, DataDim::VEC3, DataDim::VEC4 };
1647 Interpolation interpolationCases[] = { Interpolation::NORMAL, Interpolation::FLAT };
1648 de::Random rnd(1636723398u);
1649
1650 for (const auto& reqs : requiredFeatures)
1651 {
1652 GroupPtr reqsGroup (new tcu::TestCaseGroup(testCtx, reqs.name, ""));
1653
1654 // Generate the variable list according to the group requirements.
1655 IfaceVarVecPtr varsPtr(new IfaceVarVec);
1656
1657 for (const auto& ownerCase : ownerCases)
1658 for (const auto& dataTypeCase : dataTypeCases)
1659 for (const auto& bitWidthCase : bitWidthCases)
1660 for (const auto& dataDimCase : dataDimCases)
1661 for (const auto& interpolationCase : interpolationCases)
1662 {
1663 if (dataTypeCase == DataType::FLOAT)
1664 {
1665 if (bitWidthCase == BitWidth::B64 && !reqs.f64)
1666 continue;
1667 if (bitWidthCase == BitWidth::B16 && !reqs.f16)
1668 continue;
1669 }
1670 else if (dataTypeCase == DataType::INTEGER)
1671 {
1672 if (bitWidthCase == BitWidth::B64 && !reqs.i64)
1673 continue;
1674 if (bitWidthCase == BitWidth::B16 && !reqs.i16)
1675 continue;
1676 }
1677
1678 if (dataTypeCase == DataType::INTEGER && interpolationCase == Interpolation::NORMAL)
1679 continue;
1680
1681 if (ownerCase == Owner::PRIMITIVE && interpolationCase == Interpolation::NORMAL)
1682 continue;
1683
1684 if (dataTypeCase == DataType::FLOAT && bitWidthCase == BitWidth::B64 && interpolationCase == Interpolation::NORMAL)
1685 continue;
1686
1687 for (uint32_t idx = 0u; idx < IfaceVar::kVarsPerType; ++idx)
1688 varsPtr->push_back(IfaceVar(ownerCase, dataTypeCase, bitWidthCase, dataDimCase, interpolationCase, idx));
1689 }
1690
1691 // Generating all permutations of the variables above would mean millions of tests, so we just generate some pseudorandom permutations.
1692 constexpr uint32_t kPermutations = 40u;
1693 for (uint32_t combIdx = 0; combIdx < kPermutations; ++combIdx)
1694 {
1695 const auto caseName = "permutation_" + std::to_string(combIdx);
1696 GroupPtr rndGroup(new tcu::TestCaseGroup(testCtx, caseName.c_str(), ""));
1697
1698 // Duplicate and shuffle vector.
1699 IfaceVarVecPtr permutVec (new IfaceVarVec(*varsPtr));
1700 rnd.shuffle(begin(*permutVec), end(*permutVec));
1701
1702 // Cut the vector short to the usable number of locations.
1703 {
1704 uint32_t usedLocations = 0u;
1705 size_t vectorEnd = 0u;
1706 auto& varVec = *permutVec;
1707
1708 for (size_t i = 0; i < varVec.size(); ++i)
1709 {
1710 vectorEnd = i;
1711 const auto varSize = varVec[i].getLocationSize();
1712 if (usedLocations + varSize > InterfaceVariablesCase::kMaxLocations)
1713 break;
1714 usedLocations += varSize;
1715 }
1716
1717 varVec.resize(vectorEnd);
1718 }
1719
1720 for (int i = 0; i < 2; ++i)
1721 {
1722 const bool useTaskShader = (i > 0);
1723 const auto name = (useTaskShader ? "task_mesh" : "mesh_only");
1724
1725 // Duplicate vector for this particular case so both variants have the same shuffle.
1726 IfaceVarVecPtr paramsVec(new IfaceVarVec(*permutVec));
1727
1728 ParamsPtr paramsPtr (new InterfaceVariableParams(
1729 /*taskCount*/ (useTaskShader ? tcu::just(tcu::UVec3(1u, 1u, 1u)) : tcu::Nothing),
1730 /*meshCount*/ tcu::UVec3(1u, 1u, 1u),
1731 /*width*/ 8u,
1732 /*height*/ 8u,
1733 /*useInt64*/ reqs.i64,
1734 /*useFloat64*/ reqs.f64,
1735 /*useInt16*/ reqs.i16,
1736 /*useFloat16*/ reqs.f16,
1737 /*vars*/ std::move(paramsVec)));
1738
1739 rndGroup->addChild(new InterfaceVariablesCase(testCtx, name, "", std::move(paramsPtr)));
1740 }
1741
1742 reqsGroup->addChild(rndGroup.release());
1743 }
1744
1745 inOutTests->addChild(reqsGroup.release());
1746 }
1747
1748 return inOutTests.release();
1749 }
1750
1751 } // MeshShader
1752 } // vkt
1753