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