1/*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Vulkan ShaderExecutor
24 *//*--------------------------------------------------------------------*/
25
26#include "vktShaderExecutor.hpp"
27#include <map>
28#include <sstream>
29#include <iostream>
30
31#include "tcuVector.hpp"
32#include "tcuTestLog.hpp"
33#include "tcuFormatUtil.hpp"
34#include "tcuTextureUtil.hpp"
35#include "deUniquePtr.hpp"
36#include "deStringUtil.hpp"
37#include "deSharedPtr.hpp"
38
39#include "vkMemUtil.hpp"
40#include "vkRef.hpp"
41#include "vkPlatform.hpp"
42#include "vkPrograms.hpp"
43#include "vkStrUtil.hpp"
44#include "vkRefUtil.hpp"
45#include "vkTypeUtil.hpp"
46#include "vkQueryUtil.hpp"
47#include "vkDeviceUtil.hpp"
48#include "vkImageUtil.hpp"
49
50#include "gluShaderUtil.hpp"
51
52using std::vector;
53using namespace vk;
54
55namespace vkt
56{
57namespace shaderexecutor
58{
59namespace
60{
61
62enum
63{
64	DEFAULT_RENDER_WIDTH	= 100,
65	DEFAULT_RENDER_HEIGHT	= 100,
66};
67
68// Shader utilities
69
70static VkClearValue	getDefaultClearColor (void)
71{
72	return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);
73}
74
75static void checkSupported (const Context& ctx, glu::ShaderType shaderType)
76{
77	const VkPhysicalDeviceFeatures& features = ctx.getDeviceFeatures();
78
79	if (shaderType == glu::SHADERTYPE_GEOMETRY && !features.geometryShader)
80		TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
81	else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL && !features.tessellationShader)
82		TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device");
83	else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION && !features.tessellationShader)
84		TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device");
85}
86
87static std::string generateEmptyFragmentSource ()
88{
89	std::ostringstream src;
90
91	src <<	"#version 310 es\n"
92			"layout(location=0) out highp vec4 o_color;\n";
93
94	src << "void main (void)\n{\n";
95	src << "	o_color = vec4(0.0);\n";
96	src << "}\n";
97
98	return src.str();
99}
100
101static std::string generatePassthroughVertexShader (const std::vector<Symbol>& inputs, const char* inputPrefix, const char* outputPrefix)
102{
103
104	std::ostringstream	src;
105	int					location	= 0;
106
107	src <<	"#version 310 es\n"
108			"layout(location = " << location << ") in highp vec4 a_position;\n";
109
110	for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
111	{
112		location++;
113		src << "layout(location = "<< location << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n"
114			<< "layout(location = " << location - 1 << ") flat out " << glu::declare(input->varType, outputPrefix + input->name) << ";\n";
115	}
116
117	src << "\nvoid main (void)\n{\n"
118		<< "	gl_Position = a_position;\n"
119		<< "	gl_PointSize = 1.0;\n";
120
121	for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
122		src << "\t" << outputPrefix << input->name << " = " << inputPrefix << input->name << ";\n";
123
124	src << "}\n";
125
126	return src.str();
127}
128
129static std::string generateVertexShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
130{
131	DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
132
133	std::ostringstream	src;
134
135	src <<	"#version 310 es\n";
136
137	if (!shaderSpec.globalDeclarations.empty())
138		src << shaderSpec.globalDeclarations << "\n";
139
140	src << "layout(location = 0) in highp vec4 a_position;\n";
141
142	int locationNumber = 1;
143	for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
144		src <<  "layout(location = " << locationNumber << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
145
146	locationNumber = 0;
147	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
148	{
149		DE_ASSERT(output->varType.isBasicType());
150
151		if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
152		{
153			const int				vecSize		= glu::getDataTypeScalarSize(output->varType.getBasicType());
154			const glu::DataType		intBaseType	= vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
155			const glu::VarType		intType		(intBaseType, glu::PRECISION_HIGHP);
156
157			src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
158		}
159		else
160			src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
161	}
162
163	src << "\n"
164		<< "void main (void)\n"
165		<< "{\n"
166		<< "	gl_Position = a_position;\n"
167		<< "	gl_PointSize = 1.0;\n";
168
169	// Declare & fetch local input variables
170	for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
171		src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
172
173	// Declare local output variables
174	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
175		src << "\t" << glu::declare(output->varType, output->name) << ";\n";
176
177	// Operation - indented to correct level.
178	{
179		std::istringstream	opSrc	(shaderSpec.source);
180		std::string			line;
181
182		while (std::getline(opSrc, line))
183			src << "\t" << line << "\n";
184	}
185
186	// Assignments to outputs.
187	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
188	{
189		if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
190		{
191			const int				vecSize		= glu::getDataTypeScalarSize(output->varType.getBasicType());
192			const glu::DataType		intBaseType	= vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
193
194			src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
195		}
196		else
197			src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
198	}
199
200	src << "}\n";
201
202	return src.str();
203}
204
205struct FragmentOutputLayout
206{
207	std::vector<const Symbol*>		locationSymbols;		//! Symbols by location
208	std::map<std::string, int>		locationMap;			//! Map from symbol name to start location
209};
210
211static void generateFragShaderOutputDecl (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& outputPrefix)
212{
213	for (int outNdx = 0; outNdx < (int)shaderSpec.outputs.size(); ++outNdx)
214	{
215		const Symbol&				output		= shaderSpec.outputs[outNdx];
216		const int					location	= de::lookup(outLocationMap, output.name);
217		const std::string			outVarName	= outputPrefix + output.name;
218		glu::VariableDeclaration	decl		(output.varType, outVarName, glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(location));
219
220		TCU_CHECK_INTERNAL(output.varType.isBasicType());
221
222		if (useIntOutputs && glu::isDataTypeFloatOrVec(output.varType.getBasicType()))
223		{
224			const int			vecSize			= glu::getDataTypeScalarSize(output.varType.getBasicType());
225			const glu::DataType	uintBasicType	= vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT;
226			const glu::VarType	uintType		(uintBasicType, glu::PRECISION_HIGHP);
227
228			decl.varType = uintType;
229			src << decl << ";\n";
230		}
231		else if (glu::isDataTypeBoolOrBVec(output.varType.getBasicType()))
232		{
233			const int			vecSize			= glu::getDataTypeScalarSize(output.varType.getBasicType());
234			const glu::DataType	intBasicType	= vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
235			const glu::VarType	intType			(intBasicType, glu::PRECISION_HIGHP);
236
237			decl.varType = intType;
238			src << decl << ";\n";
239		}
240		else if (glu::isDataTypeMatrix(output.varType.getBasicType()))
241		{
242			const int			vecSize			= glu::getDataTypeMatrixNumRows(output.varType.getBasicType());
243			const int			numVecs			= glu::getDataTypeMatrixNumColumns(output.varType.getBasicType());
244			const glu::DataType	uintBasicType	= glu::getDataTypeUintVec(vecSize);
245			const glu::VarType	uintType		(uintBasicType, glu::PRECISION_HIGHP);
246
247			decl.varType = uintType;
248			for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
249			{
250				decl.name				= outVarName + "_" + de::toString(vecNdx);
251				decl.layout.location	= location + vecNdx;
252				src << decl << ";\n";
253			}
254		}
255		else
256			src << decl << ";\n";
257	}
258}
259
260static void generateFragShaderOutAssign (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::string& valuePrefix, const std::string& outputPrefix)
261{
262	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
263	{
264		if (useIntOutputs && glu::isDataTypeFloatOrVec(output->varType.getBasicType()))
265			src << "	o_" << output->name << " = floatBitsToUint(" << valuePrefix << output->name << ");\n";
266		else if (glu::isDataTypeMatrix(output->varType.getBasicType()))
267		{
268			const int	numVecs		= glu::getDataTypeMatrixNumColumns(output->varType.getBasicType());
269
270			for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
271				if (useIntOutputs)
272					src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = floatBitsToUint(" << valuePrefix << output->name << "[" << vecNdx << "]);\n";
273				else
274					src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = " << valuePrefix << output->name << "[" << vecNdx << "];\n";
275		}
276		else if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
277		{
278			const int				vecSize		= glu::getDataTypeScalarSize(output->varType.getBasicType());
279			const glu::DataType		intBaseType	= vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
280
281			src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << valuePrefix << output->name << ");\n";
282		}
283		else
284			src << "\t" << outputPrefix << output->name << " = " << valuePrefix << output->name << ";\n";
285	}
286}
287
288static std::string generatePassthroughFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
289{
290	std::ostringstream	src;
291
292	src <<	"#version 310 es\n";
293
294	if (!shaderSpec.globalDeclarations.empty())
295		src << shaderSpec.globalDeclarations << "\n";
296
297	int locationNumber = 0;
298	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
299	{
300		if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
301		{
302			const int				vecSize		= glu::getDataTypeScalarSize(output->varType.getBasicType());
303			const glu::DataType		intBaseType	= vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
304			const glu::VarType		intType		(intBaseType, glu::PRECISION_HIGHP);
305
306			src << "layout(location = " << locationNumber << ") flat in " << glu::declare(intType, inputPrefix + output->name) << ";\n";
307		}
308		else
309			src << "layout(location = " << locationNumber << ") flat in " << glu::declare(output->varType, inputPrefix + output->name) << ";\n";
310	}
311
312	generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
313
314	src << "\nvoid main (void)\n{\n";
315
316	generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, inputPrefix, outputPrefix);
317
318	src << "}\n";
319
320	return src.str();
321}
322
323static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
324{
325	DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
326
327	std::ostringstream	src;
328
329	src <<	"#version 310 es\n"
330		"#extension GL_EXT_geometry_shader : require\n";
331
332	if (!shaderSpec.globalDeclarations.empty())
333		src << shaderSpec.globalDeclarations << "\n";
334
335	src << "layout(points) in;\n"
336		<< "layout(points, max_vertices = 1) out;\n";
337
338	int locationNumber = 0;
339	for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
340		src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << "[];\n";
341
342	locationNumber = 0;
343	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
344	{
345		DE_ASSERT(output->varType.isBasicType());
346
347		if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
348		{
349			const int				vecSize		= glu::getDataTypeScalarSize(output->varType.getBasicType());
350			const glu::DataType		intBaseType	= vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
351			const glu::VarType		intType		(intBaseType, glu::PRECISION_HIGHP);
352
353			src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
354		}
355		else
356			src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
357	}
358
359	src << "\n"
360		<< "void main (void)\n"
361		<< "{\n"
362		<< "	gl_Position = gl_in[0].gl_Position;\n\n";
363
364	// Fetch input variables
365	for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
366		src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << "[0];\n";
367
368	// Declare local output variables.
369	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
370		src << "\t" << glu::declare(output->varType, output->name) << ";\n";
371
372	src << "\n";
373
374	// Operation - indented to correct level.
375	{
376		std::istringstream	opSrc	(shaderSpec.source);
377		std::string			line;
378
379		while (std::getline(opSrc, line))
380			src << "\t" << line << "\n";
381	}
382
383	// Assignments to outputs.
384	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
385	{
386		if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
387		{
388			const int				vecSize		= glu::getDataTypeScalarSize(output->varType.getBasicType());
389			const glu::DataType		intBaseType	= vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
390
391			src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
392		}
393		else
394			src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
395	}
396
397	src << "	EmitVertex();\n"
398		<< "	EndPrimitive();\n"
399		<< "}\n";
400
401	return src.str();
402}
403
404static std::string generateFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
405{
406	std::ostringstream src;
407	src <<  "#version 310 es\n";
408	if (!shaderSpec.globalDeclarations.empty())
409		src << shaderSpec.globalDeclarations << "\n";
410
411	int locationNumber = 0;
412	for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
413		src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
414
415	generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
416
417	src << "\nvoid main (void)\n{\n";
418
419	// Declare & fetch local input variables
420	for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
421		src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
422
423	// Declare output variables
424	for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
425		src << "\t" << glu::declare(output->varType, output->name) << ";\n";
426
427	// Operation - indented to correct level.
428	{
429		std::istringstream	opSrc	(shaderSpec.source);
430		std::string			line;
431
432		while (std::getline(opSrc, line))
433			src << "\t" << line << "\n";
434	}
435
436	generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, "", outputPrefix);
437
438	src << "}\n";
439
440	return src.str();
441}
442
443// FragmentOutExecutor
444
445class FragmentOutExecutor : public ShaderExecutor
446{
447public:
448														FragmentOutExecutor		(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
449	virtual												~FragmentOutExecutor	(void);
450
451	virtual void										execute					(const Context&			ctx,
452																				 int					numValues,
453																				 const void* const*		inputs,
454																				 void* const*			outputs);
455
456protected:
457	const FragmentOutputLayout							m_outputLayout;
458private:
459	void												bindAttributes			(const Context&			ctx,
460																				 Allocator&				memAlloc,
461																				 int					numValues,
462																				 const void* const*		inputs);
463
464	void												addAttribute			(const Context&			ctx,
465																				 Allocator&				memAlloc,
466																				 deUint32				bindingLocation,
467																				 VkFormat				format,
468																				 deUint32				sizePerElement,
469																				 deUint32				count,
470																				 const void*			dataPtr);
471	// reinit render data members
472	virtual void										clearRenderData			(void);
473
474	typedef de::SharedPtr<Unique<VkImage> >				VkImageSp;
475	typedef de::SharedPtr<Unique<VkImageView> >			VkImageViewSp;
476	typedef de::SharedPtr<Unique<VkBuffer> >			VkBufferSp;
477	typedef de::SharedPtr<de::UniquePtr<Allocation> >	AllocationSp;
478
479	std::vector<VkVertexInputBindingDescription>		m_vertexBindingDescriptions;
480	std::vector<VkVertexInputAttributeDescription>		m_vertexAttributeDescriptions;
481	std::vector<VkBufferSp>								m_vertexBuffers;
482	std::vector<AllocationSp>							m_vertexBufferAllocs;
483};
484
485static FragmentOutputLayout computeFragmentOutputLayout (const std::vector<Symbol>& symbols)
486{
487	FragmentOutputLayout	ret;
488	int						location	= 0;
489
490	for (std::vector<Symbol>::const_iterator it = symbols.begin(); it != symbols.end(); ++it)
491	{
492		const int	numLocations	= glu::getDataTypeNumLocations(it->varType.getBasicType());
493
494		TCU_CHECK_INTERNAL(!de::contains(ret.locationMap, it->name));
495		de::insert(ret.locationMap, it->name, location);
496		location += numLocations;
497
498		for (int ndx = 0; ndx < numLocations; ++ndx)
499			ret.locationSymbols.push_back(&*it);
500	}
501
502	return ret;
503}
504
505FragmentOutExecutor::FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
506	: ShaderExecutor	(shaderSpec, shaderType)
507	, m_outputLayout	(computeFragmentOutputLayout(m_shaderSpec.outputs))
508{
509}
510
511FragmentOutExecutor::~FragmentOutExecutor (void)
512{
513}
514
515static std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize)
516{
517	std::vector<tcu::Vec2> positions(numValues);
518	for (int valNdx = 0; valNdx < numValues; valNdx++)
519	{
520		const int		ix		= valNdx % renderSize.x();
521		const int		iy		= valNdx / renderSize.x();
522		const float		fx		= -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x()));
523		const float		fy		= -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y()));
524
525		positions[valNdx] = tcu::Vec2(fx, fy);
526	}
527
528	return positions;
529}
530
531static tcu::TextureFormat getRenderbufferFormatForOutput (const glu::VarType& outputType, bool useIntOutputs)
532{
533	const tcu::TextureFormat::ChannelOrder channelOrderMap[] =
534	{
535		tcu::TextureFormat::R,
536		tcu::TextureFormat::RG,
537		tcu::TextureFormat::RGBA,	// No RGB variants available.
538		tcu::TextureFormat::RGBA
539	};
540
541	const glu::DataType					basicType		= outputType.getBasicType();
542	const int							numComps		= glu::getDataTypeNumComponents(basicType);
543	tcu::TextureFormat::ChannelType		channelType;
544
545	switch (glu::getDataTypeScalarType(basicType))
546	{
547		case glu::TYPE_UINT:	channelType = tcu::TextureFormat::UNSIGNED_INT32;												break;
548		case glu::TYPE_INT:		channelType = tcu::TextureFormat::SIGNED_INT32;													break;
549		case glu::TYPE_BOOL:	channelType = tcu::TextureFormat::SIGNED_INT32;													break;
550		case glu::TYPE_FLOAT:	channelType = useIntOutputs ? tcu::TextureFormat::UNSIGNED_INT32 : tcu::TextureFormat::FLOAT;	break;
551		default:
552			throw tcu::InternalError("Invalid output type");
553	}
554
555	DE_ASSERT(de::inRange<int>(numComps, 1, DE_LENGTH_OF_ARRAY(channelOrderMap)));
556
557	return tcu::TextureFormat(channelOrderMap[numComps-1], channelType);
558}
559
560static VkFormat getAttributeFormat (const glu::DataType dataType)
561{
562	switch (dataType)
563	{
564		case glu::TYPE_FLOAT:			return VK_FORMAT_R32_SFLOAT;
565		case glu::TYPE_FLOAT_VEC2:		return VK_FORMAT_R32G32_SFLOAT;
566		case glu::TYPE_FLOAT_VEC3:		return VK_FORMAT_R32G32B32_SFLOAT;
567		case glu::TYPE_FLOAT_VEC4:		return VK_FORMAT_R32G32B32A32_SFLOAT;
568
569		case glu::TYPE_INT:				return VK_FORMAT_R32_SINT;
570		case glu::TYPE_INT_VEC2:		return VK_FORMAT_R32G32_SINT;
571		case glu::TYPE_INT_VEC3:		return VK_FORMAT_R32G32B32_SINT;
572		case glu::TYPE_INT_VEC4:		return VK_FORMAT_R32G32B32A32_SINT;
573
574		case glu::TYPE_UINT:			return VK_FORMAT_R32_UINT;
575		case glu::TYPE_UINT_VEC2:		return VK_FORMAT_R32G32_UINT;
576		case glu::TYPE_UINT_VEC3:		return VK_FORMAT_R32G32B32_UINT;
577		case glu::TYPE_UINT_VEC4:		return VK_FORMAT_R32G32B32A32_UINT;
578
579		case glu::TYPE_FLOAT_MAT2:		return VK_FORMAT_R32G32_SFLOAT;
580		case glu::TYPE_FLOAT_MAT2X3:	return VK_FORMAT_R32G32B32_SFLOAT;
581		case glu::TYPE_FLOAT_MAT2X4:	return VK_FORMAT_R32G32B32A32_SFLOAT;
582		case glu::TYPE_FLOAT_MAT3X2:	return VK_FORMAT_R32G32_SFLOAT;
583		case glu::TYPE_FLOAT_MAT3:		return VK_FORMAT_R32G32B32_SFLOAT;
584		case glu::TYPE_FLOAT_MAT3X4:	return VK_FORMAT_R32G32B32A32_SFLOAT;
585		case glu::TYPE_FLOAT_MAT4X2:	return VK_FORMAT_R32G32_SFLOAT;
586		case glu::TYPE_FLOAT_MAT4X3:	return VK_FORMAT_R32G32B32_SFLOAT;
587		case glu::TYPE_FLOAT_MAT4:		return VK_FORMAT_R32G32B32A32_SFLOAT;
588		default:
589			DE_ASSERT(false);
590			return VK_FORMAT_UNDEFINED;
591	}
592}
593
594void FragmentOutExecutor::addAttribute (const Context& ctx, Allocator& memAlloc, deUint32 bindingLocation, VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
595{
596	// Add binding specification
597	const deUint32 binding = (deUint32)m_vertexBindingDescriptions.size();
598	const VkVertexInputBindingDescription bindingDescription =
599	{
600		binding,
601		sizePerElement,
602		VK_VERTEX_INPUT_RATE_VERTEX
603	};
604
605	m_vertexBindingDescriptions.push_back(bindingDescription);
606
607	// Add location and format specification
608	const VkVertexInputAttributeDescription attributeDescription =
609	{
610		bindingLocation,			// deUint32	location;
611		binding,					// deUint32	binding;
612		format,						// VkFormat	format;
613		0u,							// deUint32	offsetInBytes;
614	};
615
616	m_vertexAttributeDescriptions.push_back(attributeDescription);
617
618	// Upload data to buffer
619	const VkDevice				vkDevice			= ctx.getDevice();
620	const DeviceInterface&		vk					= ctx.getDeviceInterface();
621	const deUint32				queueFamilyIndex	= ctx.getUniversalQueueFamilyIndex();
622
623	const VkDeviceSize inputSize = sizePerElement * count;
624	const VkBufferCreateInfo vertexBufferParams =
625	{
626		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
627		DE_NULL,									// const void*			pNext;
628		0u,											// VkBufferCreateFlags	flags;
629		inputSize,									// VkDeviceSize			size;
630		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
631		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
632		1u,											// deUint32				queueFamilyCount;
633		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
634	};
635
636	Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
637	de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
638	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
639
640	deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
641	flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
642
643	m_vertexBuffers.push_back(de::SharedPtr<Unique<VkBuffer> >(new Unique<VkBuffer>(buffer)));
644	m_vertexBufferAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(alloc)));
645}
646
647void FragmentOutExecutor::bindAttributes (const Context& ctx, Allocator& memAlloc, int numValues, const void* const* inputs)
648{
649	// Input attributes
650	for (int inputNdx = 0; inputNdx < (int)m_shaderSpec.inputs.size(); inputNdx++)
651	{
652		const Symbol&		symbol			= m_shaderSpec.inputs[inputNdx];
653		const void*			ptr				= inputs[inputNdx];
654		const glu::DataType	basicType		= symbol.varType.getBasicType();
655		const int			vecSize			= glu::getDataTypeScalarSize(basicType);
656		const VkFormat		format			= getAttributeFormat(basicType);
657		int					elementSize		= 0;
658		int					numAttrsToAdd	= 1;
659
660		if (glu::isDataTypeFloatOrVec(basicType))
661			elementSize = sizeof(float);
662		else if (glu::isDataTypeIntOrIVec(basicType))
663			elementSize = sizeof(int);
664		else if (glu::isDataTypeUintOrUVec(basicType))
665			elementSize = sizeof(deUint32);
666		else if (glu::isDataTypeMatrix(basicType))
667		{
668			int		numRows	= glu::getDataTypeMatrixNumRows(basicType);
669			int		numCols	= glu::getDataTypeMatrixNumColumns(basicType);
670
671			elementSize = numRows * numCols * (int)sizeof(float);
672			numAttrsToAdd = numCols;
673		}
674		else
675			DE_ASSERT(false);
676
677		// add attributes, in case of matrix every column is binded as an attribute
678		for (int attrNdx = 0; attrNdx < numAttrsToAdd; attrNdx++)
679		{
680			addAttribute(ctx, memAlloc, (deUint32)m_vertexBindingDescriptions.size(), format, elementSize * vecSize, numValues, ptr);
681		}
682	}
683}
684
685void FragmentOutExecutor::clearRenderData (void)
686{
687	m_vertexBindingDescriptions.clear();
688	m_vertexAttributeDescriptions.clear();
689	m_vertexBuffers.clear();
690	m_vertexBufferAllocs.clear();
691}
692
693void FragmentOutExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
694{
695	checkSupported(ctx, m_shaderType);
696
697	const VkDevice										vkDevice				= ctx.getDevice();
698	const DeviceInterface&								vk						= ctx.getDeviceInterface();
699	const VkQueue										queue					= ctx.getUniversalQueue();
700	const deUint32										queueFamilyIndex		= ctx.getUniversalQueueFamilyIndex();
701	Allocator&											memAlloc				= ctx.getDefaultAllocator();
702
703	const deUint32										renderSizeX				= de::min(static_cast<deUint32>(DEFAULT_RENDER_WIDTH), (deUint32)numValues);
704	const deUint32										renderSizeY				= ((deUint32)numValues / renderSizeX) + (((deUint32)numValues % renderSizeX != 0) ? 1u : 0u);
705	const tcu::UVec2									renderSize				(renderSizeX, renderSizeY);
706	std::vector<tcu::Vec2>								positions;
707
708	const bool											useGeometryShader		= m_shaderType == glu::SHADERTYPE_GEOMETRY;
709
710	std::vector<VkImageSp>								colorImages;
711	std::vector<VkImageMemoryBarrier>					colorImagePreRenderBarriers;
712	std::vector<VkImageMemoryBarrier>					colorImagePostRenderBarriers;
713	std::vector<AllocationSp>							colorImageAllocs;
714	std::vector<VkAttachmentDescription>				attachments;
715	std::vector<VkClearValue>							attachmentClearValues;
716	std::vector<VkImageViewSp>							colorImageViews;
717
718	std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates;
719	std::vector<VkAttachmentReference>					colorAttachmentReferences;
720
721	Move<VkRenderPass>									renderPass;
722	Move<VkFramebuffer>									framebuffer;
723	Move<VkPipelineLayout>								pipelineLayout;
724	Move<VkPipeline>									graphicsPipeline;
725
726	Move<VkShaderModule>								vertexShaderModule;
727	Move<VkShaderModule>								geometryShaderModule;
728	Move<VkShaderModule>								fragmentShaderModule;
729
730	Move<VkCommandPool>									cmdPool;
731	Move<VkCommandBuffer>								cmdBuffer;
732
733	Move<VkFence>										fence;
734
735	Move<VkDescriptorPool>								descriptorPool;
736	Move<VkDescriptorSetLayout>							descriptorSetLayout;
737	Move<VkDescriptorSet>								descriptorSet;
738
739	clearRenderData();
740
741	// Compute positions - 1px points are used to drive fragment shading.
742	positions = computeVertexPositions(numValues, renderSize.cast<int>());
743
744	// Bind attributes
745	addAttribute(ctx, memAlloc, 0u, VK_FORMAT_R32G32_SFLOAT, sizeof(tcu::Vec2), (deUint32)positions.size(), &positions[0]);
746	bindAttributes(ctx, memAlloc, numValues, inputs);
747
748	// Create color images
749	{
750		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
751		{
752			VK_FALSE,																	// VkBool32						blendEnable;
753			VK_BLEND_FACTOR_ONE,														// VkBlendFactor				srcColorBlendFactor;
754			VK_BLEND_FACTOR_ZERO,														// VkBlendFactor				dstColorBlendFactor;
755			VK_BLEND_OP_ADD,															// VkBlendOp					blendOpColor;
756			VK_BLEND_FACTOR_ONE,														// VkBlendFactor				srcAlphaBlendFactor;
757			VK_BLEND_FACTOR_ZERO,														// VkBlendFactor				destAlphaBlendFactor;
758			VK_BLEND_OP_ADD,															// VkBlendOp					blendOpAlpha;
759			(VK_COLOR_COMPONENT_R_BIT |
760			 VK_COLOR_COMPONENT_G_BIT |
761			 VK_COLOR_COMPONENT_B_BIT |
762			 VK_COLOR_COMPONENT_A_BIT)													// VkColorComponentFlags		colorWriteMask;
763		};
764
765		for (int outNdx = 0; outNdx < (int)m_outputLayout.locationSymbols.size(); ++outNdx)
766		{
767			const bool		isFloat		= isDataTypeFloatOrVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
768			const bool		isSigned	= isDataTypeIntOrIVec (m_shaderSpec.outputs[outNdx].varType.getBasicType());
769			const bool		isBool		= isDataTypeBoolOrBVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
770			const VkFormat	colorFormat = isFloat ? VK_FORMAT_R32G32B32A32_SFLOAT : (isSigned || isBool ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32G32B32A32_UINT);
771
772			const VkImageCreateInfo	 colorImageParams =
773			{
774				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType				sType;
775				DE_NULL,																	// const void*					pNext;
776				0u,																			// VkImageCreateFlags			flags;
777				VK_IMAGE_TYPE_2D,															// VkImageType					imageType;
778				colorFormat,																// VkFormat						format;
779				{ renderSize.x(), renderSize.y(), 1u },										// VkExtent3D					extent;
780				1u,																			// deUint32						mipLevels;
781				1u,																			// deUint32						arraySize;
782				VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits		samples;
783				VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling				tiling;
784				VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags			usage;
785				VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode				sharingMode;
786				1u,																			// deUint32						queueFamilyCount;
787				&queueFamilyIndex,															// const deUint32*				pQueueFamilyIndices;
788				VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout				initialLayout;
789			};
790
791			const VkAttachmentDescription colorAttachmentDescription =
792			{
793				0u,																			// VkAttachmentDescriptorFlags	flags;
794				colorFormat,																// VkFormat						format;
795				VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits		samples;
796				VK_ATTACHMENT_LOAD_OP_CLEAR,												// VkAttachmentLoadOp			loadOp;
797				VK_ATTACHMENT_STORE_OP_STORE,												// VkAttachmentStoreOp			storeOp;
798				VK_ATTACHMENT_LOAD_OP_DONT_CARE,											// VkAttachmentLoadOp			stencilLoadOp;
799				VK_ATTACHMENT_STORE_OP_DONT_CARE,											// VkAttachmentStoreOp			stencilStoreOp;
800				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,									// VkImageLayout				initialLayout;
801				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,									// VkImageLayout				finalLayout;
802			};
803
804			Move<VkImage> colorImage = createImage(vk, vkDevice, &colorImageParams);
805			colorImages.push_back(de::SharedPtr<Unique<VkImage> >(new Unique<VkImage>(colorImage)));
806			attachmentClearValues.push_back(getDefaultClearColor());
807
808			// Allocate and bind color image memory
809			{
810				de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *((const VkImage*) colorImages.back().get())), MemoryRequirement::Any);
811				VK_CHECK(vk.bindImageMemory(vkDevice, colorImages.back().get()->get(), colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
812				colorImageAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(colorImageAlloc)));
813
814				attachments.push_back(colorAttachmentDescription);
815				colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
816
817				const VkAttachmentReference colorAttachmentReference = {
818					(deUint32) (colorImages.size() - 1),			//	deUint32		attachment;
819					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		//	VkImageLayout	layout;
820				};
821
822				colorAttachmentReferences.push_back(colorAttachmentReference);
823			}
824
825			// Create color attachment view
826			{
827				const VkImageViewCreateInfo colorImageViewParams =
828				{
829					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
830					DE_NULL,											// const void*				pNext;
831					0u,													// VkImageViewCreateFlags	flags;
832					colorImages.back().get()->get(),					// VkImage					image;
833					VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
834					colorFormat,										// VkFormat					format;
835					{
836						VK_COMPONENT_SWIZZLE_R,							// VkComponentSwizzle		r;
837						VK_COMPONENT_SWIZZLE_G,							// VkComponentSwizzle		g;
838						VK_COMPONENT_SWIZZLE_B,							// VkComponentSwizzle		b;
839						VK_COMPONENT_SWIZZLE_A							// VkComponentSwizzle		a;
840					},													// VkComponentMapping		components;
841					{
842						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags		aspectMask;
843						0u,												// deUint32					baseMipLevel;
844						1u,												// deUint32					mipLevels;
845						0u,												// deUint32					baseArraySlice;
846						1u												// deUint32					arraySize;
847					}													// VkImageSubresourceRange	subresourceRange;
848				};
849
850				Move<VkImageView> colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
851				colorImageViews.push_back(de::SharedPtr<Unique<VkImageView> >(new Unique<VkImageView>(colorImageView)));
852
853				const VkImageMemoryBarrier	colorImagePreRenderBarrier =
854				{
855					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// sType
856					DE_NULL,												// pNext
857					0u,														// srcAccessMask
858					(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
859					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),					// dstAccessMask
860					VK_IMAGE_LAYOUT_UNDEFINED,								// oldLayout
861					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// newLayout
862					VK_QUEUE_FAMILY_IGNORED,								// srcQueueFamilyIndex
863					VK_QUEUE_FAMILY_IGNORED,								// dstQueueFamilyIndex
864					colorImages.back().get()->get(),						// image
865					{
866						VK_IMAGE_ASPECT_COLOR_BIT,								// aspectMask
867						0u,														// baseMipLevel
868						1u,														// levelCount
869						0u,														// baseArrayLayer
870						1u,														// layerCount
871					}														// subresourceRange
872				};
873				colorImagePreRenderBarriers.push_back(colorImagePreRenderBarrier);
874
875				const VkImageMemoryBarrier	colorImagePostRenderBarrier =
876				{
877					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// sType
878					DE_NULL,												// pNext
879					(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
880					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),					// srcAccessMask
881					VK_ACCESS_TRANSFER_READ_BIT,							// dstAccessMask
882					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// oldLayout
883					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,					// newLayout
884					VK_QUEUE_FAMILY_IGNORED,								// srcQueueFamilyIndex
885					VK_QUEUE_FAMILY_IGNORED,								// dstQueueFamilyIndex
886					colorImages.back().get()->get(),						// image
887					{
888						VK_IMAGE_ASPECT_COLOR_BIT,								// aspectMask
889						0u,														// baseMipLevel
890						1u,														// levelCount
891						0u,														// baseArrayLayer
892						1u,														// layerCount
893					}														// subresourceRange
894				};
895				colorImagePostRenderBarriers.push_back(colorImagePostRenderBarrier);
896			}
897		}
898	}
899
900	// Create render pass
901	{
902		const VkSubpassDescription subpassDescription =
903		{
904			0u,													// VkSubpassDescriptionFlags	flags;
905			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint			pipelineBindPoint;
906			0u,													// deUint32						inputCount;
907			DE_NULL,											// const VkAttachmentReference*	pInputAttachments;
908			(deUint32)colorImages.size(),						// deUint32						colorCount;
909			&colorAttachmentReferences[0],						// const VkAttachmentReference*	colorAttachments;
910			DE_NULL,											// const VkAttachmentReference*	resolveAttachments;
911			DE_NULL,											// VkAttachmentReference		depthStencilAttachment;
912			0u,													// deUint32						preserveCount;
913			DE_NULL												// const VkAttachmentReference*	pPreserveAttachments;
914		};
915
916		const VkRenderPassCreateInfo renderPassParams =
917		{
918			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
919			DE_NULL,											// const void*						pNext;
920			(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
921			(deUint32)attachments.size(),						// deUint32							attachmentCount;
922			&attachments[0],									// const VkAttachmentDescription*	pAttachments;
923			1u,													// deUint32							subpassCount;
924			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
925			0u,													// deUint32							dependencyCount;
926			DE_NULL												// const VkSubpassDependency*		pDependencies;
927		};
928
929		renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
930	}
931
932	// Create framebuffer
933	{
934		std::vector<VkImageView> views(colorImageViews.size());
935		for (size_t i = 0; i < colorImageViews.size(); i++)
936		{
937			views[i] = colorImageViews[i].get()->get();
938		}
939
940		const VkFramebufferCreateInfo framebufferParams =
941		{
942			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
943			DE_NULL,											// const void*					pNext;
944			0u,													// VkFramebufferCreateFlags		flags;
945			*renderPass,										// VkRenderPass					renderPass;
946			(deUint32)views.size(),								// deUint32						attachmentCount;
947			&views[0],											// const VkImageView*			pAttachments;
948			(deUint32)renderSize.x(),							// deUint32						width;
949			(deUint32)renderSize.y(),							// deUint32						height;
950			1u													// deUint32						layers;
951		};
952
953		framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
954	}
955
956	// Create descriptors
957	{
958		addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
959
960		descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
961		if (!m_uniformInfos.empty())
962			descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
963		else
964		{
965			const VkDescriptorPoolSize 			poolSizeCount 	= { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 };
966			const VkDescriptorPoolCreateInfo	createInfo 		=
967			{
968				VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
969				DE_NULL,
970				VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
971				1u,
972				1u,
973				&poolSizeCount,
974			};
975
976			descriptorPool = createDescriptorPool(vk, vkDevice, &createInfo);
977		}
978
979		const VkDescriptorSetAllocateInfo allocInfo =
980		{
981			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
982			DE_NULL,
983			*descriptorPool,
984			1u,
985			&*descriptorSetLayout
986		};
987
988		descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
989
990		// Update descriptors
991		{
992			vk::DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
993
994			uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
995
996			descriptorSetUpdateBuilder.update(vk, vkDevice);
997		}
998	}
999
1000	// Create pipeline layout
1001	{
1002		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1003		{
1004			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
1005			DE_NULL,											// const void*					pNext;
1006			(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
1007			1,													// deUint32						descriptorSetCount;
1008			&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
1009			0u,													// deUint32						pushConstantRangeCount;
1010			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
1011		};
1012
1013		pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1014	}
1015
1016	// Create shaders
1017	{
1018		vertexShaderModule		= createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
1019		fragmentShaderModule	= createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
1020
1021		if (useGeometryShader)
1022		{
1023			geometryShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("geom"), 0);
1024		}
1025	}
1026
1027	// Create pipeline
1028	{
1029		std::vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
1030
1031		const VkPipelineShaderStageCreateInfo vertexShaderStageParams =
1032		{
1033			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
1034			DE_NULL,													// const void*							pNext;
1035			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
1036			VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
1037			*vertexShaderModule,										// VkShaderModule						module;
1038			"main",														// const char*							pName;
1039			DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
1040		};
1041
1042		const VkPipelineShaderStageCreateInfo fragmentShaderStageParams =
1043		{
1044			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
1045			DE_NULL,													// const void*							pNext;
1046			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
1047			VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
1048			*fragmentShaderModule,										// VkShaderModule						module;
1049			"main",														// const char*							pName;
1050			DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
1051		};
1052
1053		shaderStageParams.push_back(vertexShaderStageParams);
1054		shaderStageParams.push_back(fragmentShaderStageParams);
1055
1056		if (useGeometryShader)
1057		{
1058			const VkPipelineShaderStageCreateInfo geometryShaderStageParams =
1059			{
1060				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
1061				DE_NULL,													// const void*							pNext;
1062				(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
1063				VK_SHADER_STAGE_GEOMETRY_BIT,								// VkShaderStageFlagBits				stage;
1064				*geometryShaderModule,										// VkShaderModule						module;
1065				"main",														// VkShader								shader;
1066				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
1067			};
1068
1069			shaderStageParams.push_back(geometryShaderStageParams);
1070		}
1071
1072		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1073		{
1074			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType								sType;
1075			DE_NULL,													// const void*									pNext;
1076			(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags		flags;
1077			(deUint32)m_vertexBindingDescriptions.size(),				// deUint32										bindingCount;
1078			&m_vertexBindingDescriptions[0],							// const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
1079			(deUint32)m_vertexAttributeDescriptions.size(),				// deUint32										attributeCount;
1080			&m_vertexAttributeDescriptions[0],							// const VkVertexInputAttributeDescription*		pvertexAttributeDescriptions;
1081		};
1082
1083		const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1084		{
1085			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
1086			DE_NULL,														// const void*								pNext;
1087			(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
1088			VK_PRIMITIVE_TOPOLOGY_POINT_LIST,								// VkPrimitiveTopology						topology;
1089			DE_FALSE														// VkBool32									primitiveRestartEnable;
1090		};
1091
1092		const VkViewport viewport =
1093		{
1094			0.0f,						// float	originX;
1095			0.0f,						// float	originY;
1096			(float)renderSize.x(),		// float	width;
1097			(float)renderSize.y(),		// float	height;
1098			0.0f,						// float	minDepth;
1099			1.0f						// float	maxDepth;
1100		};
1101
1102		const VkRect2D scissor =
1103		{
1104			{
1105				0u,						// deUint32	x;
1106				0u,						// deUint32	y;
1107			},							// VkOffset2D	offset;
1108			{
1109				renderSize.x(),			// deUint32	width;
1110				renderSize.y(),			// deUint32	height;
1111			},							// VkExtent2D	extent;
1112		};
1113
1114		const VkPipelineViewportStateCreateInfo viewportStateParams =
1115		{
1116			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType										sType;
1117			DE_NULL,												// const void*											pNext;
1118			0u,														// VkPipelineViewportStateCreateFlags					flags;
1119			1u,														// deUint32												viewportCount;
1120			&viewport,												// const VkViewport*									pViewports;
1121			1u,														// deUint32												scissorsCount;
1122			&scissor												// const VkRect2D*										pScissors;
1123		};
1124
1125		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1126		{
1127			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType								sType;
1128			DE_NULL,														// const void*									pNext;
1129			(VkPipelineRasterizationStateCreateFlags)0u,					//VkPipelineRasterizationStateCreateFlags		flags;
1130			VK_FALSE,														// VkBool32										depthClipEnable;
1131			VK_FALSE,														// VkBool32										rasterizerDiscardEnable;
1132			VK_POLYGON_MODE_FILL,											// VkPolygonMode								polygonMode;
1133			VK_CULL_MODE_NONE,												// VkCullModeFlags								cullMode;
1134			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace									frontFace;
1135			VK_FALSE,														// VkBool32										depthBiasEnable;
1136			0.0f,															// float										depthBias;
1137			0.0f,															// float										depthBiasClamp;
1138			0.0f,															// float										slopeScaledDepthBias;
1139			1.0f															// float										lineWidth;
1140		};
1141
1142		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1143		{
1144			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
1145			DE_NULL,														// const void*								pNext;
1146			0u,																// VkPipelineMultisampleStateCreateFlags	flags;
1147			VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
1148			VK_FALSE,														// VkBool32									sampleShadingEnable;
1149			0.0f,															// float									minSampleShading;
1150			DE_NULL,														// const VkSampleMask*						pSampleMask;
1151			VK_FALSE,														// VkBool32									alphaToCoverageEnable;
1152			VK_FALSE														// VkBool32									alphaToOneEnable;
1153		};
1154
1155		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1156		{
1157			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
1158			DE_NULL,														// const void*									pNext;
1159			(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags			flags;
1160			VK_FALSE,														// VkBool32										logicOpEnable;
1161			VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
1162			(deUint32)colorBlendAttachmentStates.size(),					// deUint32										attachmentCount;
1163			&colorBlendAttachmentStates[0],									// const VkPipelineColorBlendAttachmentState*	pAttachments;
1164			{ 0.0f, 0.0f, 0.0f, 0.0f }										// float										blendConst[4];
1165		};
1166
1167		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1168		{
1169			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
1170			DE_NULL,											// const void*										pNext;
1171			(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
1172			(deUint32)shaderStageParams.size(),					// deUint32											stageCount;
1173			&shaderStageParams[0],								// const VkPipelineShaderStageCreateInfo*			pStages;
1174			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
1175			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
1176			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
1177			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
1178			&rasterStateParams,									// const VkPipelineRasterStateCreateInfo*			pRasterState;
1179			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
1180			DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
1181			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
1182			(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
1183			*pipelineLayout,									// VkPipelineLayout									layout;
1184			*renderPass,										// VkRenderPass										renderPass;
1185			0u,													// deUint32											subpass;
1186			0u,													// VkPipeline										basePipelineHandle;
1187			0u													// deInt32											basePipelineIndex;
1188		};
1189
1190		graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1191	}
1192
1193	// Create command pool
1194	{
1195		const VkCommandPoolCreateInfo cmdPoolParams =
1196		{
1197			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType		sType;
1198			DE_NULL,											// const void*			pNext;
1199			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,				// VkCmdPoolCreateFlags	flags;
1200			queueFamilyIndex,									// deUint32				queueFamilyIndex;
1201		};
1202
1203		cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1204	}
1205
1206	// Create command buffer
1207	{
1208		const VkCommandBufferAllocateInfo cmdBufferParams =
1209		{
1210			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
1211			DE_NULL,										// const void*				pNext;
1212			*cmdPool,										// VkCmdPool				cmdPool;
1213			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCmdBufferLevel			level;
1214			1												// deUint32					bufferCount;
1215		};
1216
1217		const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1218		{
1219			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType				sType;
1220			DE_NULL,										// const void*					pNext;
1221			0u,												// VkCmdBufferOptimizeFlags		flags;
1222			(const VkCommandBufferInheritanceInfo*)DE_NULL,
1223		};
1224
1225		const VkRenderPassBeginInfo renderPassBeginInfo =
1226		{
1227			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
1228			DE_NULL,												// const void*			pNext;
1229			*renderPass,											// VkRenderPass			renderPass;
1230			*framebuffer,											// VkFramebuffer		framebuffer;
1231			{ { 0, 0 }, { renderSize.x(), renderSize.y() } },		// VkRect2D				renderArea;
1232			(deUint32)attachmentClearValues.size(),					// deUint32				attachmentCount;
1233			&attachmentClearValues[0]								// const VkClearValue*	pAttachmentClearValues;
1234		};
1235
1236		cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1237
1238		VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1239
1240		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1241							  0, (const VkMemoryBarrier*)DE_NULL,
1242							  0, (const VkBufferMemoryBarrier*)DE_NULL,
1243							  (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1244		vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1245
1246		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1247		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
1248
1249		const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1250
1251		std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1252
1253		std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1254		for (size_t i = 0; i < numberOfVertexAttributes; i++)
1255		{
1256			buffers[i] = m_vertexBuffers[i].get()->get();
1257		}
1258
1259		vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1260		vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1261
1262		vk.cmdEndRenderPass(*cmdBuffer);
1263		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1264							  0, (const VkMemoryBarrier*)DE_NULL,
1265							  0, (const VkBufferMemoryBarrier*)DE_NULL,
1266							  (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1267
1268		VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1269	}
1270
1271	// Create fence
1272	{
1273		const VkFenceCreateInfo fenceParams =
1274		{
1275			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
1276			DE_NULL,								// const void*			pNext;
1277			0u										// VkFenceCreateFlags	flags;
1278		};
1279
1280		fence = createFence(vk, vkDevice, &fenceParams);
1281	}
1282
1283	// Execute Draw
1284	{
1285
1286		const VkSubmitInfo submitInfo =
1287		{
1288			VK_STRUCTURE_TYPE_SUBMIT_INFO,			// sType
1289			DE_NULL,								// pNext
1290			0u,										// waitSemaphoreCount
1291			DE_NULL,								// pWaitSemaphores
1292			(const VkPipelineStageFlags*)DE_NULL,
1293			1u,										// commandBufferCount
1294			&cmdBuffer.get(),						// pCommandBuffers
1295			0u,										// signalSemaphoreCount
1296			DE_NULL									// pSignalSemaphores
1297		};
1298
1299		VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1300		VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1301		VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1302	}
1303
1304	// Read back result and output
1305	{
1306		const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1307		const VkBufferCreateInfo readImageBufferParams =
1308		{
1309			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1310			DE_NULL,									// const void*			pNext;
1311			0u,											// VkBufferCreateFlags	flags;
1312			imageSizeBytes,								// VkDeviceSize			size;
1313			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
1314			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1315			1u,											// deUint32				queueFamilyCount;
1316			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1317		};
1318
1319		// constants for image copy
1320
1321		const VkCommandPoolCreateInfo cmdPoolParams =
1322		{
1323			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,	// VkStructureType		sType;
1324			DE_NULL,									// const void*			pNext;
1325			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,		// VkCmdPoolCreateFlags	flags;
1326			queueFamilyIndex							// deUint32				queueFamilyIndex;
1327		};
1328
1329		Move<VkCommandPool>	copyCmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1330
1331		const VkCommandBufferAllocateInfo cmdBufferParams =
1332		{
1333			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
1334			DE_NULL,										// const void*				pNext;
1335			*copyCmdPool,									// VkCmdPool				cmdPool;
1336			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCmdBufferLevel			level;
1337			1u												// deUint32					bufferCount;
1338		};
1339
1340		const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1341		{
1342			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
1343			DE_NULL,										// const void*						pNext;
1344			0u,												// VkCmdBufferOptimizeFlags			flags;
1345			(const VkCommandBufferInheritanceInfo*)DE_NULL,
1346		};
1347
1348		const VkBufferImageCopy copyParams =
1349		{
1350			0u,											// VkDeviceSize			bufferOffset;
1351			(deUint32)renderSize.x(),					// deUint32				bufferRowLength;
1352			(deUint32)renderSize.y(),					// deUint32				bufferImageHeight;
1353			{
1354				VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspect		aspect;
1355				0u,										// deUint32				mipLevel;
1356				0u,										// deUint32				arraySlice;
1357				1u,										// deUint32				arraySize;
1358			},											// VkImageSubresource	imageSubresource;
1359			{ 0u, 0u, 0u },								// VkOffset3D			imageOffset;
1360			{ renderSize.x(), renderSize.y(), 1u }		// VkExtent3D			imageExtent;
1361		};
1362
1363		// Read back pixels.
1364		for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1365		{
1366			const Symbol&				output			= m_shaderSpec.outputs[outNdx];
1367			const int					outSize			= output.varType.getScalarSize();
1368			const int					outVecSize		= glu::getDataTypeNumComponents(output.varType.getBasicType());
1369			const int					outNumLocs		= glu::getDataTypeNumLocations(output.varType.getBasicType());
1370			deUint32*					dstPtrBase		= static_cast<deUint32*>(outputs[outNdx]);
1371			const int					outLocation		= de::lookup(m_outputLayout.locationMap, output.name);
1372
1373			for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1374			{
1375				tcu::TextureLevel			tmpBuf;
1376				const tcu::TextureFormat	format = getRenderbufferFormatForOutput(output.varType, false);
1377				const tcu::TextureFormat	readFormat (tcu::TextureFormat::RGBA, format.type);
1378				const Unique<VkBuffer>		readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1379				const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1380
1381				VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1382
1383				// Copy image to buffer
1384				{
1385
1386					Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1387
1388					const VkSubmitInfo submitInfo =
1389					{
1390						VK_STRUCTURE_TYPE_SUBMIT_INFO,
1391						DE_NULL,
1392						0u,
1393						(const VkSemaphore*)DE_NULL,
1394						(const VkPipelineStageFlags*)DE_NULL,
1395						1u,
1396						&copyCmdBuffer.get(),
1397						0u,
1398						(const VkSemaphore*)DE_NULL,
1399					};
1400
1401					VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1402					vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
1403					VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1404
1405					VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1406					VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1407					VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1408				}
1409
1410				const VkMappedMemoryRange range =
1411				{
1412					VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// VkStructureType	sType;
1413					DE_NULL,								// const void*		pNext;
1414					readImageBufferMemory->getMemory(),		// VkDeviceMemory	mem;
1415					0,										// VkDeviceSize		offset;
1416					imageSizeBytes,							// VkDeviceSize		size;
1417				};
1418
1419				VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1420
1421				tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1422
1423				const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1424				const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1425
1426				tcu::copy(tmpBuf.getAccess(), resultAccess);
1427
1428				if (outSize == 4 && outNumLocs == 1)
1429					deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1430				else
1431				{
1432					for (int valNdx = 0; valNdx < numValues; valNdx++)
1433					{
1434						const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1435						deUint32*		dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1436						deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1437					}
1438				}
1439			}
1440		}
1441	}
1442}
1443
1444// VertexShaderExecutor
1445
1446class VertexShaderExecutor : public FragmentOutExecutor
1447{
1448public:
1449								VertexShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1450	virtual						~VertexShaderExecutor	(void);
1451
1452	virtual void				log						(tcu::TestLog& dst) const { /* TODO */ (void)dst;}
1453
1454	virtual void				setShaderSources		(SourceCollections& programCollection) const;
1455
1456};
1457
1458VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1459	: FragmentOutExecutor		(shaderSpec, shaderType)
1460{
1461}
1462
1463VertexShaderExecutor::~VertexShaderExecutor (void)
1464{
1465}
1466
1467void VertexShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1468{
1469	programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(m_shaderSpec, "a_", "vtx_out_"));
1470	/* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1471	programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1472}
1473
1474// GeometryShaderExecutor
1475
1476class GeometryShaderExecutor : public FragmentOutExecutor
1477{
1478public:
1479								GeometryShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1480	virtual						~GeometryShaderExecutor	(void);
1481
1482	virtual void				log						(tcu::TestLog& dst) const	{ /* TODO */ (void)dst; }
1483
1484	virtual void				setShaderSources		(SourceCollections& programCollection) const;
1485
1486};
1487
1488GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1489	: FragmentOutExecutor		(shaderSpec, shaderType)
1490{
1491}
1492
1493GeometryShaderExecutor::~GeometryShaderExecutor (void)
1494{
1495}
1496
1497void GeometryShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1498{
1499	programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1500
1501	programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(m_shaderSpec, "vtx_out_", "geom_out_"));
1502
1503	/* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1504	programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "geom_out_", "o_"));
1505
1506}
1507
1508// FragmentShaderExecutor
1509
1510class FragmentShaderExecutor : public FragmentOutExecutor
1511{
1512public:
1513								FragmentShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1514	virtual						~FragmentShaderExecutor (void);
1515
1516	virtual void				log						(tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1517
1518	virtual void				setShaderSources		(SourceCollections& programCollection) const;
1519
1520};
1521
1522FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1523	: FragmentOutExecutor		(shaderSpec, shaderType)
1524{
1525}
1526
1527FragmentShaderExecutor::~FragmentShaderExecutor (void)
1528{
1529}
1530
1531void FragmentShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1532{
1533	programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1534	/* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1535	programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1536}
1537
1538// Shared utilities for compute and tess executors
1539
1540static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1541{
1542	switch (glu::getDataTypeScalarSize(type))
1543	{
1544		case 1:		return 4u;
1545		case 2:		return 8u;
1546		case 3:		return 16u;
1547		case 4:		return 16u;
1548		default:
1549			DE_ASSERT(false);
1550			return 0u;
1551	}
1552}
1553
1554class BufferIoExecutor : public ShaderExecutor
1555{
1556public:
1557							BufferIoExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1558	virtual					~BufferIoExecutor	(void);
1559
1560	virtual void			log					(tcu::TestLog& dst) const	{ /* TODO */ (void)dst; }
1561
1562protected:
1563	enum
1564	{
1565		INPUT_BUFFER_BINDING	= 0,
1566		OUTPUT_BUFFER_BINDING	= 1,
1567	};
1568
1569	void					initBuffers			(const Context& ctx, int numValues);
1570	VkBuffer				getInputBuffer		(void) const		{ return *m_inputBuffer;					}
1571	VkBuffer				getOutputBuffer		(void) const		{ return *m_outputBuffer;					}
1572	deUint32				getInputStride		(void) const		{ return getLayoutStride(m_inputLayout);	}
1573	deUint32				getOutputStride		(void) const		{ return getLayoutStride(m_outputLayout);	}
1574
1575	void					uploadInputBuffer	(const Context& ctx, const void* const* inputPtrs, int numValues);
1576	void					readOutputBuffer	(const Context& ctx, void* const* outputPtrs, int numValues);
1577
1578	static void				declareBufferBlocks	(std::ostream& src, const ShaderSpec& spec);
1579	static void				generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1580
1581protected:
1582	Move<VkBuffer>			m_inputBuffer;
1583	Move<VkBuffer>			m_outputBuffer;
1584
1585private:
1586	struct VarLayout
1587	{
1588		deUint32		offset;
1589		deUint32		stride;
1590		deUint32		matrixStride;
1591
1592		VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1593	};
1594
1595	static void				computeVarLayout	(const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1596	static deUint32			getLayoutStride		(const vector<VarLayout>& layout);
1597
1598	static void				copyToBuffer		(const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1599	static void				copyFromBuffer		(const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1600
1601	de::MovePtr<Allocation>	m_inputAlloc;
1602	de::MovePtr<Allocation>	m_outputAlloc;
1603
1604	vector<VarLayout>		m_inputLayout;
1605	vector<VarLayout>		m_outputLayout;
1606};
1607
1608BufferIoExecutor::BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1609	: ShaderExecutor (shaderSpec, shaderType)
1610{
1611	computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1612	computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1613}
1614
1615BufferIoExecutor::~BufferIoExecutor (void)
1616{
1617}
1618
1619inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1620{
1621	return layout.empty() ? 0 : layout[0].stride;
1622}
1623
1624void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1625{
1626	deUint32	maxAlignment	= 0;
1627	deUint32	curOffset		= 0;
1628
1629	DE_ASSERT(layout != DE_NULL);
1630	DE_ASSERT(layout->empty());
1631	layout->resize(symbols.size());
1632
1633	for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1634	{
1635		const Symbol&		symbol		= symbols[varNdx];
1636		const glu::DataType	basicType	= symbol.varType.getBasicType();
1637		VarLayout&			layoutEntry	= (*layout)[varNdx];
1638
1639		if (glu::isDataTypeScalarOrVector(basicType))
1640		{
1641			const deUint32	alignment	= getVecStd430ByteAlignment(basicType);
1642			const deUint32	size		= (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1643
1644			curOffset		= (deUint32)deAlign32((int)curOffset, (int)alignment);
1645			maxAlignment	= de::max(maxAlignment, alignment);
1646
1647			layoutEntry.offset			= curOffset;
1648			layoutEntry.matrixStride	= 0;
1649
1650			curOffset += size;
1651		}
1652		else if (glu::isDataTypeMatrix(basicType))
1653		{
1654			const int				numVecs			= glu::getDataTypeMatrixNumColumns(basicType);
1655			const glu::DataType		vecType			= glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1656			const deUint32			vecAlignment	= getVecStd430ByteAlignment(vecType);
1657
1658			curOffset		= (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1659			maxAlignment	= de::max(maxAlignment, vecAlignment);
1660
1661			layoutEntry.offset			= curOffset;
1662			layoutEntry.matrixStride	= vecAlignment;
1663
1664			curOffset += vecAlignment*numVecs;
1665		}
1666		else
1667			DE_ASSERT(false);
1668	}
1669
1670	{
1671		const deUint32	totalSize	= (deUint32)deAlign32(curOffset, maxAlignment);
1672
1673		for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1674			varIter->stride = totalSize;
1675	}
1676}
1677
1678void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1679{
1680	// Input struct
1681	if (!spec.inputs.empty())
1682	{
1683		glu::StructType inputStruct("Inputs");
1684		for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1685			inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1686		src << glu::declare(&inputStruct) << ";\n";
1687	}
1688
1689	// Output struct
1690	{
1691		glu::StructType outputStruct("Outputs");
1692		for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1693			outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1694		src << glu::declare(&outputStruct) << ";\n";
1695	}
1696
1697	src << "\n";
1698
1699	if (!spec.inputs.empty())
1700	{
1701		src	<< "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1702			<< "{\n"
1703			<< "	Inputs inputs[];\n"
1704			<< "};\n";
1705	}
1706
1707	src	<< "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1708		<< "{\n"
1709		<< "	Outputs outputs[];\n"
1710		<< "};\n"
1711		<< "\n";
1712}
1713
1714void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1715{
1716	for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1717		src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1718
1719	for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1720		src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1721
1722	src << "\n";
1723
1724	{
1725		std::istringstream	opSrc	(spec.source);
1726		std::string			line;
1727
1728		while (std::getline(opSrc, line))
1729			src << "\t" << line << "\n";
1730	}
1731
1732	src << "\n";
1733	for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1734		src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1735}
1736
1737void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1738{
1739	if (varType.isBasicType())
1740	{
1741		const glu::DataType		basicType		= varType.getBasicType();
1742		const bool				isMatrix		= glu::isDataTypeMatrix(basicType);
1743		const int				scalarSize		= glu::getDataTypeScalarSize(basicType);
1744		const int				numVecs			= isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1745		const int				numComps		= scalarSize / numVecs;
1746
1747		for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1748		{
1749			for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1750			{
1751				const int		srcOffset		= (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1752				const int		dstOffset		= layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1753				const deUint8*	srcPtr			= (const deUint8*)srcBasePtr + srcOffset;
1754				deUint8*		dstPtr			= (deUint8*)dstBasePtr + dstOffset;
1755
1756				deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1757			}
1758		}
1759	}
1760	else
1761		throw tcu::InternalError("Unsupported type");
1762}
1763
1764void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1765{
1766	if (varType.isBasicType())
1767	{
1768		const glu::DataType		basicType		= varType.getBasicType();
1769		const bool				isMatrix		= glu::isDataTypeMatrix(basicType);
1770		const int				scalarSize		= glu::getDataTypeScalarSize(basicType);
1771		const int				numVecs			= isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1772		const int				numComps		= scalarSize / numVecs;
1773
1774		for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1775		{
1776			for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1777			{
1778				const int		srcOffset		= layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1779				const int		dstOffset		= (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1780				const deUint8*	srcPtr			= (const deUint8*)srcBasePtr + srcOffset;
1781				deUint8*		dstPtr			= (deUint8*)dstBasePtr + dstOffset;
1782
1783				deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1784			}
1785		}
1786	}
1787	else
1788		throw tcu::InternalError("Unsupported type");
1789}
1790
1791void BufferIoExecutor::uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues)
1792{
1793	const VkDevice			vkDevice			= ctx.getDevice();
1794	const DeviceInterface&	vk					= ctx.getDeviceInterface();
1795
1796	const deUint32			inputStride			= getLayoutStride(m_inputLayout);
1797	const int				inputBufferSize		= inputStride * numValues;
1798
1799	if (inputBufferSize == 0)
1800		return; // No inputs
1801
1802	DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1803	for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1804	{
1805		const glu::VarType&		varType		= m_shaderSpec.inputs[inputNdx].varType;
1806		const VarLayout&		layout		= m_inputLayout[inputNdx];
1807
1808		copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1809	}
1810
1811	flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1812}
1813
1814void BufferIoExecutor::readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues)
1815{
1816	const VkDevice			vkDevice			= ctx.getDevice();
1817	const DeviceInterface&	vk					= ctx.getDeviceInterface();
1818
1819	const deUint32			outputStride		= getLayoutStride(m_outputLayout);
1820	const int				outputBufferSize	= numValues * outputStride;
1821
1822	DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1823
1824	invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1825
1826	DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1827	for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1828	{
1829		const glu::VarType&		varType		= m_shaderSpec.outputs[outputNdx].varType;
1830		const VarLayout&		layout		= m_outputLayout[outputNdx];
1831
1832		copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1833	}
1834}
1835
1836void BufferIoExecutor::initBuffers (const Context& ctx, int numValues)
1837{
1838	const deUint32				inputStride			= getLayoutStride(m_inputLayout);
1839	const deUint32				outputStride		= getLayoutStride(m_outputLayout);
1840	// Avoid creating zero-sized buffer/memory
1841	const size_t				inputBufferSize		= numValues * inputStride ? (numValues * inputStride) : 1;
1842	const size_t				outputBufferSize	= numValues * outputStride;
1843
1844	// Upload data to buffer
1845	const VkDevice				vkDevice			= ctx.getDevice();
1846	const DeviceInterface&		vk					= ctx.getDeviceInterface();
1847	const deUint32				queueFamilyIndex	= ctx.getUniversalQueueFamilyIndex();
1848	Allocator&					memAlloc			= ctx.getDefaultAllocator();
1849
1850	const VkBufferCreateInfo inputBufferParams =
1851	{
1852		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1853		DE_NULL,									// const void*			pNext;
1854		0u,											// VkBufferCreateFlags	flags;
1855		inputBufferSize,							// VkDeviceSize			size;
1856		VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,			// VkBufferUsageFlags	usage;
1857		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1858		1u,											// deUint32				queueFamilyCount;
1859		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
1860	};
1861
1862	m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1863	m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1864
1865	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1866
1867	const VkBufferCreateInfo outputBufferParams =
1868	{
1869		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1870		DE_NULL,									// const void*			pNext;
1871		0u,											// VkBufferCreateFlags	flags;
1872		outputBufferSize,							// VkDeviceSize			size;
1873		VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,			// VkBufferUsageFlags	usage;
1874		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1875		1u,											// deUint32				queueFamilyCount;
1876		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
1877	};
1878
1879	m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1880	m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1881
1882	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1883}
1884
1885// ComputeShaderExecutor
1886
1887class ComputeShaderExecutor : public BufferIoExecutor
1888{
1889public:
1890						ComputeShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1891	virtual				~ComputeShaderExecutor	(void);
1892
1893	virtual void		setShaderSources		(SourceCollections& programCollection) const;
1894
1895	virtual void		execute					(const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
1896
1897protected:
1898	static std::string	generateComputeShader	(const ShaderSpec& spec);
1899};
1900
1901ComputeShaderExecutor::ComputeShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1902	: BufferIoExecutor	(shaderSpec, shaderType)
1903{
1904}
1905
1906ComputeShaderExecutor::~ComputeShaderExecutor	(void)
1907{
1908}
1909
1910std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1911{
1912	std::ostringstream src;
1913	src <<  "#version 310 es\n";
1914
1915	if (!spec.globalDeclarations.empty())
1916		src << spec.globalDeclarations << "\n";
1917
1918	src << "layout(local_size_x = 1) in;\n"
1919		<< "\n";
1920
1921	declareBufferBlocks(src, spec);
1922
1923	src << "void main (void)\n"
1924		<< "{\n"
1925		<< "	uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1926		<< "	                   + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1927
1928	generateExecBufferIo(src, spec, "invocationNdx");
1929
1930	src << "}\n";
1931
1932	return src.str();
1933}
1934
1935void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1936{
1937	programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec));
1938}
1939
1940void ComputeShaderExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
1941{
1942	checkSupported(ctx, m_shaderType);
1943
1944	const VkDevice					vkDevice				= ctx.getDevice();
1945	const DeviceInterface&			vk						= ctx.getDeviceInterface();
1946	const VkQueue					queue					= ctx.getUniversalQueue();
1947	const deUint32					queueFamilyIndex		= ctx.getUniversalQueueFamilyIndex();
1948	Allocator&						memAlloc				= ctx.getDefaultAllocator();
1949
1950	Move<VkShaderModule>			computeShaderModule;
1951	Move<VkPipeline>				computePipeline;
1952	Move<VkPipelineLayout>			pipelineLayout;
1953	Move<VkCommandPool>				cmdPool;
1954	Move<VkDescriptorPool>			descriptorPool;
1955	Move<VkDescriptorSetLayout>		descriptorSetLayout;
1956	Move<VkDescriptorSet>			descriptorSet;
1957	Move<VkFence>					fence;
1958
1959	initBuffers(ctx, numValues);
1960
1961	// Setup input buffer & copy data
1962	uploadInputBuffer(ctx, inputs, numValues);
1963
1964	// Create command pool
1965	{
1966		const VkCommandPoolCreateInfo cmdPoolParams =
1967		{
1968			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType		sType;
1969			DE_NULL,										// const void*			pNext;
1970			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCmdPoolCreateFlags	flags;
1971			queueFamilyIndex								// deUint32				queueFamilyIndex;
1972		};
1973
1974		cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1975	}
1976
1977	// Create command buffer
1978	const VkCommandBufferAllocateInfo cmdBufferParams =
1979	{
1980		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
1981		DE_NULL,										// const void*				pNext;
1982		*cmdPool,										// VkCmdPool				cmdPool;
1983		VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCmdBufferLevel			level;
1984		1u												// deUint32					bufferCount;
1985	};
1986
1987	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1988	{
1989		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
1990		DE_NULL,										// const void*						pNext;
1991		0u,												// VkCmdBufferOptimizeFlags			flags;
1992		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1993	};
1994
1995	m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1996	m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1997	m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1998	m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1999
2000	addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
2001
2002	descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2003	descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2004
2005	const VkDescriptorSetAllocateInfo allocInfo =
2006	{
2007		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2008		DE_NULL,
2009		*descriptorPool,
2010		1u,
2011		&*descriptorSetLayout
2012	};
2013
2014	descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2015
2016	// Create pipeline layout
2017	{
2018		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2019		{
2020			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
2021			DE_NULL,											// const void*					pNext;
2022			(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
2023			1u,													// deUint32						CdescriptorSetCount;
2024			&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
2025			0u,													// deUint32						pushConstantRangeCount;
2026			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
2027		};
2028
2029		pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2030	}
2031
2032	// Create shaders
2033	{
2034		computeShaderModule		= createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("compute"), 0);
2035	}
2036
2037	// create pipeline
2038	{
2039		const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
2040		{
2041			{
2042				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
2043				DE_NULL,													// const void*							pNext;
2044				(VkPipelineShaderStageCreateFlags)0u,						// VkPipelineShaderStageCreateFlags		flags;
2045				VK_SHADER_STAGE_COMPUTE_BIT,								// VkShaderStageFlagsBit				stage;
2046				*computeShaderModule,										// VkShaderModule						shader;
2047				"main",														// const char*							pName;
2048				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
2049			}
2050		};
2051
2052		const VkComputePipelineCreateInfo computePipelineParams =
2053		{
2054			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType									sType;
2055			DE_NULL,											// const void*										pNext;
2056			(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
2057			*shaderStageParams,									// VkPipelineShaderStageCreateInfo					cs;
2058			*pipelineLayout,									// VkPipelineLayout									layout;
2059			0u,													// VkPipeline										basePipelineHandle;
2060			0u,													// int32_t											basePipelineIndex;
2061		};
2062
2063		computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2064	}
2065
2066	// Create fence
2067	{
2068		const VkFenceCreateInfo fenceParams =
2069		{
2070			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
2071			DE_NULL,								// const void*			pNext;
2072			0u										// VkFenceCreateFlags	flags;
2073		};
2074		fence = createFence(vk, vkDevice, &fenceParams);
2075	}
2076
2077	const int maxValuesPerInvocation	= ctx.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2078	int					curOffset		= 0;
2079	const deUint32		inputStride		= getInputStride();
2080	const deUint32		outputStride	= getOutputStride();
2081
2082	while (curOffset < numValues)
2083	{
2084		Move<VkCommandBuffer>		cmdBuffer;
2085		const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2086
2087		// Update descriptors
2088		{
2089			DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2090
2091			const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2092			{
2093				*m_outputBuffer,				// VkBuffer			buffer;
2094				curOffset * outputStride,		// VkDeviceSize		offset;
2095				numToExec * outputStride		// VkDeviceSize		range;
2096			};
2097
2098			descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2099
2100			if (inputStride)
2101			{
2102				const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2103				{
2104					*m_inputBuffer,					// VkBuffer			buffer;
2105					curOffset * inputStride,		// VkDeviceSize		offset;
2106					numToExec * inputStride			// VkDeviceSize		range;
2107				};
2108
2109				descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2110			}
2111
2112			uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2113
2114			descriptorSetUpdateBuilder.update(vk, vkDevice);
2115		}
2116
2117		cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2118		VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2119		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2120
2121		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2122
2123		vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2124
2125		VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2126
2127		curOffset += numToExec;
2128
2129		// Execute
2130		{
2131			VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2132
2133			const VkSubmitInfo submitInfo =
2134			{
2135				VK_STRUCTURE_TYPE_SUBMIT_INFO,
2136				DE_NULL,
2137				0u,
2138				(const VkSemaphore*)DE_NULL,
2139				(const VkPipelineStageFlags*)DE_NULL,
2140				1u,
2141				&cmdBuffer.get(),
2142				0u,
2143				(const VkSemaphore*)DE_NULL,
2144			};
2145
2146			VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2147			VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2148		}
2149	}
2150
2151	// Read back data
2152	readOutputBuffer(ctx, outputs, numValues);
2153}
2154
2155// Tessellation utils
2156
2157static std::string generateVertexShaderForTess (void)
2158{
2159	std::ostringstream	src;
2160	src <<  "#version 310 es\n"
2161		<< "void main (void)\n{\n"
2162		<< "	gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2163		<< "}\n";
2164
2165	return src.str();
2166}
2167
2168class TessellationExecutor : public BufferIoExecutor
2169{
2170public:
2171						TessellationExecutor		(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2172	virtual				~TessellationExecutor		(void);
2173
2174	void				renderTess					(const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints);
2175};
2176
2177TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2178	: BufferIoExecutor	(shaderSpec, shaderType)
2179{
2180}
2181
2182TessellationExecutor::~TessellationExecutor (void)
2183{
2184}
2185
2186void TessellationExecutor::renderTess (const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints)
2187{
2188	const size_t						inputBufferSize				= numValues * getInputStride();
2189	const VkDevice						vkDevice					= ctx.getDevice();
2190	const DeviceInterface&				vk							= ctx.getDeviceInterface();
2191	const VkQueue						queue						= ctx.getUniversalQueue();
2192	const deUint32						queueFamilyIndex			= ctx.getUniversalQueueFamilyIndex();
2193	Allocator&							memAlloc					= ctx.getDefaultAllocator();
2194
2195	const tcu::UVec2					renderSize					(DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2196
2197	Move<VkImage>						colorImage;
2198	de::MovePtr<Allocation>				colorImageAlloc;
2199	VkFormat							colorFormat					= VK_FORMAT_R8G8B8A8_UNORM;
2200	Move<VkImageView>					colorImageView;
2201
2202	Move<VkRenderPass>					renderPass;
2203	Move<VkFramebuffer>					framebuffer;
2204	Move<VkPipelineLayout>				pipelineLayout;
2205	Move<VkPipeline>					graphicsPipeline;
2206
2207	Move<VkShaderModule>				vertexShaderModule;
2208	Move<VkShaderModule>				tessControlShaderModule;
2209	Move<VkShaderModule>				tessEvalShaderModule;
2210	Move<VkShaderModule>				fragmentShaderModule;
2211
2212	Move<VkCommandPool>					cmdPool;
2213	Move<VkCommandBuffer>				cmdBuffer;
2214
2215	Move<VkFence>						fence;
2216
2217	Move<VkDescriptorPool>				descriptorPool;
2218	Move<VkDescriptorSetLayout>			descriptorSetLayout;
2219	Move<VkDescriptorSet>				descriptorSet;
2220
2221	// Create color image
2222	{
2223		const VkImageCreateInfo colorImageParams =
2224		{
2225			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
2226			DE_NULL,																	// const void*				pNext;
2227			0u,																			// VkImageCreateFlags		flags;
2228			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
2229			colorFormat,																// VkFormat					format;
2230			{ renderSize.x(), renderSize.y(), 1u },										// VkExtent3D				extent;
2231			1u,																			// deUint32					mipLevels;
2232			1u,																			// deUint32					arraySize;
2233			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
2234			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
2235			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
2236			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
2237			1u,																			// deUint32					queueFamilyCount;
2238			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
2239			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
2240		};
2241
2242		colorImage = createImage(vk, vkDevice, &colorImageParams);
2243
2244		// Allocate and bind color image memory
2245		colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2246		VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2247	}
2248
2249	// Create color attachment view
2250	{
2251		const VkImageViewCreateInfo colorImageViewParams =
2252		{
2253			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
2254			DE_NULL,											// const void*				pNext;
2255			0u,													// VkImageViewCreateFlags	flags;
2256			*colorImage,										// VkImage					image;
2257			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
2258			colorFormat,										// VkFormat					format;
2259			{
2260				VK_COMPONENT_SWIZZLE_R,							// VkComponentSwizzle		r;
2261				VK_COMPONENT_SWIZZLE_G,							// VkComponentSwizzle		g;
2262				VK_COMPONENT_SWIZZLE_B,							// VkComponentSwizzle		b;
2263				VK_COMPONENT_SWIZZLE_A							// VkComponentSwizzle		a;
2264			},													// VkComponentsMapping		components;
2265			{
2266				VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags		aspectMask;
2267				0u,												// deUint32					baseMipLevel;
2268				1u,												// deUint32					mipLevels;
2269				0u,												// deUint32					baseArraylayer;
2270				1u												// deUint32					layerCount;
2271			}													// VkImageSubresourceRange	subresourceRange;
2272		};
2273
2274		colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2275	}
2276
2277	// Create render pass
2278	{
2279		const VkAttachmentDescription colorAttachmentDescription =
2280		{
2281			0u,													// VkAttachmentDescriptorFlags	flags;
2282			colorFormat,										// VkFormat						format;
2283			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits		samples;
2284			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp			loadOp;
2285			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp			storeOp;
2286			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp			stencilLoadOp;
2287			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp			stencilStoreOp;
2288			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout				initialLayout;
2289			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout				finalLayout
2290		};
2291
2292		const VkAttachmentDescription attachments[1] =
2293		{
2294			colorAttachmentDescription
2295		};
2296
2297		const VkAttachmentReference colorAttachmentReference =
2298		{
2299			0u,													// deUint32			attachment;
2300			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2301		};
2302
2303		const VkSubpassDescription subpassDescription =
2304		{
2305			0u,													// VkSubpassDescriptionFlags	flags;
2306			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint			pipelineBindPoint;
2307			0u,													// deUint32						inputCount;
2308			DE_NULL,											// const VkAttachmentReference*	pInputAttachments;
2309			1u,													// deUint32						colorCount;
2310			&colorAttachmentReference,							// const VkAttachmentReference*	pColorAttachments;
2311			DE_NULL,											// const VkAttachmentReference*	pResolveAttachments;
2312			DE_NULL,											// VkAttachmentReference		depthStencilAttachment;
2313			0u,													// deUint32						preserveCount;
2314			DE_NULL												// const VkAttachmentReference* pPreserveAttachments;
2315		};
2316
2317		const VkRenderPassCreateInfo renderPassParams =
2318		{
2319			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
2320			DE_NULL,											// const void*						pNext;
2321			0u,													// VkRenderPassCreateFlags			flags;
2322			1u,													// deUint32							attachmentCount;
2323			attachments,										// const VkAttachmentDescription*	pAttachments;
2324			1u,													// deUint32							subpassCount;
2325			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
2326			0u,													// deUint32							dependencyCount;
2327			DE_NULL												// const VkSubpassDependency*		pDependencies;
2328		};
2329
2330		renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2331	}
2332
2333	// Create framebuffer
2334	{
2335		const VkFramebufferCreateInfo framebufferParams =
2336		{
2337			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
2338			DE_NULL,											// const void*					pNext;
2339			0u,													// VkFramebufferCreateFlags		flags;
2340			*renderPass,										// VkRenderPass					renderPass;
2341			1u,													// deUint32						attachmentCount;
2342			&*colorImageView,									// const VkAttachmentBindInfo*	pAttachments;
2343			(deUint32)renderSize.x(),							// deUint32						width;
2344			(deUint32)renderSize.y(),							// deUint32						height;
2345			1u													// deUint32						layers;
2346		};
2347
2348		framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2349	}
2350
2351	// Create descriptors
2352	{
2353		m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2354		m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2355		m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2356		m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2357
2358		addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
2359
2360		descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2361		descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2362
2363		const VkDescriptorSetAllocateInfo allocInfo =
2364		{
2365			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2366			DE_NULL,
2367			*descriptorPool,
2368			1u,
2369			&*descriptorSetLayout
2370		};
2371
2372		descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2373		// Update descriptors
2374		{
2375			DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2376			const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2377			{
2378				*m_outputBuffer,				// VkBuffer			buffer;
2379				0u,								// VkDeviceSize		offset;
2380				VK_WHOLE_SIZE					// VkDeviceSize		range;
2381			};
2382
2383			descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2384
2385			VkDescriptorBufferInfo inputDescriptorBufferInfo =
2386			{
2387				0,							// VkBuffer			buffer;
2388				0u,							// VkDeviceSize		offset;
2389				VK_WHOLE_SIZE				// VkDeviceSize		range;
2390			};
2391
2392			if (inputBufferSize > 0)
2393			{
2394				inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2395
2396				descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2397			}
2398
2399			uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2400
2401			descriptorSetUpdateBuilder.update(vk, vkDevice);
2402		}
2403	}
2404
2405	// Create pipeline layout
2406	{
2407		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2408		{
2409			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
2410			DE_NULL,											// const void*					pNext;
2411			(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
2412			1u,													// deUint32						descriptorSetCount;
2413			&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
2414			0u,													// deUint32						pushConstantRangeCount;
2415			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
2416		};
2417
2418		pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2419	}
2420
2421	// Create shader modules
2422	{
2423		vertexShaderModule		= createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
2424		tessControlShaderModule	= createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_control"), 0);
2425		tessEvalShaderModule	= createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_eval"), 0);
2426		fragmentShaderModule	= createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
2427	}
2428
2429	// Create pipeline
2430	{
2431		const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2432		{
2433			{
2434				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
2435				DE_NULL,													// const void*							pNext;
2436				(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
2437				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBit					stage;
2438				*vertexShaderModule,										// VkShaderModule						shader;
2439				"main",														// const char*							pName;
2440				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
2441			},
2442			{
2443				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
2444				DE_NULL,													// const void*							pNext;
2445				(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
2446				VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,					// VkShaderStageFlagBit					stage;
2447				*tessControlShaderModule,									// VkShaderModule						shader;
2448				"main",														// const char*							pName;
2449				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
2450			},
2451			{
2452				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
2453				DE_NULL,													// const void*							pNext;
2454				(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
2455				VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,				// VkShaderStageFlagBit					stage;
2456				*tessEvalShaderModule,										// VkShaderModule						shader;
2457				"main",														// const char*							pName;
2458				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
2459			},
2460			{
2461				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
2462				DE_NULL,													// const void*							pNext;
2463				(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
2464				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBit					stage;
2465				*fragmentShaderModule,										// VkShaderModule						shader;
2466				"main",														// const char*							pName;
2467				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
2468			}
2469		};
2470
2471		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2472		{
2473			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
2474			DE_NULL,														// const void*								pNext;
2475			(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags	flags;
2476			0u,																// deUint32									bindingCount;
2477			DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
2478			0u,																// deUint32									attributeCount;
2479			DE_NULL,														// const VkVertexInputAttributeDescription*	pvertexAttributeDescriptions;
2480		};
2481
2482		const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2483		{
2484			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType						sType;
2485			DE_NULL,														// const void*							pNext;
2486			(VkPipelineShaderStageCreateFlags)0,							// VkPipelineShaderStageCreateFlags	flags;
2487			VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,								// VkPrimitiveTopology					topology;
2488			DE_FALSE														// VkBool32								primitiveRestartEnable;
2489		};
2490
2491		struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2492		{
2493			VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType							sType;
2494			DE_NULL,														// const void*								pNext;
2495			(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags	flags;
2496			patchControlPoints												// uint32_t									patchControlPoints;
2497		};
2498
2499		const VkViewport viewport =
2500		{
2501			0.0f,						// float	originX;
2502			0.0f,						// float	originY;
2503			(float)renderSize.x(),		// float	width;
2504			(float)renderSize.y(),		// float	height;
2505			0.0f,						// float	minDepth;
2506			1.0f						// float	maxDepth;
2507		};
2508
2509		const VkRect2D scissor =
2510		{
2511			{
2512				0u,						// deUint32	x;
2513				0u,						// deUint32	y;
2514			},							// VkOffset2D	offset;
2515			{
2516				renderSize.x(),			// deUint32	width;
2517				renderSize.y(),			// deUint32	height;
2518			},							// VkExtent2D	extent;
2519		};
2520
2521		const VkPipelineViewportStateCreateInfo viewportStateParams =
2522		{
2523			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType						sType;
2524			DE_NULL,												// const void*							pNext;
2525			(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewPortStateCreateFlags	flags;
2526			1u,														// deUint32								viewportCount;
2527			&viewport,												// const VkViewport*					pViewports;
2528			1u,														// deUint32								scissorsCount;
2529			&scissor												// const VkRect2D*						pScissors;
2530		};
2531
2532		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2533		{
2534			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
2535			DE_NULL,														// const void*								pNext;
2536			(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStageCreateFlags	flags;
2537			VK_FALSE,														// VkBool32									depthClipEnable;
2538			VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
2539			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
2540			VK_CULL_MODE_NONE,												// VkCullMode								cullMode;
2541			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
2542			VK_FALSE,														// VkBool32									depthBiasEnable;
2543			0.0f,															// float									depthBias;
2544			0.0f,															// float									depthBiasClamp;
2545			0.0f,															// float									slopeScaledDepthBias;
2546			1.0f															// float									lineWidth;
2547		};
2548
2549		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2550		{
2551			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
2552			DE_NULL,														// const void*								pNext;
2553			0u,																// VkPipelineMultisampleStateCreateFlags	flags;
2554			VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
2555			VK_FALSE,														// VkBool32									sampleShadingEnable;
2556			0.0f,															// float									minSampleShading;
2557			DE_NULL,														// const VkSampleMask*						pSampleMask;
2558			VK_FALSE,														// VkBool32									alphaToCoverageEnable;
2559			VK_FALSE														// VkBool32									alphaToOneEnable;
2560		};
2561
2562		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2563		{
2564			VK_FALSE,						// VkBool32					blendEnable;
2565			VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcBlendColor;
2566			VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			destBlendColor;
2567			VK_BLEND_OP_ADD,				// VkBlendOp				blendOpColor;
2568			VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcBlendAlpha;
2569			VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			destBlendAlpha;
2570			VK_BLEND_OP_ADD,				// VkBlendOp				blendOpAlpha;
2571			(VK_COLOR_COMPONENT_R_BIT |
2572			 VK_COLOR_COMPONENT_G_BIT |
2573			 VK_COLOR_COMPONENT_B_BIT |
2574			 VK_COLOR_COMPONENT_A_BIT)		// VkColorComponentFlags	colorWriteMask;
2575		};
2576
2577		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2578		{
2579			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
2580			DE_NULL,													// const void*									pNext;
2581			(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags
2582			VK_FALSE,													// VkBool32										logicOpEnable;
2583			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
2584			1u,															// deUint32										attachmentCount;
2585			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
2586			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConst[4];
2587		};
2588
2589		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2590		{
2591			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
2592			DE_NULL,											// const void*										pNext;
2593			0u,													// VkPipelineCreateFlags							flags;
2594			4u,													// deUint32											stageCount;
2595			shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
2596			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
2597			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
2598			&tessellationStateParams,							// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
2599			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
2600			&rasterStateParams,									// const VkPipelineRasterStateCreateInfo*			pRasterState;
2601			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
2602			DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
2603			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
2604			(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
2605			*pipelineLayout,									// VkPipelineLayout									layout;
2606			*renderPass,										// VkRenderPass										renderPass;
2607			0u,													// deUint32											subpass;
2608			0u,													// VkPipeline										basePipelineHandle;
2609			0u													// deInt32											basePipelineIndex;
2610		};
2611
2612		graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2613	}
2614
2615	// Create command pool
2616	{
2617		const VkCommandPoolCreateInfo cmdPoolParams =
2618		{
2619			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType		sType;
2620			DE_NULL,										// const void*			pNext;
2621			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCmdPoolCreateFlags	flags;
2622			queueFamilyIndex,								// deUint32				queueFamilyIndex;
2623		};
2624
2625		cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2626	}
2627
2628	// Create command buffer
2629	{
2630		const VkCommandBufferAllocateInfo cmdBufferParams =
2631		{
2632			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
2633			DE_NULL,										// const void*				pNext;
2634			*cmdPool,										// VkCmdPool				cmdPool;
2635			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCmdBufferLevel			level;
2636			1u												// uint32_t					bufferCount;
2637		};
2638
2639		const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2640		{
2641			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
2642			DE_NULL,										// const void*						pNext;
2643			0u,												// VkCmdBufferOptimizeFlags			flags;
2644			(const VkCommandBufferInheritanceInfo*)DE_NULL,
2645		};
2646
2647		const VkClearValue clearValues[1] =
2648		{
2649			getDefaultClearColor()
2650		};
2651
2652		const VkRenderPassBeginInfo renderPassBeginInfo =
2653		{
2654			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
2655			DE_NULL,												// const void*			pNext;
2656			*renderPass,											// VkRenderPass			renderPass;
2657			*framebuffer,											// VkFramebuffer		framebuffer;
2658			{ { 0, 0 }, { renderSize.x(), renderSize.y() } },		// VkRect2D				renderArea;
2659			1,														// deUint32				attachmentCount;
2660			clearValues												// const VkClearValue*	pClearValues;
2661		};
2662
2663		cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2664
2665		VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2666
2667		vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2668
2669		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2670
2671		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2672
2673		vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2674
2675		vk.cmdEndRenderPass(*cmdBuffer);
2676		VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2677	}
2678
2679	// Create fence
2680	{
2681		const VkFenceCreateInfo fenceParams =
2682		{
2683			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
2684			DE_NULL,								// const void*			pNext;
2685			0u										// VkFenceCreateFlags	flags;
2686		};
2687		fence = createFence(vk, vkDevice, &fenceParams);
2688	}
2689
2690	// Execute Draw
2691	{
2692		VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2693		const VkSubmitInfo submitInfo =
2694		{
2695			VK_STRUCTURE_TYPE_SUBMIT_INFO,
2696			DE_NULL,
2697			0u,
2698			(const VkSemaphore*)0,
2699			(const VkPipelineStageFlags*)DE_NULL,
2700			1u,
2701			&cmdBuffer.get(),
2702			0u,
2703			(const VkSemaphore*)0,
2704		};
2705		VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2706		VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2707	}
2708}
2709
2710// TessControlExecutor
2711
2712class TessControlExecutor : public TessellationExecutor
2713{
2714public:
2715						TessControlExecutor			(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2716	virtual				~TessControlExecutor		(void);
2717
2718	virtual void		setShaderSources			(SourceCollections& programCollection) const;
2719
2720	virtual void		execute						(const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2721
2722protected:
2723	static std::string	generateTessControlShader	(const ShaderSpec& shaderSpec);
2724};
2725
2726TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2727	: TessellationExecutor (shaderSpec, shaderType)
2728{
2729}
2730
2731TessControlExecutor::~TessControlExecutor (void)
2732{
2733}
2734
2735std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2736{
2737	std::ostringstream src;
2738	src <<  "#version 310 es\n"
2739			"#extension GL_EXT_tessellation_shader : require\n\n";
2740
2741	if (!shaderSpec.globalDeclarations.empty())
2742		src << shaderSpec.globalDeclarations << "\n";
2743
2744	src << "\nlayout(vertices = 1) out;\n\n";
2745
2746	declareBufferBlocks(src, shaderSpec);
2747
2748	src << "void main (void)\n{\n";
2749
2750	for (int ndx = 0; ndx < 2; ndx++)
2751		src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2752
2753	for (int ndx = 0; ndx < 4; ndx++)
2754		src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2755
2756	src << "\n"
2757		<< "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2758
2759	generateExecBufferIo(src, shaderSpec, "invocationId");
2760
2761	src << "}\n";
2762
2763	return src.str();
2764}
2765
2766static std::string generateEmptyTessEvalShader ()
2767{
2768	std::ostringstream src;
2769
2770	src <<  "#version 310 es\n"
2771			"#extension GL_EXT_tessellation_shader : require\n\n";
2772
2773	src << "layout(triangles, ccw) in;\n";
2774
2775	src << "\nvoid main (void)\n{\n"
2776		<< "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2777		<< "}\n";
2778
2779	return src.str();
2780}
2781
2782void TessControlExecutor::setShaderSources (SourceCollections& programCollection) const
2783{
2784	programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2785	programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(m_shaderSpec));
2786	programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader());
2787	programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2788}
2789
2790void TessControlExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2791{
2792	const deUint32	patchSize	= 3;
2793
2794	checkSupported(ctx, m_shaderType);
2795
2796	initBuffers(ctx, numValues);
2797
2798	// Setup input buffer & copy data
2799	uploadInputBuffer(ctx, inputs, numValues);
2800
2801	renderTess(ctx, numValues, patchSize * numValues, patchSize);
2802
2803	// Read back data
2804	readOutputBuffer(ctx, outputs, numValues);
2805}
2806
2807// TessEvaluationExecutor
2808
2809class TessEvaluationExecutor : public TessellationExecutor
2810{
2811public:
2812						TessEvaluationExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2813	virtual				~TessEvaluationExecutor	(void);
2814
2815	virtual void		setShaderSources		(SourceCollections& programCollection) const;
2816
2817	virtual void		execute					(const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2818
2819protected:
2820	static std::string	generateTessEvalShader	(const ShaderSpec& shaderSpec);
2821};
2822
2823TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2824	: TessellationExecutor (shaderSpec, shaderType)
2825{
2826}
2827
2828TessEvaluationExecutor::~TessEvaluationExecutor (void)
2829{
2830}
2831
2832static std::string generatePassthroughTessControlShader (void)
2833{
2834	std::ostringstream src;
2835
2836	src <<  "#version 310 es\n"
2837			"#extension GL_EXT_tessellation_shader : require\n\n";
2838
2839	src << "layout(vertices = 1) out;\n\n";
2840
2841	src << "void main (void)\n{\n";
2842
2843	for (int ndx = 0; ndx < 2; ndx++)
2844		src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2845
2846	for (int ndx = 0; ndx < 4; ndx++)
2847		src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2848
2849	src << "}\n";
2850
2851	return src.str();
2852}
2853
2854std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2855{
2856	std::ostringstream src;
2857
2858	src <<  "#version 310 es\n"
2859			"#extension GL_EXT_tessellation_shader : require\n\n";
2860
2861	if (!shaderSpec.globalDeclarations.empty())
2862		src << shaderSpec.globalDeclarations << "\n";
2863
2864	src << "\n";
2865
2866	src << "layout(isolines, equal_spacing) in;\n\n";
2867
2868	declareBufferBlocks(src, shaderSpec);
2869
2870	src << "void main (void)\n{\n"
2871		<< "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2872		<< "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2873
2874	generateExecBufferIo(src, shaderSpec, "invocationId");
2875
2876	src	<< "}\n";
2877
2878	return src.str();
2879}
2880
2881void TessEvaluationExecutor::setShaderSources (SourceCollections& programCollection) const
2882{
2883	programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2884	programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader());
2885	programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(m_shaderSpec));
2886	programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2887}
2888
2889void TessEvaluationExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2890{
2891	checkSupported(ctx, m_shaderType);
2892
2893	const int	patchSize		= 2;
2894	const int	alignedValues	= deAlign32(numValues, patchSize);
2895
2896	// Initialize buffers with aligned value count to make room for padding
2897	initBuffers(ctx, alignedValues);
2898
2899	// Setup input buffer & copy data
2900	uploadInputBuffer(ctx, inputs, numValues);
2901
2902	renderTess(ctx, (deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize);
2903
2904	// Read back data
2905	readOutputBuffer(ctx, outputs, numValues);
2906}
2907
2908} // anonymous
2909
2910// ShaderExecutor
2911
2912ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2913	: m_shaderSpec	(shaderSpec)
2914	, m_shaderType	(shaderType)
2915{
2916}
2917
2918ShaderExecutor::~ShaderExecutor (void)
2919{
2920}
2921
2922// Utilities
2923
2924ShaderExecutor* createExecutor (glu::ShaderType shaderType, const ShaderSpec& shaderSpec)
2925{
2926	switch (shaderType)
2927	{
2928		case glu::SHADERTYPE_VERTEX:					return new VertexShaderExecutor		(shaderSpec, shaderType);
2929		case glu::SHADERTYPE_TESSELLATION_CONTROL:		return new TessControlExecutor		(shaderSpec, shaderType);
2930		case glu::SHADERTYPE_TESSELLATION_EVALUATION:	return new TessEvaluationExecutor	(shaderSpec, shaderType);
2931		case glu::SHADERTYPE_GEOMETRY:					return new GeometryShaderExecutor	(shaderSpec, shaderType);
2932		case glu::SHADERTYPE_FRAGMENT:					return new FragmentShaderExecutor	(shaderSpec, shaderType);
2933		case glu::SHADERTYPE_COMPUTE:					return new ComputeShaderExecutor	(shaderSpec, shaderType);
2934		default:
2935			throw tcu::InternalError("Unsupported shader type");
2936	}
2937}
2938
2939de::MovePtr<ShaderExecutor::BufferUniform> ShaderExecutor::createBufferUniform (const VkDevice&				vkDevice,
2940																				const DeviceInterface&		vk,
2941																				const VkQueue				/*queue*/,
2942																				const deUint32				queueFamilyIndex,
2943																				Allocator&					memAlloc,
2944																				deUint32					bindingLocation,
2945																				VkDescriptorType			descriptorType,
2946																				deUint32					size,
2947																				const void*					dataPtr)
2948{
2949	DE_ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2950
2951	VkImageUsageFlags usage = descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2952
2953	const VkBufferCreateInfo uniformBufferParams =
2954	{
2955		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2956		DE_NULL,									// const void*			pNext;
2957		0u,											// VkBufferCreateFlags	flags;
2958		size,										// VkDeviceSize			size;
2959		usage,										// VkBufferUsageFlags	usage;
2960		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2961		1u,											// deUint32				queueFamilyIndexCount;
2962		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
2963	};
2964
2965	Move<VkBuffer>					buffer				= createBuffer(vk, vkDevice, &uniformBufferParams);
2966	de::MovePtr<Allocation>			alloc				= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
2967	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
2968
2969	deMemcpy(alloc->getHostPtr(), dataPtr, size);
2970	flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
2971
2972	de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
2973	uniformInfo->type = descriptorType;
2974	uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
2975	uniformInfo->location = bindingLocation;
2976	uniformInfo->buffer = VkBufferSp(new Unique<VkBuffer>(buffer));
2977	uniformInfo->alloc = AllocationSp(alloc.release());
2978
2979	return uniformInfo;
2980}
2981
2982void ShaderExecutor::setupUniformData (const VkDevice&				vkDevice,
2983									   const DeviceInterface&		vk,
2984									   const VkQueue				queue,
2985									   const deUint32				queueFamilyIndex,
2986									   Allocator&					memAlloc,
2987									   deUint32						bindingLocation,
2988									   VkDescriptorType				descriptorType,
2989									   deUint32						size,
2990									   const void*					dataPtr)
2991{
2992	de::MovePtr<BufferUniform>			uniform			= createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, dataPtr);
2993
2994	m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_ALL);
2995	m_descriptorPoolBuilder.addType(descriptorType);
2996
2997	m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
2998}
2999
3000void ShaderExecutor::setupUniformArray (const VkDevice&				vkDevice,
3001										const DeviceInterface&		vk,
3002										const VkQueue				queue,
3003										const deUint32				queueFamilyIndex,
3004										Allocator&					memAlloc,
3005										deUint32					bindingLocation,
3006										VkDescriptorType			descriptorType,
3007										deUint32					arraySize,
3008										deUint32					size,
3009										const void*					dataPtr)
3010{
3011	DE_ASSERT(arraySize > 0);
3012
3013	de::MovePtr<BufferArrayUniform>		bufferArray		(new BufferArrayUniform());
3014
3015	bufferArray->type = descriptorType;
3016	bufferArray->location = bindingLocation;
3017
3018	for (deUint32 ndx = 0; ndx < arraySize; ++ndx)
3019	{
3020		const void*						bufferData		= ((deUint8*)dataPtr) + (ndx * size);
3021		de::MovePtr<BufferUniform>		uniform			= createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, bufferData);
3022
3023		bufferArray->uniforms.push_back(BufferUniformSp(new de::UniquePtr<BufferUniform>(uniform)));
3024	}
3025
3026	m_descriptorSetLayoutBuilder.addArrayBinding(descriptorType, arraySize, VK_SHADER_STAGE_ALL);
3027	m_descriptorPoolBuilder.addType(descriptorType, arraySize);
3028
3029	m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(bufferArray)));
3030}
3031
3032void ShaderExecutor::setupSamplerData (const VkDevice&				vkDevice,
3033									   const DeviceInterface&		vk,
3034									   const VkQueue				queue,
3035									   const deUint32				queueFamilyIndex,
3036									   Allocator&					memAlloc,
3037									   deUint32						bindingLocation,
3038									   deUint32						numSamplers,
3039									   const tcu::Sampler&			refSampler,
3040									   const tcu::TextureFormat&	texFormat,
3041									   const tcu::IVec3&			texSize,
3042									   VkImageType					imageType,
3043									   VkImageViewType				imageViewType,
3044									   const void*					data)
3045{
3046	DE_ASSERT(numSamplers > 0);
3047
3048	de::MovePtr<SamplerArrayUniform>	samplers		(new SamplerArrayUniform());
3049
3050	samplers->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3051	samplers->location = bindingLocation;
3052
3053	for (deUint32 ndx = 0; ndx < numSamplers; ++ndx)
3054	{
3055		const int						offset			= ndx * texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
3056		const void*						samplerData		= ((deUint8*)data) + offset;
3057		de::MovePtr<SamplerUniform>		uniform			= createSamplerUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, refSampler, texFormat, texSize, imageType, imageViewType, samplerData);
3058
3059		samplers->uniforms.push_back(SamplerUniformSp(new de::UniquePtr<SamplerUniform>(uniform)));
3060	}
3061
3062	m_descriptorSetLayoutBuilder.addArraySamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, VK_SHADER_STAGE_ALL, DE_NULL);
3063	m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers);
3064
3065	m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers)));
3066}
3067
3068const void*	ShaderExecutor::getBufferPtr (const deUint32 bindingLocation) const
3069{
3070	std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin();
3071	for (; it != m_uniformInfos.end(); it++)
3072	{
3073		const UniformInfo* uniformInfo = it->get()->get();
3074		if (uniformInfo->getType() == UniformInfo::UNIFORM_TYPE_BUFFER && uniformInfo->location == bindingLocation)
3075		{
3076			const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3077			return bufferUniform->alloc->getHostPtr();
3078		}
3079	}
3080
3081	return DE_NULL;
3082}
3083
3084void ShaderExecutor::addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc)
3085{
3086	if (!m_uniformSetup)
3087		return;
3088
3089	for (std::vector<UniformDataSp>::const_iterator it = m_uniformSetup->uniforms().begin(); it != m_uniformSetup->uniforms().end(); ++it)
3090	{
3091		const UniformDataBase* uniformData = it->get()->get();
3092		uniformData->setup(*this, vkDevice, vk, queue, queueFamilyIndex, memAlloc);
3093	}
3094}
3095
3096void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet)
3097{
3098	for (std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); it != m_uniformInfos.end(); ++it)
3099	{
3100		const UniformInfo*							uniformInfo		= it->get()->get();
3101		UniformInfo::UniformType					uniformType		= uniformInfo->getType();
3102
3103		if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER_ARRAY)
3104		{
3105			const BufferArrayUniform*				arrayInfo		= static_cast<const BufferArrayUniform*>(uniformInfo);
3106			std::vector<VkDescriptorBufferInfo>		descriptors;
3107
3108			for (std::vector<BufferUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3109			{
3110				descriptors.push_back(ait->get()->get()->descriptor);
3111			}
3112
3113			descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3114		}
3115		else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER_ARRAY)
3116		{
3117			const SamplerArrayUniform*				arrayInfo		= static_cast<const SamplerArrayUniform*>(uniformInfo);
3118			std::vector<VkDescriptorImageInfo>		descriptors;
3119
3120			for (std::vector<SamplerUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3121			{
3122				descriptors.push_back(ait->get()->get()->descriptor);
3123			}
3124
3125			descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3126		}
3127		else if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER)
3128		{
3129			const BufferUniform*					bufferUniform	= static_cast<const BufferUniform*>(uniformInfo);
3130			descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bufferUniform->location), bufferUniform->type, &bufferUniform->descriptor);
3131		}
3132		else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER)
3133		{
3134			const SamplerUniform*					samplerUniform	= static_cast<const SamplerUniform*>(uniformInfo);
3135			descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
3136		}
3137	}
3138}
3139
3140void ShaderExecutor::uploadImage (const VkDevice&				vkDevice,
3141								  const DeviceInterface&		vk,
3142								  const VkQueue					queue,
3143								  const deUint32				queueFamilyIndex,
3144								  Allocator&					memAlloc,
3145								  const tcu::TextureFormat&		texFormat,
3146								  const tcu::IVec3&				texSize,
3147								  const void*					data,
3148								  const deUint32				arraySize,
3149								  const VkImageAspectFlags		aspectMask,
3150								  VkImage						destImage)
3151{
3152	deUint32						textureSize			= texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
3153	deUint32						bufferSize;
3154	Move<VkBuffer>					buffer;
3155	de::MovePtr<Allocation>			bufferAlloc;
3156	Move<VkCommandPool>				cmdPool;
3157	Move<VkCommandBuffer>			cmdBuffer;
3158	Move<VkFence>					fence;
3159	std::vector<deUint32>			levelDataSizes;
3160
3161	// Calculate buffer size
3162	bufferSize = arraySize * textureSize;
3163
3164	// Create source buffer
3165	{
3166		const VkBufferCreateInfo bufferParams =
3167		{
3168			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
3169			DE_NULL,									// const void*			pNext;
3170			0u,											// VkBufferCreateFlags	flags;
3171			bufferSize,									// VkDeviceSize			size;
3172			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
3173			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
3174			0u,											// deUint32				queueFamilyIndexCount;
3175			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
3176		};
3177
3178		buffer		= createBuffer(vk, vkDevice, &bufferParams);
3179		bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
3180		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
3181	}
3182
3183	// Create command pool and buffer
3184	{
3185		const VkCommandPoolCreateInfo cmdPoolParams =
3186		{
3187			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType			sType;
3188			DE_NULL,										// const void*				pNext;
3189			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCommandPoolCreateFlags	flags;
3190			queueFamilyIndex,								// deUint32					queueFamilyIndex;
3191		};
3192
3193		cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
3194
3195		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
3196		{
3197			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
3198			DE_NULL,										// const void*				pNext;
3199			*cmdPool,										// VkCommandPool			commandPool;
3200			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
3201			1u,												// deUint32					bufferCount;
3202		};
3203
3204		cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
3205	}
3206
3207	// Create fence
3208	{
3209		const VkFenceCreateInfo fenceParams =
3210		{
3211			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,		// VkStructureType		sType;
3212			DE_NULL,									// const void*			pNext;
3213			0u											// VkFenceCreateFlags	flags;
3214		};
3215
3216		fence = createFence(vk, vkDevice, &fenceParams);
3217	}
3218
3219	// Barriers for copying buffer to image
3220	const VkBufferMemoryBarrier preBufferBarrier =
3221	{
3222		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
3223		DE_NULL,									// const void*		pNext;
3224		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
3225		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
3226		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
3227		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
3228		*buffer,									// VkBuffer			buffer;
3229		0u,											// VkDeviceSize		offset;
3230		bufferSize									// VkDeviceSize		size;
3231	};
3232
3233	const VkImageMemoryBarrier preImageBarrier =
3234	{
3235		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3236		DE_NULL,										// const void*				pNext;
3237		0u,												// VkAccessFlags			srcAccessMask;
3238		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
3239		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
3240		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
3241		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3242		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3243		destImage,										// VkImage					image;
3244		{												// VkImageSubresourceRange	subresourceRange;
3245			aspectMask,								// VkImageAspect	aspect;
3246			0u,										// deUint32			baseMipLevel;
3247			1u,										// deUint32			mipLevels;
3248			0u,										// deUint32			baseArraySlice;
3249			arraySize								// deUint32			arraySize;
3250		}
3251	};
3252
3253	const VkImageMemoryBarrier postImageBarrier =
3254	{
3255		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3256		DE_NULL,										// const void*				pNext;
3257		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
3258		VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask;
3259		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
3260		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// VkImageLayout			newLayout;
3261		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3262		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3263		destImage,										// VkImage					image;
3264		{												// VkImageSubresourceRange	subresourceRange;
3265			aspectMask,								// VkImageAspect	aspect;
3266			0u,										// deUint32			baseMipLevel;
3267			1u,										// deUint32			mipLevels;
3268			0u,										// deUint32			baseArraySlice;
3269			arraySize								// deUint32			arraySize;
3270		}
3271	};
3272
3273	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
3274	{
3275		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
3276		DE_NULL,										// const void*						pNext;
3277		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags		flags;
3278		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3279	};
3280
3281	std::vector<VkBufferImageCopy>		copyRegions;
3282
3283	{
3284		deUint32 layerDataOffset = 0;
3285
3286		for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx)
3287		{
3288			const VkBufferImageCopy layerRegion =
3289			{
3290				layerDataOffset,						// VkDeviceSize				bufferOffset;
3291				(deUint32)texSize.x(),					// deUint32					bufferRowLength;
3292				(deUint32)texSize.y(),					// deUint32					bufferImageHeight;
3293				{										// VkImageSubresourceLayers	imageSubresource;
3294					aspectMask,
3295					0u,
3296					(deUint32)layerNdx,
3297					1u
3298				},
3299				{ 0u, 0u, 0u },							// VkOffset3D			imageOffset;
3300				{										// VkExtent3D			imageExtent;
3301					(deUint32)texSize.x(),
3302					(deUint32)texSize.y(),
3303					(deUint32)texSize.z()
3304				}
3305			};
3306
3307			copyRegions.push_back(layerRegion);
3308			layerDataOffset += textureSize;
3309		}
3310	}
3311
3312	// Write buffer data
3313	{
3314		deUint8*	destPtr				= (deUint8*)bufferAlloc->getHostPtr();
3315		deUint32	levelOffset			= 0;
3316
3317		for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx)
3318		{
3319			tcu::ConstPixelBufferAccess		access		(texFormat, texSize, data);
3320			tcu::PixelBufferAccess			destAccess	(texFormat, texSize, destPtr + levelOffset);
3321
3322			tcu::copy(destAccess, access);
3323			levelOffset += textureSize;
3324		}
3325	}
3326
3327	flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
3328
3329	// Copy buffer to image
3330	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
3331	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
3332	vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
3333	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
3334	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
3335
3336	const VkSubmitInfo submitInfo =
3337	{
3338		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
3339		DE_NULL,						// const void*				pNext;
3340		0u,								// deUint32					waitSemaphoreCount;
3341		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
3342		DE_NULL,
3343		1u,								// deUint32					commandBufferCount;
3344		&cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
3345		0u,								// deUint32					signalSemaphoreCount;
3346		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
3347	};
3348
3349	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
3350	VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
3351}
3352
3353de::MovePtr<ShaderExecutor::SamplerUniform> ShaderExecutor::createSamplerUniform (const VkDevice&				vkDevice,
3354																				  const DeviceInterface&		vk,
3355																				  const VkQueue					queue,
3356																				  const deUint32				queueFamilyIndex,
3357																				  Allocator&					memAlloc,
3358																				  deUint32						bindingLocation,
3359																				  const tcu::Sampler&			refSampler,
3360																				  const tcu::TextureFormat&		texFormat,
3361																				  const tcu::IVec3&				texSize,
3362																				  VkImageType					imageType,
3363																				  VkImageViewType				imageViewType,
3364																				  const void*					data)
3365{
3366	const VkFormat					format			= mapTextureFormat(texFormat);
3367	const bool						isCube			= imageViewType == VK_IMAGE_VIEW_TYPE_CUBE;
3368	const bool						isShadowSampler	= texFormat == tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
3369	const VkImageCreateFlags		imageFlags		= isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
3370	const deUint32					arraySize		= isCube ? 6u : 1u;
3371	const VkImageAspectFlags		aspectMask		= isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
3372	VkImageUsageFlags				imageUsage		= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3373	Move<VkImage>					vkTexture;
3374	de::MovePtr<Allocation>			allocation;
3375
3376	if (isShadowSampler)
3377		imageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3378
3379	// Create image
3380	const VkImageCreateInfo	imageParams =
3381	{
3382		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
3383		DE_NULL,														// const void*				pNext;
3384		imageFlags,														// VkImageCreateFlags		flags;
3385		imageType,														// VkImageType				imageType;
3386		format,															// VkFormat					format;
3387		{																// VkExtent3D				extent;
3388			(deUint32)texSize.x(),
3389			(deUint32)texSize.y(),
3390			(deUint32)texSize.z()
3391		},
3392		1u,																// deUint32					mipLevels;
3393		arraySize,														// deUint32					arrayLayers;
3394		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits	samples;
3395		VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling;
3396		imageUsage,														// VkImageUsageFlags		usage;
3397		VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharingMode;
3398		1u,																// deUint32					queueFamilyIndexCount;
3399		&queueFamilyIndex,												// const deUint32*			pQueueFamilyIndices;
3400		VK_IMAGE_LAYOUT_UNDEFINED										// VkImageLayout			initialLayout;
3401	};
3402
3403	vkTexture		= createImage(vk, vkDevice, &imageParams);
3404	allocation		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
3405	VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
3406
3407	// Upload texture data
3408	uploadImage(vkDevice, vk, queue, queueFamilyIndex, memAlloc, texFormat, texSize, data, arraySize, aspectMask, *vkTexture);
3409
3410	// Create sampler
3411	const VkSamplerCreateInfo		samplerParams	= mapSampler(refSampler, texFormat);
3412	Move<VkSampler>					sampler			= createSampler(vk, vkDevice, &samplerParams);
3413
3414	const VkImageViewCreateInfo		viewParams		=
3415	{
3416		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
3417		NULL,										// const voide*				pNexŧ;
3418		0u,											// VkImageViewCreateFlags	flags;
3419		*vkTexture,									// VkImage					image;
3420		imageViewType,								// VkImageViewType			viewType;
3421		format,										// VkFormat					format;
3422		{
3423			VK_COMPONENT_SWIZZLE_R,						// VkComponentSwizzle		r;
3424			VK_COMPONENT_SWIZZLE_G,						// VkComponentSwizzle		g;
3425			VK_COMPONENT_SWIZZLE_B,						// VkComponentSwizzle		b;
3426			VK_COMPONENT_SWIZZLE_A						// VkComponentSwizzle		a;
3427		},											// VkComponentMapping			components;
3428		{
3429			aspectMask,									// VkImageAspectFlags	aspectMask;
3430			0,											// deUint32				baseMipLevel;
3431			1,											// deUint32				mipLevels;
3432			0,											// deUint32				baseArraySlice;
3433			arraySize									// deUint32				arraySize;
3434		}											// VkImageSubresourceRange	subresourceRange;
3435	};
3436
3437	Move<VkImageView>				imageView		= createImageView(vk, vkDevice, &viewParams);
3438
3439	const VkDescriptorImageInfo descriptor			=
3440	{
3441		sampler.get(),								// VkSampler				sampler;
3442		imageView.get(),							// VkImageView				imageView;
3443		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout			imageLayout;
3444	};
3445
3446	de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
3447	uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3448	uniform->descriptor = descriptor;
3449	uniform->location = bindingLocation;
3450	uniform->image = VkImageSp(new Unique<VkImage>(vkTexture));
3451	uniform->imageView = VkImageViewSp(new Unique<VkImageView>(imageView));
3452	uniform->sampler = VkSamplerSp(new Unique<VkSampler>(sampler));
3453	uniform->alloc = AllocationSp(allocation.release());
3454
3455	return uniform;
3456}
3457
3458SamplerUniformData::SamplerUniformData (deUint32						bindingLocation,
3459										deUint32						numSamplers,
3460										const tcu::Sampler&				refSampler,
3461										const tcu::TextureFormat&		texFormat,
3462										const tcu::IVec3&				texSize,
3463										VkImageType						imageType,
3464										VkImageViewType					imageViewType,
3465										const void*						data)
3466	: UniformDataBase		(bindingLocation)
3467	, m_numSamplers			(numSamplers)
3468	, m_refSampler			(refSampler)
3469	, m_texFormat			(texFormat)
3470	, m_texSize				(texSize)
3471	, m_imageType			(imageType)
3472	, m_imageViewType		(imageViewType)
3473	, m_data				(data)
3474{
3475}
3476
3477SamplerUniformData::~SamplerUniformData (void)
3478{
3479}
3480
3481void SamplerUniformData::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
3482{
3483	executor.setupSamplerData(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_numSamplers, m_refSampler, m_texFormat, m_texSize, m_imageType, m_imageViewType, m_data);
3484}
3485
3486} // shaderexecutor
3487} // vkt
3488