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 
52 using std::vector;
53 using namespace vk;
54 
55 namespace vkt
56 {
57 namespace shaderexecutor
58 {
59 namespace
60 {
61 
62 enum
63 {
64 	DEFAULT_RENDER_WIDTH	= 100,
65 	DEFAULT_RENDER_HEIGHT	= 100,
66 };
67 
68 // Shader utilities
69 
getDefaultClearColor(void)70 static VkClearValue	getDefaultClearColor (void)
71 {
72 	return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);
73 }
74 
checkSupported(const Context & ctx,glu::ShaderType shaderType)75 static 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 
generateEmptyFragmentSource()87 static 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 
generatePassthroughVertexShader(const std::vector<Symbol> & inputs,const char * inputPrefix,const char * outputPrefix)101 static 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 
generateVertexShader(const ShaderSpec & shaderSpec,const std::string & inputPrefix,const std::string & outputPrefix)129 static 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 
205 struct 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 
generateFragShaderOutputDecl(std::ostream & src,const ShaderSpec & shaderSpec,bool useIntOutputs,const std::map<std::string,int> & outLocationMap,const std::string & outputPrefix)211 static 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 
generateFragShaderOutAssign(std::ostream & src,const ShaderSpec & shaderSpec,bool useIntOutputs,const std::string & valuePrefix,const std::string & outputPrefix)260 static 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 
generatePassthroughFragmentShader(const ShaderSpec & shaderSpec,bool useIntOutputs,const std::map<std::string,int> & outLocationMap,const std::string & inputPrefix,const std::string & outputPrefix)288 static 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 
generateGeometryShader(const ShaderSpec & shaderSpec,const std::string & inputPrefix,const std::string & outputPrefix)323 static 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 
generateFragmentShader(const ShaderSpec & shaderSpec,bool useIntOutputs,const std::map<std::string,int> & outLocationMap,const std::string & inputPrefix,const std::string & outputPrefix)404 static 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 
445 class FragmentOutExecutor : public ShaderExecutor
446 {
447 public:
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 
456 protected:
457 	const FragmentOutputLayout							m_outputLayout;
458 private:
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 
computeFragmentOutputLayout(const std::vector<Symbol> & symbols)485 static 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 
FragmentOutExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)505 FragmentOutExecutor::FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
506 	: ShaderExecutor	(shaderSpec, shaderType)
507 	, m_outputLayout	(computeFragmentOutputLayout(m_shaderSpec.outputs))
508 {
509 }
510 
~FragmentOutExecutor(void)511 FragmentOutExecutor::~FragmentOutExecutor (void)
512 {
513 }
514 
computeVertexPositions(int numValues,const tcu::IVec2 & renderSize)515 static 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 
getRenderbufferFormatForOutput(const glu::VarType & outputType,bool useIntOutputs)531 static 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 
getAttributeFormat(const glu::DataType dataType)560 static 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 
addAttribute(const Context & ctx,Allocator & memAlloc,deUint32 bindingLocation,VkFormat format,deUint32 sizePerElement,deUint32 count,const void * dataPtr)594 void 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 
bindAttributes(const Context & ctx,Allocator & memAlloc,int numValues,const void * const * inputs)647 void 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 
clearRenderData(void)685 void FragmentOutExecutor::clearRenderData (void)
686 {
687 	m_vertexBindingDescriptions.clear();
688 	m_vertexAttributeDescriptions.clear();
689 	m_vertexBuffers.clear();
690 	m_vertexBufferAllocs.clear();
691 }
692 
execute(const Context & ctx,int numValues,const void * const * inputs,void * const * outputs)693 void 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 
1446 class VertexShaderExecutor : public FragmentOutExecutor
1447 {
1448 public:
1449 								VertexShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1450 	virtual						~VertexShaderExecutor	(void);
1451 
log(tcu::TestLog & dst) const1452 	virtual void				log						(tcu::TestLog& dst) const { /* TODO */ (void)dst;}
1453 
1454 	virtual void				setShaderSources		(SourceCollections& programCollection) const;
1455 
1456 };
1457 
VertexShaderExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)1458 VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1459 	: FragmentOutExecutor		(shaderSpec, shaderType)
1460 {
1461 }
1462 
~VertexShaderExecutor(void)1463 VertexShaderExecutor::~VertexShaderExecutor (void)
1464 {
1465 }
1466 
setShaderSources(SourceCollections & programCollection) const1467 void 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 
1476 class GeometryShaderExecutor : public FragmentOutExecutor
1477 {
1478 public:
1479 								GeometryShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1480 	virtual						~GeometryShaderExecutor	(void);
1481 
log(tcu::TestLog & dst) const1482 	virtual void				log						(tcu::TestLog& dst) const	{ /* TODO */ (void)dst; }
1483 
1484 	virtual void				setShaderSources		(SourceCollections& programCollection) const;
1485 
1486 };
1487 
GeometryShaderExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)1488 GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1489 	: FragmentOutExecutor		(shaderSpec, shaderType)
1490 {
1491 }
1492 
~GeometryShaderExecutor(void)1493 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1494 {
1495 }
1496 
setShaderSources(SourceCollections & programCollection) const1497 void 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 
1510 class FragmentShaderExecutor : public FragmentOutExecutor
1511 {
1512 public:
1513 								FragmentShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1514 	virtual						~FragmentShaderExecutor (void);
1515 
log(tcu::TestLog & dst) const1516 	virtual void				log						(tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1517 
1518 	virtual void				setShaderSources		(SourceCollections& programCollection) const;
1519 
1520 };
1521 
FragmentShaderExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)1522 FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1523 	: FragmentOutExecutor		(shaderSpec, shaderType)
1524 {
1525 }
1526 
~FragmentShaderExecutor(void)1527 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1528 {
1529 }
1530 
setShaderSources(SourceCollections & programCollection) const1531 void 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 
getVecStd430ByteAlignment(glu::DataType type)1540 static 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 
1554 class BufferIoExecutor : public ShaderExecutor
1555 {
1556 public:
1557 							BufferIoExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1558 	virtual					~BufferIoExecutor	(void);
1559 
log(tcu::TestLog & dst) const1560 	virtual void			log					(tcu::TestLog& dst) const	{ /* TODO */ (void)dst; }
1561 
1562 protected:
1563 	enum
1564 	{
1565 		INPUT_BUFFER_BINDING	= 0,
1566 		OUTPUT_BUFFER_BINDING	= 1,
1567 	};
1568 
1569 	void					initBuffers			(const Context& ctx, int numValues);
getInputBuffer(void) const1570 	VkBuffer				getInputBuffer		(void) const		{ return *m_inputBuffer;					}
getOutputBuffer(void) const1571 	VkBuffer				getOutputBuffer		(void) const		{ return *m_outputBuffer;					}
getInputStride(void) const1572 	deUint32				getInputStride		(void) const		{ return getLayoutStride(m_inputLayout);	}
getOutputStride(void) const1573 	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 
1581 protected:
1582 	Move<VkBuffer>			m_inputBuffer;
1583 	Move<VkBuffer>			m_outputBuffer;
1584 
1585 private:
1586 	struct VarLayout
1587 	{
1588 		deUint32		offset;
1589 		deUint32		stride;
1590 		deUint32		matrixStride;
1591 
VarLayoutvkt::shaderexecutor::__anon9d58b36f0111::BufferIoExecutor::VarLayout1592 		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 
BufferIoExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)1608 BufferIoExecutor::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 
~BufferIoExecutor(void)1615 BufferIoExecutor::~BufferIoExecutor (void)
1616 {
1617 }
1618 
getLayoutStride(const vector<VarLayout> & layout)1619 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1620 {
1621 	return layout.empty() ? 0 : layout[0].stride;
1622 }
1623 
computeVarLayout(const std::vector<Symbol> & symbols,std::vector<VarLayout> * layout)1624 void 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 
declareBufferBlocks(std::ostream & src,const ShaderSpec & spec)1678 void 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 
generateExecBufferIo(std::ostream & src,const ShaderSpec & spec,const char * invocationNdxName)1714 void 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 
copyToBuffer(const glu::VarType & varType,const VarLayout & layout,int numValues,const void * srcBasePtr,void * dstBasePtr)1737 void 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 
copyFromBuffer(const glu::VarType & varType,const VarLayout & layout,int numValues,const void * srcBasePtr,void * dstBasePtr)1764 void 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 
uploadInputBuffer(const Context & ctx,const void * const * inputPtrs,int numValues)1791 void 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 
readOutputBuffer(const Context & ctx,void * const * outputPtrs,int numValues)1814 void 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 
initBuffers(const Context & ctx,int numValues)1836 void 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 
1887 class ComputeShaderExecutor : public BufferIoExecutor
1888 {
1889 public:
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 
1897 protected:
1898 	static std::string	generateComputeShader	(const ShaderSpec& spec);
1899 };
1900 
ComputeShaderExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)1901 ComputeShaderExecutor::ComputeShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1902 	: BufferIoExecutor	(shaderSpec, shaderType)
1903 {
1904 }
1905 
~ComputeShaderExecutor(void)1906 ComputeShaderExecutor::~ComputeShaderExecutor	(void)
1907 {
1908 }
1909 
generateComputeShader(const ShaderSpec & spec)1910 std::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 
setShaderSources(SourceCollections & programCollection) const1935 void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1936 {
1937 	programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec));
1938 }
1939 
execute(const Context & ctx,int numValues,const void * const * inputs,void * const * outputs)1940 void 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 
generateVertexShaderForTess(void)2157 static 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 
2168 class TessellationExecutor : public BufferIoExecutor
2169 {
2170 public:
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 
TessellationExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)2177 TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2178 	: BufferIoExecutor	(shaderSpec, shaderType)
2179 {
2180 }
2181 
~TessellationExecutor(void)2182 TessellationExecutor::~TessellationExecutor (void)
2183 {
2184 }
2185 
renderTess(const Context & ctx,deUint32 numValues,deUint32 vertexCount,deUint32 patchControlPoints)2186 void 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 
2712 class TessControlExecutor : public TessellationExecutor
2713 {
2714 public:
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 
2722 protected:
2723 	static std::string	generateTessControlShader	(const ShaderSpec& shaderSpec);
2724 };
2725 
TessControlExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)2726 TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2727 	: TessellationExecutor (shaderSpec, shaderType)
2728 {
2729 }
2730 
~TessControlExecutor(void)2731 TessControlExecutor::~TessControlExecutor (void)
2732 {
2733 }
2734 
generateTessControlShader(const ShaderSpec & shaderSpec)2735 std::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 
generateEmptyTessEvalShader()2766 static 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 
setShaderSources(SourceCollections & programCollection) const2782 void 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 
execute(const Context & ctx,int numValues,const void * const * inputs,void * const * outputs)2790 void 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 
2809 class TessEvaluationExecutor : public TessellationExecutor
2810 {
2811 public:
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 
2819 protected:
2820 	static std::string	generateTessEvalShader	(const ShaderSpec& shaderSpec);
2821 };
2822 
TessEvaluationExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)2823 TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2824 	: TessellationExecutor (shaderSpec, shaderType)
2825 {
2826 }
2827 
~TessEvaluationExecutor(void)2828 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2829 {
2830 }
2831 
generatePassthroughTessControlShader(void)2832 static 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 
generateTessEvalShader(const ShaderSpec & shaderSpec)2854 std::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 
setShaderSources(SourceCollections & programCollection) const2881 void 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 
execute(const Context & ctx,int numValues,const void * const * inputs,void * const * outputs)2889 void 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 
ShaderExecutor(const ShaderSpec & shaderSpec,glu::ShaderType shaderType)2912 ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2913 	: m_shaderSpec	(shaderSpec)
2914 	, m_shaderType	(shaderType)
2915 {
2916 }
2917 
~ShaderExecutor(void)2918 ShaderExecutor::~ShaderExecutor (void)
2919 {
2920 }
2921 
2922 // Utilities
2923 
createExecutor(glu::ShaderType shaderType,const ShaderSpec & shaderSpec)2924 ShaderExecutor* 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 
createBufferUniform(const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue,const deUint32 queueFamilyIndex,Allocator & memAlloc,deUint32 bindingLocation,VkDescriptorType descriptorType,deUint32 size,const void * dataPtr)2939 de::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 
setupUniformData(const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue queue,const deUint32 queueFamilyIndex,Allocator & memAlloc,deUint32 bindingLocation,VkDescriptorType descriptorType,deUint32 size,const void * dataPtr)2982 void 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 
setupUniformArray(const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue queue,const deUint32 queueFamilyIndex,Allocator & memAlloc,deUint32 bindingLocation,VkDescriptorType descriptorType,deUint32 arraySize,deUint32 size,const void * dataPtr)3000 void 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 
setupSamplerData(const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue queue,const deUint32 queueFamilyIndex,Allocator & memAlloc,deUint32 bindingLocation,deUint32 numSamplers,const tcu::Sampler & refSampler,const tcu::TextureFormat & texFormat,const tcu::IVec3 & texSize,VkImageType imageType,VkImageViewType imageViewType,const void * data)3032 void 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 
getBufferPtr(const deUint32 bindingLocation) const3068 const 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 
addUniforms(const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue queue,const deUint32 queueFamilyIndex,Allocator & memAlloc)3084 void 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 
uploadUniforms(DescriptorSetUpdateBuilder & descriptorSetUpdateBuilder,VkDescriptorSet descriptorSet)3096 void 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 
uploadImage(const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue queue,const deUint32 queueFamilyIndex,Allocator & memAlloc,const tcu::TextureFormat & texFormat,const tcu::IVec3 & texSize,const void * data,const deUint32 arraySize,const VkImageAspectFlags aspectMask,VkImage destImage)3140 void 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 
createSamplerUniform(const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue queue,const deUint32 queueFamilyIndex,Allocator & memAlloc,deUint32 bindingLocation,const tcu::Sampler & refSampler,const tcu::TextureFormat & texFormat,const tcu::IVec3 & texSize,VkImageType imageType,VkImageViewType imageViewType,const void * data)3353 de::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 
SamplerUniformData(deUint32 bindingLocation,deUint32 numSamplers,const tcu::Sampler & refSampler,const tcu::TextureFormat & texFormat,const tcu::IVec3 & texSize,VkImageType imageType,VkImageViewType imageViewType,const void * data)3458 SamplerUniformData::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 
~SamplerUniformData(void)3477 SamplerUniformData::~SamplerUniformData (void)
3478 {
3479 }
3480 
setup(ShaderExecutor & executor,const VkDevice & vkDevice,const DeviceInterface & vk,const VkQueue queue,const deUint32 queueFamilyIndex,Allocator & memAlloc) const3481 void 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