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