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