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