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