Home | History | Annotate | Download | only in texture
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2016 The Khronos Group Inc.
      6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
      7  * Copyright (c) 2014 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 Texture test utilities.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "vktTextureTestUtil.hpp"
     27 
     28 #include "deFilePath.hpp"
     29 #include "deMath.h"
     30 #include "tcuCompressedTexture.hpp"
     31 #include "tcuImageIO.hpp"
     32 #include "tcuStringTemplate.hpp"
     33 #include "tcuTestLog.hpp"
     34 #include "vkBuilderUtil.hpp"
     35 #include "vkImageUtil.hpp"
     36 #include "vkPrograms.hpp"
     37 #include "vkQueryUtil.hpp"
     38 #include "vkRefUtil.hpp"
     39 #include "vkTypeUtil.hpp"
     40 #include <map>
     41 #include <string>
     42 #include <vector>
     43 
     44 using tcu::TestLog;
     45 
     46 using namespace vk;
     47 using namespace glu::TextureTestUtil;
     48 
     49 namespace vkt
     50 {
     51 namespace texture
     52 {
     53 namespace util
     54 {
     55 
     56 struct ShaderParameters {
     57 	float		bias;				//!< User-supplied bias.
     58 	float		ref;				//!< Reference value for shadow lookups.
     59 	tcu::Vec2	padding;			//!< Shader uniform padding.
     60 	tcu::Vec4	colorScale;			//!< Scale for texture color values.
     61 	tcu::Vec4	colorBias;			//!< Bias for texture color values.
     62 };
     63 
     64 const char* getProgramName(Program program)
     65 {
     66 	switch (program)
     67 	{
     68 		case PROGRAM_2D_FLOAT:			return "2D_FLOAT";
     69 		case PROGRAM_2D_INT:			return "2D_INT";
     70 		case PROGRAM_2D_UINT:			return "2D_UINT";
     71 		case PROGRAM_2D_SHADOW:			return "2D_SHADOW";
     72 		case PROGRAM_2D_FLOAT_BIAS:		return "2D_FLOAT_BIAS";
     73 		case PROGRAM_2D_INT_BIAS:		return "2D_INT_BIAS";
     74 		case PROGRAM_2D_UINT_BIAS:		return "2D_UINT_BIAS";
     75 		case PROGRAM_2D_SHADOW_BIAS:	return "2D_SHADOW_BIAS";
     76 		case PROGRAM_1D_FLOAT:			return "1D_FLOAT";
     77 		case PROGRAM_1D_INT:			return "1D_INT";
     78 		case PROGRAM_1D_UINT:			return "1D_UINT";
     79 		case PROGRAM_1D_SHADOW:			return "1D_SHADOW";
     80 		case PROGRAM_1D_FLOAT_BIAS:		return "1D_FLOAT_BIAS";
     81 		case PROGRAM_1D_INT_BIAS:		return "1D_INT_BIAS";
     82 		case PROGRAM_1D_UINT_BIAS:		return "1D_UINT_BIAS";
     83 		case PROGRAM_1D_SHADOW_BIAS:	return "1D_SHADOW_BIAS";
     84 		case PROGRAM_CUBE_FLOAT:		return "CUBE_FLOAT";
     85 		case PROGRAM_CUBE_INT:			return "CUBE_INT";
     86 		case PROGRAM_CUBE_UINT:			return "CUBE_UINT";
     87 		case PROGRAM_CUBE_SHADOW:		return "CUBE_SHADOW";
     88 		case PROGRAM_CUBE_FLOAT_BIAS:	return "CUBE_FLOAT_BIAS";
     89 		case PROGRAM_CUBE_INT_BIAS:		return "CUBE_INT_BIAS";
     90 		case PROGRAM_CUBE_UINT_BIAS:	return "CUBE_UINT_BIAS";
     91 		case PROGRAM_CUBE_SHADOW_BIAS:	return "CUBE_SHADOW_BIAS";
     92 		case PROGRAM_2D_ARRAY_FLOAT:	return "2D_ARRAY_FLOAT";
     93 		case PROGRAM_2D_ARRAY_INT:		return "2D_ARRAY_INT";
     94 		case PROGRAM_2D_ARRAY_UINT:		return "2D_ARRAY_UINT";
     95 		case PROGRAM_2D_ARRAY_SHADOW:	return "2D_ARRAY_SHADOW";
     96 		case PROGRAM_3D_FLOAT:			return "3D_FLOAT";
     97 		case PROGRAM_3D_INT:			return "3D_INT";
     98 		case PROGRAM_3D_UINT:			return "3D_UINT";
     99 		case PROGRAM_3D_FLOAT_BIAS:		return "3D_FLOAT_BIAS";
    100 		case PROGRAM_3D_INT_BIAS:		return "3D_INT_BIAS";
    101 		case PROGRAM_3D_UINT_BIAS:		return "3D_UINT_BIAS";
    102 		case PROGRAM_CUBE_ARRAY_FLOAT:	return "CUBE_ARRAY_FLOAT";
    103 		case PROGRAM_CUBE_ARRAY_INT:	return "CUBE_ARRAY_INT";
    104 		case PROGRAM_CUBE_ARRAY_UINT:	return "CUBE_ARRAY_UINT";
    105 		case PROGRAM_CUBE_ARRAY_SHADOW:	return "CUBE_ARRAY_SHADOW";
    106 		case PROGRAM_1D_ARRAY_FLOAT:	return "1D_ARRAY_FLOAT";
    107 		case PROGRAM_1D_ARRAY_INT:		return "1D_ARRAY_INT";
    108 		case PROGRAM_1D_ARRAY_UINT:		return "1D_ARRAY_UINT";
    109 		case PROGRAM_1D_ARRAY_SHADOW:	return "1D_ARRAY_SHADOW";
    110 		case PROGRAM_BUFFER_FLOAT:		return "BUFFER_FLOAT";
    111 		case PROGRAM_BUFFER_INT:		return "BUFFER_INT";
    112 		case PROGRAM_BUFFER_UINT:		return "BUFFER_UINT";
    113 		default:
    114 			DE_ASSERT(false);
    115 	}
    116 	return NULL;
    117 }
    118 
    119 VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
    120 {
    121 	switch (type)
    122 	{
    123 		case TextureBinding::TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
    124 		case TextureBinding::TYPE_2D_ARRAY:		return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    125 		case TextureBinding::TYPE_CUBE_MAP:		return VK_IMAGE_VIEW_TYPE_CUBE;
    126 		case TextureBinding::TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
    127 		default:
    128 			DE_ASSERT(false);
    129 	}
    130 
    131 	return VK_IMAGE_VIEW_TYPE_2D;
    132 }
    133 
    134 VkImageType imageViewTypeToImageType (VkImageViewType type)
    135 {
    136 	switch (type)
    137 	{
    138 		case VK_IMAGE_VIEW_TYPE_2D:
    139 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
    140 		case VK_IMAGE_VIEW_TYPE_CUBE:			return VK_IMAGE_TYPE_2D;
    141 		case VK_IMAGE_VIEW_TYPE_3D:				return VK_IMAGE_TYPE_3D;
    142 		default:
    143 			DE_ASSERT(false);
    144 	}
    145 
    146 	return VK_IMAGE_TYPE_2D;
    147 }
    148 
    149 void initializePrograms(vk::SourceCollections& programCollection, glu::Precision texCoordPrecision, const std::vector<Program>& programs)
    150 {
    151 	static const char* vertShaderTemplate =
    152 		"${VTX_HEADER}"
    153 		"layout(location = 0) ${VTX_IN} highp vec4 a_position;\n"
    154 		"layout(location = 1) ${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n"
    155 		"layout(location = 0) ${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
    156 		"${VTX_OUT} gl_PerVertex { vec4 gl_Position; };\n"
    157 		"\n"
    158 		"void main (void)\n"
    159 		"{\n"
    160 		"	gl_Position = a_position;\n"
    161 		"	v_texCoord = a_texCoord;\n"
    162 		"}\n";
    163 
    164 	static const char* fragShaderTemplate =
    165 		"${FRAG_HEADER}"
    166 		"layout(location = 0) ${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
    167 		"layout(location = 0) out mediump vec4 ${FRAG_COLOR};\n"
    168 		"layout (set=0, binding=0, std140) uniform Block \n"
    169 		"{\n"
    170 		"  ${PRECISION} float u_bias;\n"
    171 		"  ${PRECISION} float u_ref;\n"
    172 		"  ${PRECISION} vec4 u_colorScale;\n"
    173 		"  ${PRECISION} vec4 u_colorBias;\n"
    174 		"};\n\n"
    175 		"layout (set=1, binding=0) uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n"
    176 		"void main (void)\n"
    177 		"{\n"
    178 		"	${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n"
    179 		"}\n";
    180 
    181 	tcu::StringTemplate					vertexSource	(vertShaderTemplate);
    182 	tcu::StringTemplate					fragmentSource	(fragShaderTemplate);
    183 
    184 	for (std::vector<Program>::const_iterator programIt = programs.begin(); programIt != programs.end(); ++programIt)
    185 	{
    186 		Program								program	= *programIt;
    187 		std::map<std::string, std::string>	params;
    188 
    189 		bool	isCube		= de::inRange<int>(program, PROGRAM_CUBE_FLOAT, PROGRAM_CUBE_SHADOW_BIAS);
    190 		bool	isArray		= de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW)
    191 								|| de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW);
    192 
    193 		bool	is1D		= de::inRange<int>(program, PROGRAM_1D_FLOAT, PROGRAM_1D_SHADOW_BIAS)
    194 								|| de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW)
    195 								|| de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
    196 
    197 		bool	is2D		= de::inRange<int>(program, PROGRAM_2D_FLOAT, PROGRAM_2D_SHADOW_BIAS)
    198 								|| de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW);
    199 
    200 		bool	is3D		= de::inRange<int>(program, PROGRAM_3D_FLOAT, PROGRAM_3D_UINT_BIAS);
    201 		bool	isCubeArray	= de::inRange<int>(program, PROGRAM_CUBE_ARRAY_FLOAT, PROGRAM_CUBE_ARRAY_SHADOW);
    202 
    203 		const std::string	version	= glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450);
    204 
    205 		params["FRAG_HEADER"]	= version + "\n";
    206 		params["VTX_HEADER"]	= version + "\n";
    207 		params["VTX_IN"]		= "in";
    208 		params["VTX_OUT"]		= "out";
    209 		params["FRAG_IN"]		= "in";
    210 		params["FRAG_COLOR"]	= "dEQP_FragColor";
    211 
    212 		params["PRECISION"]		= glu::getPrecisionName(texCoordPrecision);
    213 
    214 		if (isCubeArray)
    215 			params["TEXCOORD_TYPE"]	= "vec4";
    216 		else if (isCube || (is2D && isArray) || is3D)
    217 			params["TEXCOORD_TYPE"]	= "vec3";
    218 		else if ((is1D && isArray) || is2D)
    219 			params["TEXCOORD_TYPE"]	= "vec2";
    220 		else if (is1D)
    221 			params["TEXCOORD_TYPE"]	= "float";
    222 		else
    223 			DE_ASSERT(DE_FALSE);
    224 
    225 		const char*	sampler	= DE_NULL;
    226 		const char*	lookup	= DE_NULL;
    227 
    228 		switch (program)
    229 		{
    230 			case PROGRAM_2D_FLOAT:			sampler = "sampler2D";				lookup = "texture(u_sampler, v_texCoord)";												break;
    231 			case PROGRAM_2D_INT:			sampler = "isampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    232 			case PROGRAM_2D_UINT:			sampler = "usampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    233 			case PROGRAM_2D_SHADOW:			sampler = "sampler2DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
    234 			case PROGRAM_2D_FLOAT_BIAS:		sampler = "sampler2D";				lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
    235 			case PROGRAM_2D_INT_BIAS:		sampler = "isampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    236 			case PROGRAM_2D_UINT_BIAS:		sampler = "usampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    237 			case PROGRAM_2D_SHADOW_BIAS:	sampler = "sampler2DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";	break;
    238 			case PROGRAM_1D_FLOAT:			sampler = "sampler1D";				lookup = "texture(u_sampler, v_texCoord)";												break;
    239 			case PROGRAM_1D_INT:			sampler = "isampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    240 			case PROGRAM_1D_UINT:			sampler = "usampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    241 			case PROGRAM_1D_SHADOW:			sampler = "sampler1DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref)), 0.0, 0.0, 1.0)";		break;
    242 			case PROGRAM_1D_FLOAT_BIAS:		sampler = "sampler1D";				lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
    243 			case PROGRAM_1D_INT_BIAS:		sampler = "isampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    244 			case PROGRAM_1D_UINT_BIAS:		sampler = "usampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    245 			case PROGRAM_1D_SHADOW_BIAS:	sampler = "sampler1DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref), u_bias), 0.0, 0.0, 1.0)";	break;
    246 			case PROGRAM_CUBE_FLOAT:		sampler = "samplerCube";			lookup = "texture(u_sampler, v_texCoord)";												break;
    247 			case PROGRAM_CUBE_INT:			sampler = "isamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    248 			case PROGRAM_CUBE_UINT:			sampler = "usamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    249 			case PROGRAM_CUBE_SHADOW:		sampler = "samplerCubeShadow";		lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
    250 			case PROGRAM_CUBE_FLOAT_BIAS:	sampler = "samplerCube";			lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
    251 			case PROGRAM_CUBE_INT_BIAS:		sampler = "isamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    252 			case PROGRAM_CUBE_UINT_BIAS:	sampler = "usamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    253 			case PROGRAM_CUBE_SHADOW_BIAS:	sampler = "samplerCubeShadow";		lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";	break;
    254 			case PROGRAM_2D_ARRAY_FLOAT:	sampler = "sampler2DArray";			lookup = "texture(u_sampler, v_texCoord)";												break;
    255 			case PROGRAM_2D_ARRAY_INT:		sampler = "isampler2DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    256 			case PROGRAM_2D_ARRAY_UINT:		sampler = "usampler2DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    257 			case PROGRAM_2D_ARRAY_SHADOW:	sampler = "sampler2DArrayShadow";	lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
    258 			case PROGRAM_3D_FLOAT:			sampler = "sampler3D";				lookup = "texture(u_sampler, v_texCoord)";												break;
    259 			case PROGRAM_3D_INT:			sampler = "isampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    260 			case PROGRAM_3D_UINT:			sampler = "usampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    261 			case PROGRAM_3D_FLOAT_BIAS:		sampler = "sampler3D";				lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
    262 			case PROGRAM_3D_INT_BIAS:		sampler = "isampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    263 			case PROGRAM_3D_UINT_BIAS:		sampler = "usampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
    264 			case PROGRAM_CUBE_ARRAY_FLOAT:	sampler = "samplerCubeArray";		lookup = "texture(u_sampler, v_texCoord)";												break;
    265 			case PROGRAM_CUBE_ARRAY_INT:	sampler = "isamplerCubeArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    266 			case PROGRAM_CUBE_ARRAY_UINT:	sampler = "usamplerCubeArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    267 			case PROGRAM_CUBE_ARRAY_SHADOW:	sampler = "samplerCubeArrayShadow";	lookup = "vec4(texture(u_sampler, v_texCoord, u_ref), 0.0, 0.0, 1.0)";			break;
    268 			case PROGRAM_1D_ARRAY_FLOAT:	sampler = "sampler1DArray";			lookup = "texture(u_sampler, v_texCoord)";												break;
    269 			case PROGRAM_1D_ARRAY_INT:		sampler = "isampler1DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    270 			case PROGRAM_1D_ARRAY_UINT:		sampler = "usampler1DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
    271 			case PROGRAM_1D_ARRAY_SHADOW:	sampler = "sampler1DArrayShadow";	lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
    272 			case PROGRAM_BUFFER_FLOAT:		sampler = "samplerBuffer";			lookup = "texelFetch(u_sampler, int(v_texCoord))";										break;
    273 			case PROGRAM_BUFFER_INT:		sampler = "isamplerBuffer";			lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";								break;
    274 			case PROGRAM_BUFFER_UINT:		sampler = "usamplerBuffer";			lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";								break;
    275 			default:
    276 				DE_ASSERT(false);
    277 		}
    278 
    279 		params["SAMPLER_TYPE"]	= sampler;
    280 		params["LOOKUP"]		= lookup;
    281 
    282 		programCollection.glslSources.add("vertext_" + std::string(getProgramName(program))) << glu::VertexSource(vertexSource.specialize(params));
    283 		programCollection.glslSources.add("fragment_" + std::string(getProgramName(program))) << glu::FragmentSource(fragmentSource.specialize(params));
    284 	}
    285 }
    286 
    287 TextureBinding::TextureBinding (Context& context)
    288 	: m_context			(context)
    289 {
    290 }
    291 
    292 TextureBinding::TextureBinding (Context& context, const TestTextureSp& textureData, const TextureBinding::Type type)
    293 	: m_context			(context)
    294 	, m_type			(type)
    295 	, m_textureData		(textureData)
    296 {
    297 	updateTextureData(m_textureData, m_type);
    298 }
    299 
    300 void TextureBinding::updateTextureData (const TestTextureSp& textureData, const TextureBinding::Type textureType)
    301 {
    302 	const DeviceInterface&						vkd						= m_context.getDeviceInterface();
    303 	const VkDevice								vkDevice				= m_context.getDevice();
    304 	const VkQueue								queue					= m_context.getUniversalQueue();
    305 	const deUint32								queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
    306 	Allocator&									allocator				= m_context.getDefaultAllocator();
    307 
    308 	m_type			= textureType;
    309 	m_textureData	= textureData;
    310 
    311 	const bool									isCube					= m_type == TYPE_CUBE_MAP;
    312 	const VkImageCreateFlags					imageCreateFlags		= isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
    313 	const VkImageViewType						imageViewType			= textureTypeToImageViewType(textureType);
    314 	const VkImageType							imageType				= imageViewTypeToImageType(imageViewType);
    315 	const VkImageTiling							imageTiling				= VK_IMAGE_TILING_OPTIMAL;
    316 	const VkImageUsageFlags						imageUsageFlags			= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    317 	const VkFormat								format					= textureData->isCompressed() ? mapCompressedTextureFormat(textureData->getCompressedLevel(0, 0).getFormat()) : mapTextureFormat(textureData->getTextureFormat());
    318 	const tcu::UVec3							textureDimension		= textureData->getTextureDimension();
    319 	const deUint32								mipLevels				= textureData->getNumLevels();
    320 	const deUint32								arraySize				= textureData->getArraySize();
    321 	vk::VkImageFormatProperties					imageFormatProperties;
    322 	const VkResult								imageFormatQueryResult	= m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties);
    323 
    324 	if (imageFormatQueryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
    325 	{
    326 		TCU_THROW(NotSupportedError, (std::string("Format not supported: ") + vk::getFormatName(format)).c_str());
    327 	}
    328 	else
    329 		VK_CHECK(imageFormatQueryResult);
    330 
    331 	if (imageFormatProperties.maxArrayLayers < arraySize)
    332 		TCU_THROW(NotSupportedError, ("Maximum array layers number for this format is not enough for this test."));
    333 
    334 	if (imageFormatProperties.maxMipLevels < mipLevels)
    335 		TCU_THROW(NotSupportedError, ("Maximum mimap level number for this format is not enough for this test."));
    336 
    337 	if (imageFormatProperties.maxExtent.width < textureDimension.x() ||
    338 		imageFormatProperties.maxExtent.height < textureDimension.y() ||
    339 		imageFormatProperties.maxExtent.depth < textureDimension.z())
    340 	{
    341 		TCU_THROW(NotSupportedError, ("Maximum image dimension for this format is not enough for this test."));
    342 	}
    343 
    344 	// Create image
    345 	const VkImageCreateInfo						imageParams				=
    346 	{
    347 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
    348 		DE_NULL,														// const void*				pNext;
    349 		imageCreateFlags,												// VkImageCreateFlags		flags;
    350 		imageType,														// VkImageType				imageType;
    351 		format,															// VkFormat					format;
    352 		{																// VkExtent3D				extent;
    353 			(deUint32)textureDimension.x(),
    354 			(deUint32)textureDimension.y(),
    355 			(deUint32)textureDimension.z()
    356 		},
    357 		mipLevels,														// deUint32					mipLevels;
    358 		arraySize,														// deUint32					arrayLayers;
    359 		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits	samples;
    360 		imageTiling,													// VkImageTiling			tiling;
    361 		imageUsageFlags,												// VkImageUsageFlags		usage;
    362 		VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharingMode;
    363 		1u,																// deUint32					queueFamilyIndexCount;
    364 		&queueFamilyIndex,												// const deUint32*			pQueueFamilyIndices;
    365 		VK_IMAGE_LAYOUT_UNDEFINED										// VkImageLayout			initialLayout;
    366 	};
    367 
    368 	m_textureImage			= createImage(vkd, vkDevice, &imageParams);
    369 	m_textureImageMemory	= allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_textureImage), MemoryRequirement::Any);
    370 	VK_CHECK(vkd.bindImageMemory(vkDevice, *m_textureImage, m_textureImageMemory->getMemory(), m_textureImageMemory->getOffset()));
    371 
    372 	updateTextureViewMipLevels(0, mipLevels - 1);
    373 
    374 	pipeline::uploadTestTexture(vkd, vkDevice, queue, queueFamilyIndex, allocator, *m_textureData, *m_textureImage);
    375 }
    376 
    377 void TextureBinding::updateTextureViewMipLevels (deUint32 baseLevel, deUint32 maxLevel)
    378 {
    379 	const DeviceInterface&						vkd						= m_context.getDeviceInterface();
    380 	const VkDevice								vkDevice				= m_context.getDevice();
    381 	const vk::VkImageViewType					imageViewType			= textureTypeToImageViewType(m_type);
    382 	const vk::VkFormat							format					= m_textureData->isCompressed() ? mapCompressedTextureFormat(m_textureData->getCompressedLevel(0, 0).getFormat()) : mapTextureFormat(m_textureData->getTextureFormat());
    383 	const bool									isShadowTexture			= tcu::hasDepthComponent(m_textureData->getTextureFormat().order);
    384 	const VkImageAspectFlags					aspectMask				= isShadowTexture ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
    385 	const deUint32								layerCount				= m_textureData->getArraySize();
    386 	const vk::VkImageViewCreateInfo				viewParams				=
    387 	{
    388 		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
    389 		NULL,											// const voide*				pNext;
    390 		0u,												// VkImageViewCreateFlags	flags;
    391 		*m_textureImage,								// VkImage					image;
    392 		imageViewType,									// VkImageViewType			viewType;
    393 		format,											// VkFormat					format;
    394 		makeComponentMappingRGBA(),						// VkComponentMapping		components;
    395 		{
    396 			aspectMask,									// VkImageAspectFlags	aspectMask;
    397 			baseLevel,									// deUint32				baseMipLevel;
    398 			maxLevel-baseLevel+1,						// deUint32				levelCount;
    399 			0,											// deUint32				baseArrayLayer;
    400 			layerCount									// deUint32				layerCount;
    401 		},												// VkImageSubresourceRange	subresourceRange;
    402 	};
    403 
    404 	m_textureImageView		= createImageView(vkd, vkDevice, &viewParams);
    405 }
    406 
    407 const deUint16		TextureRenderer::s_vertexIndices[6] = { 0, 1, 2, 2, 1, 3 };
    408 const VkDeviceSize	TextureRenderer::s_vertexIndexBufferSize = sizeof(TextureRenderer::s_vertexIndices);
    409 
    410 TextureRenderer::TextureRenderer (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderWidth, deUint32 renderHeight)
    411 	: m_context					(context)
    412 	, m_log						(context.getTestContext().getLog())
    413 	, m_renderWidth				(renderWidth)
    414 	, m_renderHeight			(renderHeight)
    415 	, m_sampleCount				(sampleCount)
    416 	, m_multisampling			(m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
    417 	, m_imageFormat				(VK_FORMAT_R8G8B8A8_UNORM)
    418 	, m_textureFormat			(vk::mapVkFormat(m_imageFormat))
    419 	, m_uniformBufferSize		(sizeof(ShaderParameters))
    420 	, m_resultBufferSize		(renderWidth * renderHeight * m_textureFormat.getPixelSize())
    421 	, m_viewportOffsetX			(0.0f)
    422 	, m_viewportOffsetY			(0.0f)
    423 	, m_viewportWidth			((float)renderWidth)
    424 	, m_viewportHeight			((float)renderHeight)
    425 {
    426 	const DeviceInterface&						vkd						= m_context.getDeviceInterface();
    427 	const VkDevice								vkDevice				= m_context.getDevice();
    428 	const deUint32								queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
    429 	Allocator&									allocator				= m_context.getDefaultAllocator();
    430 
    431 	// Command Pool
    432 	m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
    433 
    434 	// Image
    435 	{
    436 		const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    437 		VkImageFormatProperties	properties;
    438 
    439 		if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
    440 																					 m_imageFormat,
    441 																					 VK_IMAGE_TYPE_2D,
    442 																					 VK_IMAGE_TILING_OPTIMAL,
    443 																					 imageUsage,
    444 																					 0,
    445 																					 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
    446 		{
    447 			TCU_THROW(NotSupportedError, "Format not supported");
    448 		}
    449 
    450 		if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
    451 		{
    452 			TCU_THROW(NotSupportedError, "Format not supported");
    453 		}
    454 
    455 		const VkImageCreateInfo					imageCreateInfo			=
    456 		{
    457 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
    458 			DE_NULL,									// const void*				pNext;
    459 			0u,											// VkImageCreateFlags		flags;
    460 			VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
    461 			m_imageFormat,								// VkFormat					format;
    462 			{ m_renderWidth, m_renderHeight, 1u },		// VkExtent3D				extent;
    463 			1u,											// deUint32					mipLevels;
    464 			1u,											// deUint32					arrayLayers;
    465 			m_sampleCount,								// VkSampleCountFlagBits	samples;
    466 			VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
    467 			imageUsage,									// VkImageUsageFlags		usage;
    468 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
    469 			1u,											// deUint32					queueFamilyIndexCount;
    470 			&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
    471 			VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
    472 		};
    473 
    474 		m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
    475 
    476 		m_imageMemory	= allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
    477 		VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
    478 	}
    479 
    480 	// Image View
    481 	{
    482 		const VkImageViewCreateInfo				imageViewCreateInfo		=
    483 		{
    484 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
    485 			DE_NULL,									// const void*					pNext;
    486 			0u,											// VkImageViewCreateFlags		flags;
    487 			*m_image,									// VkImage						image;
    488 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
    489 			m_imageFormat,								// VkFormat						format;
    490 			makeComponentMappingRGBA(),					// VkComponentMapping			components;
    491 			{
    492 				VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
    493 				0u,											// deUint32						baseMipLevel;
    494 				1u,											// deUint32						mipLevels;
    495 				0u,											// deUint32						baseArrayLayer;
    496 				1u,											// deUint32						arraySize;
    497 			},											// VkImageSubresourceRange		subresourceRange;
    498 		};
    499 
    500 		m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
    501 	}
    502 
    503 	if (m_multisampling)
    504 	{
    505 		{
    506 			// Resolved Image
    507 			const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    508 			VkImageFormatProperties	properties;
    509 
    510 			if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
    511 																						 m_imageFormat,
    512 																						 VK_IMAGE_TYPE_2D,
    513 																						 VK_IMAGE_TILING_OPTIMAL,
    514 																						 imageUsage,
    515 																						 0,
    516 																						 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
    517 			{
    518 				TCU_THROW(NotSupportedError, "Format not supported");
    519 			}
    520 
    521 			const VkImageCreateInfo					imageCreateInfo			=
    522 			{
    523 				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
    524 				DE_NULL,									// const void*				pNext;
    525 				0u,											// VkImageCreateFlags		flags;
    526 				VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
    527 				m_imageFormat,								// VkFormat					format;
    528 				{ m_renderWidth, m_renderHeight, 1u },		// VkExtent3D				extent;
    529 				1u,											// deUint32					mipLevels;
    530 				1u,											// deUint32					arrayLayers;
    531 				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
    532 				VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
    533 				imageUsage,									// VkImageUsageFlags		usage;
    534 				VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
    535 				1u,											// deUint32					queueFamilyIndexCount;
    536 				&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
    537 				VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
    538 			};
    539 
    540 			m_resolvedImage			= vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
    541 			m_resolvedImageMemory	= allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
    542 			VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
    543 		}
    544 
    545 		// Resolved Image View
    546 		{
    547 			const VkImageViewCreateInfo				imageViewCreateInfo		=
    548 			{
    549 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
    550 				DE_NULL,									// const void*					pNext;
    551 				0u,											// VkImageViewCreateFlags		flags;
    552 				*m_resolvedImage,							// VkImage						image;
    553 				VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
    554 				m_imageFormat,								// VkFormat						format;
    555 				makeComponentMappingRGBA(),					// VkComponentMapping			components;
    556 				{
    557 					VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
    558 					0u,											// deUint32						baseMipLevel;
    559 					1u,											// deUint32						mipLevels;
    560 					0u,											// deUint32						baseArrayLayer;
    561 					1u,											// deUint32						arraySize;
    562 				},											// VkImageSubresourceRange		subresourceRange;
    563 			};
    564 
    565 			m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
    566 		}
    567 	}
    568 
    569 	// Render Pass
    570 	{
    571 		const VkImageLayout						imageLayout				= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    572 		const VkAttachmentDescription			attachmentDesc[]		=
    573 		{
    574 			{
    575 				0u,													// VkAttachmentDescriptionFlags		flags;
    576 				m_imageFormat,										// VkFormat							format;
    577 				m_sampleCount,										// VkSampleCountFlagBits			samples;
    578 				VK_ATTACHMENT_LOAD_OP_LOAD,												// VkAttachmentLoadOp				loadOp;
    579 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
    580 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
    581 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
    582 				imageLayout,										// VkImageLayout					initialLayout;
    583 				imageLayout,										// VkImageLayout					finalLayout;
    584 			},
    585 			{
    586 				0u,													// VkAttachmentDescriptionFlags		flags;
    587 				m_imageFormat,										// VkFormat							format;
    588 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
    589 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				loadOp;
    590 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
    591 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
    592 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
    593 				imageLayout,										// VkImageLayout					initialLayout;
    594 				imageLayout,										// VkImageLayout					finalLayout;
    595 			}
    596 		};
    597 
    598 		const VkAttachmentReference				attachmentRef			=
    599 		{
    600 			0u,													// deUint32							attachment;
    601 			imageLayout,										// VkImageLayout					layout;
    602 		};
    603 
    604 		const VkAttachmentReference				resolveAttachmentRef	=
    605 		{
    606 			1u,													// deUint32							attachment;
    607 			imageLayout,										// VkImageLayout					layout;
    608 		};
    609 
    610 		const VkSubpassDescription				subpassDesc				=
    611 		{
    612 			0u,													// VkSubpassDescriptionFlags		flags;
    613 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
    614 			0u,													// deUint32							inputAttachmentCount;
    615 			DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
    616 			1u,													// deUint32							colorAttachmentCount;
    617 			&attachmentRef,										// const VkAttachmentReference*		pColorAttachments;
    618 			m_multisampling ? &resolveAttachmentRef : DE_NULL,	// const VkAttachmentReference*		pResolveAttachments;
    619 			DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
    620 			0u,													// deUint32							preserveAttachmentCount;
    621 			DE_NULL,											// const VkAttachmentReference*		pPreserveAttachments;
    622 		};
    623 
    624 		const VkRenderPassCreateInfo			renderPassCreateInfo	=
    625 		{
    626 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
    627 			DE_NULL,											// const void*						pNext;
    628 			0u,													// VkRenderPassCreateFlags			flags;
    629 			m_multisampling ? 2u : 1u,							// deUint32							attachmentCount;
    630 			attachmentDesc,										// const VkAttachmentDescription*	pAttachments;
    631 			1u,													// deUint32							subpassCount;
    632 			&subpassDesc,										// const VkSubpassDescription*		pSubpasses;
    633 			0u,													// deUint32							dependencyCount;
    634 			DE_NULL,											// const VkSubpassDependency*		pDependencies;
    635 		};
    636 
    637 		m_renderPass =  createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
    638 	}
    639 
    640 	// Vertex index buffer
    641 	{
    642 		const VkBufferCreateInfo			indexBufferParams		=
    643 		{
    644 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    645 			DE_NULL,									// const void*			pNext;
    646 			0u,											// VkBufferCreateFlags	flags;
    647 			s_vertexIndexBufferSize,					// VkDeviceSize			size;
    648 			VK_BUFFER_USAGE_INDEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
    649 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    650 			1u,											// deUint32				queueFamilyCount;
    651 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
    652 		};
    653 
    654 		m_vertexIndexBuffer			= createBuffer(vkd, vkDevice, &indexBufferParams);
    655 		m_vertexIndexBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_vertexIndexBuffer), MemoryRequirement::HostVisible);
    656 
    657 		VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_vertexIndexBuffer, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset()));
    658 
    659 		// Load vertices into vertex buffer
    660 		deMemcpy(m_vertexIndexBufferMemory->getHostPtr(), s_vertexIndices, s_vertexIndexBufferSize);
    661 		flushMappedMemoryRange(vkd, vkDevice, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset(), VK_WHOLE_SIZE);
    662 	}
    663 
    664 	// FrameBuffer
    665 	{
    666 		const VkImageView						attachments[]			=
    667 		{
    668 			*m_imageView,
    669 			*m_resolvedImageView,
    670 		};
    671 
    672 		const VkFramebufferCreateInfo			framebufferCreateInfo	=
    673 		{
    674 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
    675 			DE_NULL,									// const void*				pNext;
    676 			0u,											// VkFramebufferCreateFlags	flags;
    677 			*m_renderPass,								// VkRenderPass				renderPass;
    678 			m_multisampling ? 2u : 1u,					// deUint32					attachmentCount;
    679 			attachments,								// const VkImageView*		pAttachments;
    680 			m_renderWidth,								// deUint32					width;
    681 			m_renderHeight,								// deUint32					height;
    682 			1u,											// deUint32					layers;
    683 		};
    684 
    685 		m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
    686 	}
    687 
    688 	// Uniform Buffer
    689 	{
    690 		const VkBufferCreateInfo				bufferCreateInfo		=
    691 		{
    692 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    693 			DE_NULL,									// const void*			pNext;
    694 			0u,											// VkBufferCreateFlags	flags;
    695 			m_uniformBufferSize,						// VkDeviceSize			size;
    696 			VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,			// VkBufferUsageFlags	usage;
    697 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    698 			1u,											// deUint32				queueFamilyIndexCount;
    699 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
    700 		};
    701 
    702 		m_uniformBuffer			= createBuffer(vkd, vkDevice, &bufferCreateInfo);
    703 		m_uniformBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
    704 
    705 		VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
    706 	}
    707 
    708 	// DescriptorPool
    709 	{
    710 		DescriptorPoolBuilder					descriptorPoolBuilder;
    711 
    712 		descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
    713 		descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
    714 		m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
    715 	}
    716 
    717 	// Fence
    718 	m_fence = createFence(vkd, vkDevice);
    719 
    720 	// Result Buffer
    721 	{
    722 		const VkBufferCreateInfo				bufferCreateInfo		=
    723 		{
    724 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    725 			DE_NULL,									// const void*			pNext;
    726 			0u,											// VkBufferCreateFlags	flags;
    727 			m_resultBufferSize,							// VkDeviceSize			size;
    728 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
    729 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    730 			1u,											// deUint32				queueFamilyIndexCount;
    731 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
    732 		};
    733 
    734 		m_resultBuffer			= createBuffer(vkd, vkDevice, &bufferCreateInfo);
    735 		m_resultBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
    736 
    737 		VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
    738 	}
    739 
    740 	clearImage(*m_image);
    741 	if(m_multisampling)
    742 		clearImage(*m_resolvedImage);
    743 }
    744 
    745 TextureRenderer::~TextureRenderer (void)
    746 {
    747 }
    748 
    749 void TextureRenderer::clearImage(VkImage image)
    750 {
    751 	const DeviceInterface&			vkd					= m_context.getDeviceInterface();
    752 	const VkDevice					vkDevice			= m_context.getDevice();
    753 	Move<VkCommandBuffer>			commandBuffer;
    754 	const VkQueue					queue				= m_context.getUniversalQueue();
    755 
    756 	const VkImageSubresourceRange	subResourcerange	=
    757 	{
    758 		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
    759 		0,								// deUint32				baseMipLevel;
    760 		1,								// deUint32				levelCount;
    761 		0,								// deUint32				baseArrayLayer;
    762 		1								// deUint32				layerCount;
    763 	};
    764 
    765 	commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
    766 
    767 	const VkCommandBufferBeginInfo		cmdBufferBeginInfo		=
    768 	{
    769 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType							sType;
    770 		DE_NULL,										// const void*								pNext;
    771 		0u,												// VkCmdBufferOptimizeFlags					flags;
    772 		DE_NULL											// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
    773 	};
    774 
    775 	VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
    776 
    777 	addImageTransitionBarrier(*commandBuffer, image,
    778 							  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// VkPipelineStageFlags		srcStageMask
    779 							  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,				// VkPipelineStageFlags		dstStageMask
    780 							  0,												// VkAccessFlags			srcAccessMask
    781 							  VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			dstAccessMask
    782 							  VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
    783 							  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);			// VkImageLayout			newLayout;
    784 
    785 	VkClearColorValue color = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color;
    786 	vkd.cmdClearColorImage(*commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subResourcerange);
    787 
    788 	addImageTransitionBarrier(*commandBuffer, image,
    789 							  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// VkPipelineStageFlags		srcStageMask
    790 							  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,				// VkPipelineStageFlags		dstStageMask
    791 							  VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask
    792 							  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags			dstAccessMask
    793 							  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout;
    794 							  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);		// VkImageLayout			newLayout;
    795 
    796 	VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
    797 
    798 	const VkSubmitInfo					submitInfo				=
    799 	{
    800 		VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType				sType;
    801 		DE_NULL,								// const void*					pNext;
    802 		0u,										// deUint32						waitSemaphoreCount;
    803 		DE_NULL,								// const VkSemaphore*			pWaitSemaphores;
    804 		DE_NULL,								// const VkPipelineStageFlags*	pWaitDstStageMask;
    805 		1u,										// deUint32						commandBufferCount;
    806 		&commandBuffer.get(),					// const VkCommandBuffer*		pCommandBuffers;
    807 		0u,										// deUint32						signalSemaphoreCount;
    808 		DE_NULL,								// const VkSemaphore*			pSignalSemaphores;
    809 	};
    810 
    811 	VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
    812 	VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
    813 	VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
    814 }
    815 
    816 void TextureRenderer::add2DTexture (const TestTexture2DSp& texture)
    817 {
    818 	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D)));
    819 }
    820 
    821 void TextureRenderer::addCubeTexture (const TestTextureCubeSp& texture)
    822 {
    823 	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_CUBE_MAP)));
    824 }
    825 
    826 void TextureRenderer::add2DArrayTexture (const TestTexture2DArraySp& texture)
    827 {
    828 	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D_ARRAY)));
    829 }
    830 
    831 void TextureRenderer::add3DTexture (const TestTexture3DSp& texture)
    832 {
    833 	m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_3D)));
    834 }
    835 
    836 const pipeline::TestTexture2D& TextureRenderer::get2DTexture (int textureIndex) const
    837 {
    838 	DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
    839 	DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D);
    840 
    841 	return dynamic_cast<const pipeline::TestTexture2D&>(m_textureBindings[textureIndex]->getTestTexture());
    842 }
    843 
    844 const pipeline::TestTextureCube& TextureRenderer::getCubeTexture (int textureIndex) const
    845 {
    846 	DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
    847 	DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_CUBE_MAP);
    848 
    849 	return dynamic_cast<const pipeline::TestTextureCube&>(m_textureBindings[textureIndex]->getTestTexture());
    850 }
    851 
    852 const pipeline::TestTexture2DArray& TextureRenderer::get2DArrayTexture (int textureIndex) const
    853 {
    854 	DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
    855 	DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D_ARRAY);
    856 
    857 	return dynamic_cast<const pipeline::TestTexture2DArray&>(m_textureBindings[textureIndex]->getTestTexture());
    858 }
    859 
    860 const pipeline::TestTexture3D& TextureRenderer::get3DTexture (int textureIndex) const
    861 {
    862 	DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
    863 	DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_3D);
    864 
    865 	return dynamic_cast<const pipeline::TestTexture3D&>(m_textureBindings[textureIndex]->getTestTexture());
    866 }
    867 
    868 void TextureRenderer::setViewport (float viewportX, float viewportY, float viewportW, float viewportH)
    869 {
    870 	m_viewportHeight = viewportH;
    871 	m_viewportWidth = viewportW;
    872 	m_viewportOffsetX = viewportX;
    873 	m_viewportOffsetY = viewportY;
    874 }
    875 
    876 TextureBinding* TextureRenderer::getTextureBinding (int textureIndex) const
    877 {
    878 	DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
    879 	return m_textureBindings[textureIndex].get();
    880 }
    881 
    882 deUint32 TextureRenderer::getRenderWidth (void) const
    883 {
    884 	return m_renderWidth;
    885 }
    886 
    887 deUint32 TextureRenderer::getRenderHeight (void) const
    888 {
    889 	return m_renderHeight;
    890 }
    891 
    892 Move<VkDescriptorSet> TextureRenderer::makeDescriptorSet (const VkDescriptorPool descriptorPool, const VkDescriptorSetLayout setLayout) const
    893 {
    894 	const DeviceInterface&						vkd						= m_context.getDeviceInterface();
    895 	const VkDevice								vkDevice				= m_context.getDevice();
    896 
    897 	const VkDescriptorSetAllocateInfo			allocateParams			=
    898 	{
    899 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType					sType
    900 			DE_NULL,											// const void*						pNext
    901 			descriptorPool,										// VkDescriptorPool					descriptorPool
    902 			1u,													// deUint32							descriptorSetCount
    903 			&setLayout,											// const VkDescriptorSetLayout*		pSetLayouts
    904 	};
    905 	return allocateDescriptorSet(vkd, vkDevice, &allocateParams);
    906 }
    907 
    908 void TextureRenderer::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
    909 {
    910 	const DeviceInterface&			vkd					= m_context.getDeviceInterface();
    911 
    912 	const VkImageSubresourceRange	subResourcerange	=
    913 	{
    914 		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
    915 		0,								// deUint32				baseMipLevel;
    916 		1,								// deUint32				levelCount;
    917 		0,								// deUint32				baseArrayLayer;
    918 		1								// deUint32				layerCount;
    919 	};
    920 
    921 	const VkImageMemoryBarrier		imageBarrier		=
    922 	{
    923 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
    924 		DE_NULL,									// const void*				pNext;
    925 		srcAccessMask,								// VkAccessFlags			srcAccessMask;
    926 		dstAccessMask,								// VkAccessFlags			dstAccessMask;
    927 		oldLayout,									// VkImageLayout			oldLayout;
    928 		newLayout,									// VkImageLayout			newLayout;
    929 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
    930 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex;
    931 		image,										// VkImage					image;
    932 		subResourcerange							// VkImageSubresourceRange	subresourceRange;
    933 	};
    934 
    935 	vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
    936 }
    937 
    938 
    939 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, TextureType texType)
    940 {
    941 	renderQuad(result, texUnit, texCoord, ReferenceParams(texType));
    942 }
    943 
    944 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, const ReferenceParams& params)
    945 {
    946 	const float	maxAnisotropy = 1.0f;
    947 	float		positions[]	=
    948 	{
    949 		-1.0,	-1.0f,	0.0f,	1.0f,
    950 		-1.0f,	+1.0f,	0.0f,	1.0f,
    951 		+1.0f,	-1.0f,	0.0f,	1.0f,
    952 		+1.0f,	+1.0f,	0.0f,	1.0f
    953 	};
    954 	renderQuad(result, positions, texUnit, texCoord, params, maxAnisotropy);
    955 }
    956 
    957 void TextureRenderer::renderQuad (tcu::Surface&									result,
    958 								  const float*									positions,
    959 								  int											texUnit,
    960 								  const float*									texCoord,
    961 								  const glu::TextureTestUtil::ReferenceParams&	params,
    962 								  const float									maxAnisotropy)
    963 {
    964 	const DeviceInterface&		vkd						= m_context.getDeviceInterface();
    965 	const VkDevice				vkDevice				= m_context.getDevice();
    966 	const VkQueue				queue					= m_context.getUniversalQueue();
    967 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
    968 	Allocator&					allocator				= m_context.getDefaultAllocator();
    969 
    970 	tcu::Vec4					wCoord					= params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
    971 	bool						useBias					= !!(params.flags & RenderParams::USE_BIAS);
    972 	bool						logUniforms				= !!(params.flags & RenderParams::LOG_UNIFORMS);
    973 
    974 	// Render quad with texture.
    975 	float						position[]				=
    976 	{
    977 		positions[0]*wCoord.x(),	positions[1]*wCoord.x(),	positions[2],	positions[3]*wCoord.x(),
    978 		positions[4]*wCoord.y(),	positions[5]*wCoord.y(),	positions[6],	positions[7]*wCoord.y(),
    979 		positions[8]*wCoord.z(),	positions[9]*wCoord.z(),	positions[10],	positions[11]*wCoord.z(),
    980 		positions[12]*wCoord.w(),	positions[13]*wCoord.w(),	positions[14],	positions[15]*wCoord.w()
    981 	};
    982 
    983 	Program						progSpec				= PROGRAM_LAST;
    984 	int							numComps				= 0;
    985 
    986 	if (params.texType == TEXTURETYPE_2D)
    987 	{
    988 		numComps = 2;
    989 
    990 		switch (params.samplerType)
    991 		{
    992 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS	: PROGRAM_2D_FLOAT;		break;
    993 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_2D_INT_BIAS	: PROGRAM_2D_INT;		break;
    994 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_2D_UINT_BIAS	: PROGRAM_2D_UINT;		break;
    995 			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS	: PROGRAM_2D_SHADOW;	break;
    996 			default:					DE_ASSERT(false);
    997 		}
    998 	}
    999 	else if (params.texType == TEXTURETYPE_1D)
   1000 	{
   1001 		numComps = 1;
   1002 
   1003 		switch (params.samplerType)
   1004 		{
   1005 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS	: PROGRAM_1D_FLOAT;		break;
   1006 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_1D_INT_BIAS	: PROGRAM_1D_INT;		break;
   1007 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_1D_UINT_BIAS	: PROGRAM_1D_UINT;		break;
   1008 			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS	: PROGRAM_1D_SHADOW;	break;
   1009 			default:					DE_ASSERT(false);
   1010 		}
   1011 	}
   1012 	else if (params.texType == TEXTURETYPE_CUBE)
   1013 	{
   1014 		numComps = 3;
   1015 
   1016 		switch (params.samplerType)
   1017 		{
   1018 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS	: PROGRAM_CUBE_FLOAT;	break;
   1019 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_CUBE_INT_BIAS		: PROGRAM_CUBE_INT;		break;
   1020 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS		: PROGRAM_CUBE_UINT;	break;
   1021 			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS	: PROGRAM_CUBE_SHADOW;	break;
   1022 			default:					DE_ASSERT(false);
   1023 		}
   1024 	}
   1025 	else if (params.texType == TEXTURETYPE_3D)
   1026 	{
   1027 		numComps = 3;
   1028 
   1029 		switch (params.samplerType)
   1030 		{
   1031 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS	: PROGRAM_3D_FLOAT;		break;
   1032 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_3D_INT_BIAS	: PROGRAM_3D_INT;		break;
   1033 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_3D_UINT_BIAS	: PROGRAM_3D_UINT;		break;
   1034 			default:					DE_ASSERT(false);
   1035 		}
   1036 	}
   1037 	else if (params.texType == TEXTURETYPE_2D_ARRAY)
   1038 	{
   1039 		DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
   1040 
   1041 		numComps = 3;
   1042 
   1043 		switch (params.samplerType)
   1044 		{
   1045 			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_2D_ARRAY_FLOAT;	break;
   1046 			case SAMPLERTYPE_INT:		progSpec = PROGRAM_2D_ARRAY_INT;	break;
   1047 			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_2D_ARRAY_UINT;	break;
   1048 			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_2D_ARRAY_SHADOW;	break;
   1049 			default:					DE_ASSERT(false);
   1050 		}
   1051 	}
   1052 	else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
   1053 	{
   1054 		DE_ASSERT(!useBias);
   1055 
   1056 		numComps = 4;
   1057 
   1058 		switch (params.samplerType)
   1059 		{
   1060 			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_CUBE_ARRAY_FLOAT;	break;
   1061 			case SAMPLERTYPE_INT:		progSpec = PROGRAM_CUBE_ARRAY_INT;		break;
   1062 			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_CUBE_ARRAY_UINT;		break;
   1063 			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_CUBE_ARRAY_SHADOW;	break;
   1064 			default:					DE_ASSERT(false);
   1065 		}
   1066 	}
   1067 	else if (params.texType == TEXTURETYPE_1D_ARRAY)
   1068 	{
   1069 		DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
   1070 
   1071 		numComps = 2;
   1072 
   1073 		switch (params.samplerType)
   1074 		{
   1075 			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_1D_ARRAY_FLOAT;	break;
   1076 			case SAMPLERTYPE_INT:		progSpec = PROGRAM_1D_ARRAY_INT;	break;
   1077 			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_1D_ARRAY_UINT;	break;
   1078 			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_1D_ARRAY_SHADOW;	break;
   1079 			default:					DE_ASSERT(false);
   1080 		}
   1081 	}
   1082 	else if (params.texType == TEXTURETYPE_BUFFER)
   1083 	{
   1084 		numComps = 1;
   1085 
   1086 		switch (params.samplerType)
   1087 		{
   1088 			case SAMPLERTYPE_FETCH_FLOAT:	progSpec = PROGRAM_BUFFER_FLOAT;	break;
   1089 			case SAMPLERTYPE_FETCH_INT:		progSpec = PROGRAM_BUFFER_INT;		break;
   1090 			case SAMPLERTYPE_FETCH_UINT:	progSpec = PROGRAM_BUFFER_UINT;		break;
   1091 			default:						DE_ASSERT(false);
   1092 		}
   1093 	}
   1094 	else
   1095 		DE_ASSERT(DE_FALSE);
   1096 
   1097 	Unique<VkShaderModule>					vertexShaderModule			(createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_" + std::string(getProgramName(progSpec))), 0));
   1098 	Unique<VkShaderModule>					fragmentShaderModule		(createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_" + std::string(getProgramName(progSpec))), 0));
   1099 
   1100 	Move<VkSampler>							sampler;
   1101 	Move<VkDescriptorSet>					descriptorSet[2];
   1102 	Move<VkDescriptorSetLayout>				descriptorSetLayout[2];
   1103 	Move<VkPipelineLayout>					pipelineLayout;
   1104 
   1105 	Move<VkCommandBuffer>					commandBuffer;
   1106 	Move<VkPipeline>						graphicsPipeline;
   1107 	Move<VkBuffer>							vertexBuffer;
   1108 	de::MovePtr<Allocation>					vertexBufferMemory;
   1109 
   1110 	const VkDeviceSize						vertexBufferOffset			= 0;
   1111 	const deUint32							vertexPositionStrideSize	= deUint32(sizeof(tcu::Vec4));
   1112 	const deUint32							vertexTextureStrideSize		= deUint32(numComps * sizeof(float));
   1113 	const deUint32							positionDataSize			= vertexPositionStrideSize * 4u;
   1114 	const deUint32							textureCoordDataSize		= vertexTextureStrideSize * 4u;
   1115 
   1116 	const VkPhysicalDeviceProperties		properties					= m_context.getDeviceProperties();
   1117 
   1118 	if (positionDataSize > properties.limits.maxVertexInputAttributeOffset)
   1119 	{
   1120 		std::stringstream message;
   1121 		message << "Larger vertex input attribute offset is needed (" << positionDataSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
   1122 		TCU_THROW(NotSupportedError, message.str().c_str());
   1123 	}
   1124 
   1125 	// Create Graphics Pipeline
   1126 	{
   1127 		const VkPipelineShaderStageCreateInfo	shaderStageParams[2]	=
   1128 		{
   1129 			{
   1130 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType					sType;
   1131 				DE_NULL,													// const void*						pNext;
   1132 				0,															// VkPipelineShaderStageCreateFlags flags;
   1133 				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStage					stage;
   1134 				*vertexShaderModule,										// VkShaderModule					shader;
   1135 				"main",														// const char*						pName;
   1136 				DE_NULL														// const VkSpecializationInfo*		pSpecializationInfo;
   1137 			},
   1138 			{
   1139 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType					sType;
   1140 				DE_NULL,													// const void*						pNext;
   1141 				0,															// VkPipelineShaderStageCreateFlags flags;
   1142 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStage					stage;
   1143 				*fragmentShaderModule,										// VkShaderModule					shader;
   1144 				"main",														// const char*						pName;
   1145 				DE_NULL														// const VkSpecializationInfo*		pSpecializationInfo;
   1146 			}
   1147 		};
   1148 
   1149 		const VkVertexInputBindingDescription	vertexInputBindingDescription[2]	=
   1150 		{
   1151 			{
   1152 				0u,								// deUint32					binding;
   1153 				vertexPositionStrideSize,		// deUint32					strideInBytes;
   1154 				VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	stepRate;
   1155 			},
   1156 			{
   1157 				1u,								// deUint32					binding;
   1158 				vertexTextureStrideSize,		// deUint32					strideInBytes;
   1159 				VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	stepRate;
   1160 			}
   1161 		};
   1162 
   1163 		VkFormat								textureCoordinateFormat			= VK_FORMAT_R32G32B32A32_SFLOAT;
   1164 
   1165 		switch (numComps) {
   1166 			case 1: textureCoordinateFormat = VK_FORMAT_R32_SFLOAT;				break;
   1167 			case 2: textureCoordinateFormat = VK_FORMAT_R32G32_SFLOAT;			break;
   1168 			case 3: textureCoordinateFormat = VK_FORMAT_R32G32B32_SFLOAT;		break;
   1169 			case 4: textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT;	break;
   1170 			default:
   1171 				DE_ASSERT(false);
   1172 		}
   1173 
   1174 		const VkVertexInputAttributeDescription	vertexInputAttributeDescriptions[2] =
   1175 		{
   1176 			{
   1177 				0u,									// deUint32	location;
   1178 				0u,									// deUint32	binding;
   1179 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
   1180 				0u									// deUint32	offsetInBytes;
   1181 			},
   1182 			{
   1183 				1u,									// deUint32	location;
   1184 				1u,									// deUint32	binding;
   1185 				textureCoordinateFormat,			// VkFormat	format;
   1186 				positionDataSize					// deUint32	offsetInBytes;
   1187 			}
   1188 		};
   1189 
   1190 		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams =
   1191 		{
   1192 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
   1193 			DE_NULL,														// const void*								pNext;
   1194 			0,																// VkPipelineVertexInputStateCreateFlags	flags;
   1195 			2u,																// deUint32									bindingCount;
   1196 			vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
   1197 			2u,																// deUint32									attributeCount;
   1198 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
   1199 		};
   1200 
   1201 		const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateParams =
   1202 		{
   1203 			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
   1204 			DE_NULL,														// const void*								pNext;
   1205 			0,																// VkPipelineInputAssemblyStateCreateFlags	flags;
   1206 			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
   1207 			VK_FALSE														// VkBool32									primitiveRestartEnable;
   1208 		};
   1209 
   1210 		const VkViewport						viewport =
   1211 		{
   1212 			m_viewportOffsetX,			// float	originX;
   1213 			m_viewportOffsetY,			// float	originY;
   1214 			m_viewportWidth,			// float	width;
   1215 			m_viewportHeight,			// float	height;
   1216 			0.0f,						// float	minDepth;
   1217 			1.0f						// float	maxDepth;
   1218 		};
   1219 
   1220 		const VkRect2D							scissor =
   1221 		{
   1222 			{ 0, 0 },														// VkOffset2D  offset;
   1223 			{ m_renderWidth, m_renderHeight }								// VkExtent2D  extent;
   1224 		};
   1225 
   1226 		const VkPipelineViewportStateCreateInfo	viewportStateParams =
   1227 		{
   1228 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
   1229 			DE_NULL,														// const void*							pNext;
   1230 			0,																// VkPipelineViewportStateCreateFlags	flags;
   1231 			1u,																// deUint32								viewportCount;
   1232 			&viewport,														// const VkViewport*					pViewports;
   1233 			1u,																// deUint32								scissorCount;
   1234 			&scissor														// const VkRect2D*						pScissors;
   1235 		};
   1236 
   1237 		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
   1238 		{
   1239 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
   1240 			DE_NULL,														// const void*								pNext;
   1241 			0u,																// VkPipelineMultisampleStateCreateFlags	flags;
   1242 			m_sampleCount,													// VkSampleCountFlagBits					rasterizationSamples;
   1243 			VK_FALSE,														// VkBool32									sampleShadingEnable;
   1244 			0.0f,															// float									minSampleShading;
   1245 			DE_NULL,														// const VkSampleMask*						pSampleMask;
   1246 			VK_FALSE,														// VkBool32									alphaToCoverageEnable;
   1247 			VK_FALSE														// VkBool32									alphaToOneEnable;
   1248 		};
   1249 
   1250 		const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
   1251 		{
   1252 			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
   1253 			DE_NULL,														// const void*								pNext;
   1254 			0,																// VkPipelineRasterizationStateCreateFlags	flags;
   1255 			VK_FALSE,														// VkBool32									depthClipEnable;
   1256 			VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
   1257 			VK_POLYGON_MODE_FILL,											// VkFillMode								fillMode;
   1258 			VK_CULL_MODE_NONE,												// VkCullMode								cullMode;
   1259 			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
   1260 			VK_FALSE,														// VkBool32									depthBiasEnable;
   1261 			0.0f,															// float									depthBias;
   1262 			0.0f,															// float									depthBiasClamp;
   1263 			0.0f,															// float									slopeScaledDepthBias;
   1264 			1.0f,															// float									lineWidth;
   1265 		};
   1266 
   1267 		const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState	=
   1268 		{
   1269 			VK_FALSE,													// VkBool32			blendEnable;
   1270 			VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendColor;
   1271 			VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendColor;
   1272 			VK_BLEND_OP_ADD,											// VkBlendOp		blendOpColor;
   1273 			VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendAlpha;
   1274 			VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendAlpha;
   1275 			VK_BLEND_OP_ADD,											// VkBlendOp		blendOpAlpha;
   1276 			(VK_COLOR_COMPONENT_R_BIT |
   1277 			 VK_COLOR_COMPONENT_G_BIT |
   1278 			 VK_COLOR_COMPONENT_B_BIT |
   1279 			 VK_COLOR_COMPONENT_A_BIT)									// VkChannelFlags	channelWriteMask;
   1280 		};
   1281 
   1282 		const VkPipelineColorBlendStateCreateInfo	colorBlendStateParams		=
   1283 		{
   1284 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
   1285 			DE_NULL,													// const void*									pNext;
   1286 			0,															// VkPipelineColorBlendStateCreateFlags			flags;
   1287 			VK_FALSE,													// VkBool32										logicOpEnable;
   1288 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
   1289 			1u,															// deUint32										attachmentCount;
   1290 			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
   1291 			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
   1292 		};
   1293 
   1294 		VkSamplerCreateInfo					samplerCreateInfo			= mapSampler(params.sampler, m_textureBindings[texUnit]->getTestTexture().getTextureFormat(), params.minLod, params.maxLod);
   1295 
   1296 		if (maxAnisotropy > 1.0f)
   1297 		{
   1298 			samplerCreateInfo.anisotropyEnable = VK_TRUE;
   1299 			samplerCreateInfo.maxAnisotropy = maxAnisotropy;
   1300 		}
   1301 
   1302 		if (samplerCreateInfo.magFilter == VK_FILTER_LINEAR || samplerCreateInfo.minFilter == VK_FILTER_LINEAR || samplerCreateInfo.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR)
   1303 		{
   1304 			const pipeline::TestTexture&	testTexture			= m_textureBindings[texUnit]->getTestTexture();
   1305 			const VkFormat					textureFormat		= testTexture.isCompressed() ? mapCompressedTextureFormat(testTexture.getCompressedLevel(0, 0).getFormat())
   1306 																							 : mapTextureFormat          (testTexture.getTextureFormat());
   1307 			const VkFormatProperties		formatProperties	= getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), textureFormat);
   1308 
   1309 			if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
   1310 				TCU_THROW(NotSupportedError, "Linear filtering for this image format is not supported");
   1311 		}
   1312 
   1313 		sampler = createSampler(vkd, vkDevice, &samplerCreateInfo);
   1314 
   1315 		descriptorSetLayout[0] = DescriptorSetLayoutBuilder()
   1316 											.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
   1317 												.build(vkd, vkDevice);
   1318 
   1319 		descriptorSetLayout[1] = DescriptorSetLayoutBuilder()
   1320 											.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
   1321 											.build(vkd, vkDevice);
   1322 
   1323 
   1324 		descriptorSet[0] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[0]);
   1325 		descriptorSet[1] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[1]);
   1326 
   1327 		{
   1328 			const VkDescriptorBufferInfo			descriptorBufferInfo	=
   1329 			{
   1330 				*m_uniformBuffer,							// VkBuffer		buffer;
   1331 				0u,											// VkDeviceSize	offset;
   1332 				VK_WHOLE_SIZE								// VkDeviceSize	range;
   1333 			};
   1334 
   1335 			DescriptorSetUpdateBuilder()
   1336 				.writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorBufferInfo)
   1337 				.update(vkd, vkDevice);
   1338 		}
   1339 
   1340 		{
   1341 			VkDescriptorImageInfo					descriptorImageInfo		=
   1342 			{
   1343 				*sampler,										// VkSampler		sampler;
   1344 				m_textureBindings[texUnit]->getImageView(),		// VkImageView		imageView;
   1345 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL		// VkImageLayout	imageLayout;
   1346 			};
   1347 
   1348 			DescriptorSetUpdateBuilder()
   1349 				.writeSingle(*descriptorSet[1], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo)
   1350 				.update(vkd, vkDevice);
   1351 		}
   1352 
   1353 		// Pipeline Layout
   1354 		{
   1355 			VkDescriptorSetLayout					descriptorSetLayouts[2]		=
   1356 			{
   1357 				*descriptorSetLayout[0],
   1358 				*descriptorSetLayout[1]
   1359 			};
   1360 
   1361 			const VkPipelineLayoutCreateInfo		pipelineLayoutCreateInfo	=
   1362 			{
   1363 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
   1364 				DE_NULL,											// const void*					pNext;
   1365 				0u,													// VkPipelineLayoutCreateFlags	flags;
   1366 				2u,													// deUint32						descriptorSetCount;
   1367 				descriptorSetLayouts,								// const VkDescriptorSetLayout*	pSetLayouts;
   1368 				0u,													// deUint32						pushConstantRangeCount;
   1369 				DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
   1370 			};
   1371 
   1372 			pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
   1373 		}
   1374 
   1375 		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
   1376 		{
   1377 			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
   1378 			DE_NULL,											// const void*										pNext;
   1379 			0u,													// VkPipelineCreateFlags							flags;
   1380 			2u,													// deUint32											stageCount;
   1381 			shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
   1382 			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
   1383 			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
   1384 			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
   1385 			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
   1386 			&rasterizationStateCreateInfo,						// const VkPipelineRasterStateCreateInfo*			pRasterizationState;
   1387 			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
   1388 			DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
   1389 			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
   1390 			DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
   1391 			*pipelineLayout,									// VkPipelineLayout									layout;
   1392 			*m_renderPass,										// VkRenderPass										renderPass;
   1393 			0u,													// deUint32											subpass;
   1394 			0u,													// VkPipeline										basePipelineHandle;
   1395 			0u													// deInt32											basePipelineIndex;
   1396 		};
   1397 
   1398 		graphicsPipeline		= createGraphicsPipeline(vkd, vkDevice, DE_NULL, &graphicsPipelineParams);
   1399 	}
   1400 
   1401 	// Create Vertex Buffer
   1402 	{
   1403 		VkDeviceSize bufferSize = positionDataSize + textureCoordDataSize;
   1404 
   1405 		// Pad the buffer size to a stride multiple for the last element so that it isn't out of bounds
   1406 		bufferSize += vertexTextureStrideSize - ((bufferSize - vertexBufferOffset) % vertexTextureStrideSize);
   1407 
   1408 		const VkBufferCreateInfo			vertexBufferParams		=
   1409 		{
   1410 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   1411 			DE_NULL,									// const void*			pNext;
   1412 			0u,											// VkBufferCreateFlags	flags;
   1413 			bufferSize,									// VkDeviceSize			size;
   1414 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
   1415 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   1416 			1u,											// deUint32				queueFamilyCount;
   1417 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
   1418 		};
   1419 
   1420 		vertexBuffer		= createBuffer(vkd, vkDevice, &vertexBufferParams);
   1421 		vertexBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
   1422 
   1423 		VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
   1424 
   1425 		// Load vertices into vertex buffer
   1426 		deMemcpy(vertexBufferMemory->getHostPtr(), position, positionDataSize);
   1427 		deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) +  positionDataSize, texCoord, textureCoordDataSize);
   1428 		flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), VK_WHOLE_SIZE);
   1429 	}
   1430 
   1431 	// Create Command Buffer
   1432 	commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
   1433 
   1434 	// Begin Command Buffer
   1435 	{
   1436 		const VkCommandBufferBeginInfo		cmdBufferBeginInfo		=
   1437 		{
   1438 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType							sType;
   1439 			DE_NULL,										// const void*								pNext;
   1440 			0u,												// VkCmdBufferOptimizeFlags					flags;
   1441 			DE_NULL											// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
   1442 		};
   1443 
   1444 		VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
   1445 	}
   1446 
   1447 	// Begin Render Pass
   1448 	{
   1449 		const VkRenderPassBeginInfo			renderPassBeginInfo		=
   1450 		{
   1451 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
   1452 			DE_NULL,												// const void*			pNext;
   1453 			*m_renderPass,											// VkRenderPass			renderPass;
   1454 			*m_frameBuffer,											// VkFramebuffer		framebuffer;
   1455 			{
   1456 				{ 0, 0 },
   1457 				{ m_renderWidth, m_renderHeight }
   1458 			},														// VkRect2D				renderArea;
   1459 			0u,														// deUint32				clearValueCount;
   1460 			DE_NULL													// const VkClearValue*	pClearValues;
   1461 		};
   1462 
   1463 		vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   1464 	}
   1465 
   1466 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
   1467 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &descriptorSet[0].get(), 0u, DE_NULL);
   1468 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 1u, 1, &descriptorSet[1].get(), 0u, DE_NULL);
   1469 	vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
   1470 	vkd.cmdBindVertexBuffers(*commandBuffer, 1, 1, &vertexBuffer.get(), &vertexBufferOffset);
   1471 	vkd.cmdBindIndexBuffer(*commandBuffer, *m_vertexIndexBuffer, 0, VK_INDEX_TYPE_UINT16);
   1472 	vkd.cmdDrawIndexed(*commandBuffer, 6, 1, 0, 0, 0);
   1473 	vkd.cmdEndRenderPass(*commandBuffer);
   1474 
   1475 	// Copy Image
   1476 	{
   1477 		const VkBufferMemoryBarrier			bufferBarrier			=
   1478 		{
   1479 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType		sType;
   1480 			DE_NULL,									// const void*			pNext;
   1481 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkMemoryOutputFlags	outputMask;
   1482 			VK_ACCESS_HOST_READ_BIT,					// VkMemoryInputFlags	inputMask;
   1483 			VK_QUEUE_FAMILY_IGNORED,					// deUint32				srcQueueFamilyIndex;
   1484 			VK_QUEUE_FAMILY_IGNORED,					// deUint32				destQueueFamilyIndex;
   1485 			*m_resultBuffer,							// VkBuffer				buffer;
   1486 			0u,											// VkDeviceSize			offset;
   1487 			m_resultBufferSize							// VkDeviceSize			size;
   1488 		};
   1489 
   1490 		const VkBufferImageCopy				copyRegion				=
   1491 		{
   1492 			0u,											// VkDeviceSize				bufferOffset;
   1493 			m_renderWidth,								// deUint32					bufferRowLength;
   1494 			m_renderHeight,								// deUint32					bufferImageHeight;
   1495 			{
   1496 				VK_IMAGE_ASPECT_COLOR_BIT,
   1497 				0u,
   1498 				0u,
   1499 				1u
   1500 			},											// VkImageSubresourceCopy	imageSubresource;
   1501 			{ 0, 0, 0 },								// VkOffset3D				imageOffset;
   1502 			{ m_renderWidth, m_renderHeight, 1u }		// VkExtent3D				imageExtent;
   1503 		};
   1504 
   1505 		addImageTransitionBarrier(*commandBuffer,
   1506 								  m_multisampling ? *m_resolvedImage : *m_image,
   1507 								  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,		// VkPipelineStageFlags		srcStageMask
   1508 								  VK_PIPELINE_STAGE_TRANSFER_BIT,						// VkPipelineStageFlags		dstStageMask
   1509 								  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags			srcAccessMask
   1510 								  VK_ACCESS_TRANSFER_READ_BIT,							// VkAccessFlags			dstAccessMask
   1511 								  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			oldLayout;
   1512 								  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);				// VkImageLayout			newLayout;
   1513 
   1514 		if (m_multisampling)
   1515 			vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, &copyRegion);
   1516 		else
   1517 			vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, &copyRegion);
   1518 
   1519 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
   1520 
   1521 		addImageTransitionBarrier(*commandBuffer,
   1522 								  m_multisampling ? *m_resolvedImage : *m_image,
   1523 								  VK_PIPELINE_STAGE_TRANSFER_BIT,					// VkPipelineStageFlags		srcStageMask
   1524 								  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// VkPipelineStageFlags		dstStageMask
   1525 								  VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			srcAccessMask
   1526 								  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags			dstAccessMask
   1527 								  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,				// VkImageLayout			oldLayout;
   1528 								  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);		// VkImageLayout			newLayout;
   1529 	}
   1530 
   1531 	VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
   1532 
   1533 	// Upload uniform buffer data
   1534 	{
   1535 		const ShaderParameters	shaderParameters	=
   1536 		{
   1537 			params.bias,			// float		bias;				//!< User-supplied bias.
   1538 			params.ref,				// float		ref;				//!< Reference value for shadow lookups.
   1539 			tcu::Vec2(),			// tcu::Vec2	padding;			//!< Shader uniform padding.
   1540 			params.colorScale,		// tcu::Vec4	colorScale;			//!< Scale for texture color values.
   1541 			params.colorBias		// tcu::Vec4	colorBias;			//!< Bias for texture color values.
   1542 		};
   1543 		deMemcpy(m_uniformBufferMemory->getHostPtr(), &shaderParameters, sizeof(shaderParameters));
   1544 		flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), VK_WHOLE_SIZE);
   1545 
   1546 		if (logUniforms)
   1547 			m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
   1548 
   1549 		if (useBias)
   1550 		{
   1551 			if (logUniforms)
   1552 				m_log << TestLog::Message << "u_bias = " << shaderParameters.bias << TestLog::EndMessage;
   1553 		}
   1554 
   1555 		if (params.samplerType == SAMPLERTYPE_SHADOW)
   1556 		{
   1557 			if (logUniforms)
   1558 				m_log << TestLog::Message << "u_ref = " << shaderParameters.ref << TestLog::EndMessage;
   1559 		}
   1560 
   1561 		if (logUniforms)
   1562 		{
   1563 			m_log << TestLog::Message << "u_colorScale = " << shaderParameters.colorScale << TestLog::EndMessage;
   1564 			m_log << TestLog::Message << "u_colorBias = " << shaderParameters.colorBias << TestLog::EndMessage;
   1565 		}
   1566 	}
   1567 
   1568 	// Submit
   1569 	{
   1570 		const VkSubmitInfo					submitInfo				=
   1571 		{
   1572 			VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType				sType;
   1573 			DE_NULL,								// const void*					pNext;
   1574 			0u,										// deUint32						waitSemaphoreCount;
   1575 			DE_NULL,								// const VkSemaphore*			pWaitSemaphores;
   1576 			DE_NULL,								// const VkPipelineStageFlags*	pWaitDstStageMask;
   1577 			1u,										// deUint32						commandBufferCount;
   1578 			&commandBuffer.get(),					// const VkCommandBuffer*		pCommandBuffers;
   1579 			0u,										// deUint32						signalSemaphoreCount;
   1580 			DE_NULL,								// const VkSemaphore*			pSignalSemaphores;
   1581 		};
   1582 
   1583 		VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
   1584 		VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
   1585 		VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
   1586 	}
   1587 
   1588 	invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
   1589 
   1590 	tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderWidth, m_renderHeight, 1u), m_resultBufferMemory->getHostPtr()));
   1591 }
   1592 
   1593 /*--------------------------------------------------------------------*//*!
   1594  * \brief Map Vulkan sampler parameters to tcu::Sampler.
   1595  *
   1596  * If no mapping is found, throws tcu::InternalError.
   1597  *
   1598  * \param wrapU			U-component wrap mode
   1599  * \param wrapV			V-component wrap mode
   1600  * \param wrapW			W-component wrap mode
   1601  * \param minFilterMode	Minification filter mode
   1602  * \param magFilterMode	Magnification filter mode
   1603  * \return Sampler description.
   1604  *//*--------------------------------------------------------------------*/
   1605 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::WrapMode wrapW, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
   1606 {
   1607 	return tcu::Sampler(wrapU, wrapV, wrapW,
   1608 						minFilterMode, magFilterMode,
   1609 						0.0f /* lod threshold */,
   1610 						true /* normalized coords */,
   1611 						tcu::Sampler::COMPAREMODE_NONE /* no compare */,
   1612 						0 /* compare channel */,
   1613 						tcu::Vec4(0.0f) /* border color, not used */);
   1614 }
   1615 
   1616 /*--------------------------------------------------------------------*//*!
   1617  * \brief Map Vulkan sampler parameters to tcu::Sampler.
   1618  *
   1619  * If no mapping is found, throws tcu::InternalError.
   1620  *
   1621  * \param wrapU			U-component wrap mode
   1622  * \param wrapV			V-component wrap mode
   1623  * \param minFilterMode	Minification filter mode
   1624  * \param minFilterMode	Magnification filter mode
   1625  * \return Sampler description.
   1626  *//*--------------------------------------------------------------------*/
   1627 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
   1628 {
   1629 	return createSampler(wrapU, wrapV, wrapU, minFilterMode, magFilterMode);
   1630 }
   1631 
   1632 /*--------------------------------------------------------------------*//*!
   1633  * \brief Map Vulkan sampler parameters to tcu::Sampler.
   1634  *
   1635  * If no mapping is found, throws tcu::InternalError.
   1636  *
   1637  * \param wrapU			U-component wrap mode
   1638  * \param minFilterMode	Minification filter mode
   1639  * \return Sampler description.
   1640  *//*--------------------------------------------------------------------*/
   1641 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
   1642 {
   1643 	return createSampler(wrapU, wrapU, wrapU, minFilterMode, magFilterMode);
   1644 }
   1645 
   1646 TestTexture2DSp loadTexture2D (const tcu::Archive& archive, const std::vector<std::string>& filenames)
   1647 {
   1648 	DE_ASSERT(filenames.size() > 0);
   1649 
   1650 	TestTexture2DSp texture;
   1651 
   1652 	std::string ext = de::FilePath(filenames[0]).getFileExtension();
   1653 
   1654 	if (ext == "png")
   1655 	{
   1656 
   1657 		for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
   1658 		{
   1659 			tcu::TextureLevel level;
   1660 
   1661 			tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
   1662 
   1663 			TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
   1664 											   level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
   1665 
   1666 			if (fileIndex == 0)
   1667 				texture = TestTexture2DSp(new pipeline::TestTexture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
   1668 
   1669 			tcu::copy(texture->getLevel((int)fileIndex, 0), level.getAccess());
   1670 		}
   1671 	}
   1672 	else if (ext == "pkm")
   1673 	{
   1674 
   1675 		for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
   1676 		{
   1677 			// Compressed texture.
   1678 			tcu::CompressedTexture	level;
   1679 
   1680 			tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
   1681 
   1682 			tcu::TextureFormat		uncompressedFormat		= tcu::getUncompressedFormat(level.getFormat());
   1683 			std::vector<deUint8>	uncompressedData		(uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
   1684 			tcu::PixelBufferAccess	decompressedBuffer		(uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data());
   1685 
   1686 			tcu::TextureFormat		commonFormat			= tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
   1687 			std::vector<deUint8>	commonFromatData		(commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
   1688 			tcu::PixelBufferAccess	commonFormatBuffer		(commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data());
   1689 
   1690 			if (fileIndex == 0)
   1691 				texture = TestTexture2DSp(new pipeline::TestTexture2D(commonFormat, level.getWidth(), level.getHeight()));
   1692 
   1693 			level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
   1694 
   1695 			tcu::copy(commonFormatBuffer, decompressedBuffer);
   1696 			tcu::copy(texture->getLevel((int)fileIndex, 0), commonFormatBuffer);
   1697 		}
   1698 	}
   1699 	else
   1700 		TCU_FAIL("Unsupported file format");
   1701 
   1702 	return texture;
   1703 }
   1704 
   1705 TestTextureCubeSp loadTextureCube (const tcu::Archive& archive, const std::vector<std::string>& filenames)
   1706 {
   1707 	DE_ASSERT(filenames.size() > 0);
   1708 	DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
   1709 	TCU_CHECK((int)filenames.size() % tcu::CUBEFACE_LAST == 0);
   1710 
   1711 	TestTextureCubeSp texture;
   1712 
   1713 	std::string ext = de::FilePath(filenames[0]).getFileExtension();
   1714 
   1715 	if (ext == "png")
   1716 	{
   1717 
   1718 		for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
   1719 		{
   1720 			tcu::TextureLevel level;
   1721 
   1722 			tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
   1723 
   1724 			TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
   1725 											   level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
   1726 
   1727 			TCU_CHECK( level.getWidth() == level.getHeight());
   1728 
   1729 			if (fileIndex == 0)
   1730 				texture = TestTextureCubeSp(new pipeline::TestTextureCube(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth()));
   1731 
   1732 			tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), level.getAccess());
   1733 		}
   1734 	}
   1735 	else if (ext == "pkm")
   1736 	{
   1737 		for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
   1738 		{
   1739 			// Compressed texture.
   1740 			tcu::CompressedTexture	level;
   1741 
   1742 			tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
   1743 
   1744 			TCU_CHECK( level.getWidth() == level.getHeight());
   1745 
   1746 			tcu::TextureFormat		uncompressedFormat				= tcu::getUncompressedFormat(level.getFormat());
   1747 			std::vector<deUint8>	uncompressedData				(uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
   1748 			tcu::PixelBufferAccess	decompressedBuffer				(uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data());
   1749 
   1750 			tcu::TextureFormat		commonFormat					= tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
   1751 			std::vector<deUint8>	commonFromatData				(commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
   1752 			tcu::PixelBufferAccess	commonFormatBuffer				(commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data());
   1753 
   1754 			if (fileIndex == 0)
   1755 				texture = TestTextureCubeSp(new pipeline::TestTextureCube(commonFormat, level.getWidth()));
   1756 
   1757 			level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
   1758 
   1759 			tcu::copy(commonFormatBuffer, decompressedBuffer);
   1760 			tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), commonFormatBuffer);
   1761 		}
   1762 	}
   1763 	else
   1764 		TCU_FAIL("Unsupported file format");
   1765 
   1766 	return texture;
   1767 }
   1768 
   1769 TextureCommonTestCaseParameters::TextureCommonTestCaseParameters (void)
   1770 	: sampleCount			(VK_SAMPLE_COUNT_1_BIT)
   1771 	, texCoordPrecision		(glu::PRECISION_HIGHP)
   1772 	, minFilter				(tcu::Sampler::LINEAR)
   1773 	, magFilter				(tcu::Sampler::LINEAR)
   1774 	, wrapS					(tcu::Sampler::REPEAT_GL)
   1775 	, wrapT					(tcu::Sampler::REPEAT_GL)
   1776 	, format				(VK_FORMAT_R8G8B8A8_UNORM)
   1777 {
   1778 }
   1779 
   1780 Texture2DTestCaseParameters::Texture2DTestCaseParameters (void)
   1781 	: width					(64)
   1782 	, height				(64)
   1783 {
   1784 }
   1785 
   1786 TextureCubeTestCaseParameters::TextureCubeTestCaseParameters (void)
   1787 	: size					(64)
   1788 {
   1789 }
   1790 
   1791 Texture2DArrayTestCaseParameters::Texture2DArrayTestCaseParameters (void)
   1792 	: numLayers				(8)
   1793 {
   1794 }
   1795 
   1796 Texture3DTestCaseParameters::Texture3DTestCaseParameters (void)
   1797 	: wrapR					(tcu::Sampler::REPEAT_GL)
   1798 	, depth					(64)
   1799 {
   1800 }
   1801 
   1802 } // util
   1803 } // texture
   1804 } // vkt
   1805