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