Home | History | Annotate | Download | only in shaderexecutor
      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 
     70 static VkClearValue	getDefaultClearColor (void)
     71 {
     72 	return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);
     73 }
     74 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    505 FragmentOutExecutor::FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
    506 	: ShaderExecutor	(shaderSpec, shaderType)
    507 	, m_outputLayout	(computeFragmentOutputLayout(m_shaderSpec.outputs))
    508 {
    509 }
    510 
    511 FragmentOutExecutor::~FragmentOutExecutor (void)
    512 {
    513 }
    514 
    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 
    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 
    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 
    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 
    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 
    685 void FragmentOutExecutor::clearRenderData (void)
    686 {
    687 	m_vertexBindingDescriptions.clear();
    688 	m_vertexAttributeDescriptions.clear();
    689 	m_vertexBuffers.clear();
    690 	m_vertexBufferAllocs.clear();
    691 }
    692 
    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 
   1452 	virtual void				log						(tcu::TestLog& dst) const { /* TODO */ (void)dst;}
   1453 
   1454 	virtual void				setShaderSources		(SourceCollections& programCollection) const;
   1455 
   1456 };
   1457 
   1458 VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   1459 	: FragmentOutExecutor		(shaderSpec, shaderType)
   1460 {
   1461 }
   1462 
   1463 VertexShaderExecutor::~VertexShaderExecutor (void)
   1464 {
   1465 }
   1466 
   1467 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 
   1482 	virtual void				log						(tcu::TestLog& dst) const	{ /* TODO */ (void)dst; }
   1483 
   1484 	virtual void				setShaderSources		(SourceCollections& programCollection) const;
   1485 
   1486 };
   1487 
   1488 GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   1489 	: FragmentOutExecutor		(shaderSpec, shaderType)
   1490 {
   1491 }
   1492 
   1493 GeometryShaderExecutor::~GeometryShaderExecutor (void)
   1494 {
   1495 }
   1496 
   1497 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 
   1516 	virtual void				log						(tcu::TestLog& dst) const { /* TODO */ (void)dst; }
   1517 
   1518 	virtual void				setShaderSources		(SourceCollections& programCollection) const;
   1519 
   1520 };
   1521 
   1522 FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   1523 	: FragmentOutExecutor		(shaderSpec, shaderType)
   1524 {
   1525 }
   1526 
   1527 FragmentShaderExecutor::~FragmentShaderExecutor (void)
   1528 {
   1529 }
   1530 
   1531 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 
   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 
   1560 	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);
   1570 	VkBuffer				getInputBuffer		(void) const		{ return *m_inputBuffer;					}
   1571 	VkBuffer				getOutputBuffer		(void) const		{ return *m_outputBuffer;					}
   1572 	deUint32				getInputStride		(void) const		{ return getLayoutStride(m_inputLayout);	}
   1573 	deUint32				getOutputStride		(void) const		{ return getLayoutStride(m_outputLayout);	}
   1574 
   1575 	void					uploadInputBuffer	(const Context& ctx, const void* const* inputPtrs, int numValues);
   1576 	void					readOutputBuffer	(const Context& ctx, void* const* outputPtrs, int numValues);
   1577 
   1578 	static void				declareBufferBlocks	(std::ostream& src, const ShaderSpec& spec);
   1579 	static void				generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
   1580 
   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 
   1592 		VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
   1593 	};
   1594 
   1595 	static void				computeVarLayout	(const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
   1596 	static deUint32			getLayoutStride		(const vector<VarLayout>& layout);
   1597 
   1598 	static void				copyToBuffer		(const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
   1599 	static void				copyFromBuffer		(const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
   1600 
   1601 	de::MovePtr<Allocation>	m_inputAlloc;
   1602 	de::MovePtr<Allocation>	m_outputAlloc;
   1603 
   1604 	vector<VarLayout>		m_inputLayout;
   1605 	vector<VarLayout>		m_outputLayout;
   1606 };
   1607 
   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 
   1615 BufferIoExecutor::~BufferIoExecutor (void)
   1616 {
   1617 }
   1618 
   1619 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
   1620 {
   1621 	return layout.empty() ? 0 : layout[0].stride;
   1622 }
   1623 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1901 ComputeShaderExecutor::ComputeShaderExecutor	(const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   1902 	: BufferIoExecutor	(shaderSpec, shaderType)
   1903 {
   1904 }
   1905 
   1906 ComputeShaderExecutor::~ComputeShaderExecutor	(void)
   1907 {
   1908 }
   1909 
   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 
   1935 void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const
   1936 {
   1937 	programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec));
   1938 }
   1939 
   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 
   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 
   2177 TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   2178 	: BufferIoExecutor	(shaderSpec, shaderType)
   2179 {
   2180 }
   2181 
   2182 TessellationExecutor::~TessellationExecutor (void)
   2183 {
   2184 }
   2185 
   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 
   2726 TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   2727 	: TessellationExecutor (shaderSpec, shaderType)
   2728 {
   2729 }
   2730 
   2731 TessControlExecutor::~TessControlExecutor (void)
   2732 {
   2733 }
   2734 
   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 
   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 
   2782 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 
   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 
   2823 TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   2824 	: TessellationExecutor (shaderSpec, shaderType)
   2825 {
   2826 }
   2827 
   2828 TessEvaluationExecutor::~TessEvaluationExecutor (void)
   2829 {
   2830 }
   2831 
   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 
   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 
   2881 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 
   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 
   2912 ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
   2913 	: m_shaderSpec	(shaderSpec)
   2914 	, m_shaderType	(shaderType)
   2915 {
   2916 }
   2917 
   2918 ShaderExecutor::~ShaderExecutor (void)
   2919 {
   2920 }
   2921 
   2922 // Utilities
   2923 
   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 
   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 
   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 
   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 
   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 
   3068 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 
   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 
   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 
   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 
   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 
   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 
   3477 SamplerUniformData::~SamplerUniformData (void)
   3478 {
   3479 }
   3480 
   3481 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