1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2014 The Android Open Source Project
6  * Copyright (c) 2016 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Geometry Utilities
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktGeometryTestsUtil.hpp"
26 #include "vkTypeUtil.hpp"
27 #include "vkDefs.hpp"
28 #include "tcuImageCompare.hpp"
29 
30 #include "tcuImageIO.hpp"
31 
32 #include "deMath.h"
33 
34 using namespace vk;
35 
36 namespace vkt
37 {
38 namespace geometry
39 {
40 
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)41 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&			vk,
42 															 const VkDevice					device,
43 															 const VkShaderStageFlagBits	stage,
44 															 const ProgramBinary&			binary,
45 															 const VkSpecializationInfo*	specInfo)
46 {
47 	VkShaderModule module;
48 	switch (stage)
49 	{
50 		case (VK_SHADER_STAGE_VERTEX_BIT):
51 			DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
52 			m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
53 			module = *m_vertexShaderModule;
54 			break;
55 
56 		case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
57 			DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
58 			m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
59 			module = *m_tessControlShaderModule;
60 			break;
61 
62 		case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
63 			DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
64 			m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
65 			module = *m_tessEvaluationShaderModule;
66 			break;
67 
68 		case (VK_SHADER_STAGE_GEOMETRY_BIT):
69 			DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
70 			m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
71 			module = *m_geometryShaderModule;
72 			break;
73 
74 		case (VK_SHADER_STAGE_FRAGMENT_BIT):
75 			DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
76 			m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
77 			module = *m_fragmentShaderModule;
78 			break;
79 
80 		default:
81 			DE_FATAL("Invalid shader stage");
82 			return *this;
83 	}
84 
85 	const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
86 	{
87 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
88 		DE_NULL,												// const void*							pNext;
89 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
90 		stage,													// VkShaderStageFlagBits				stage;
91 		module,													// VkShaderModule						module;
92 		"main",													// const char*							pName;
93 		specInfo,												// const VkSpecializationInfo*			pSpecializationInfo;
94 	};
95 
96 	m_shaderStageFlags |= stage;
97 	m_shaderStages.push_back(pipelineShaderStageInfo);
98 
99 	return *this;
100 }
101 
setVertexInputSingleAttribute(const VkFormat vertexFormat,const deUint32 stride)102 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
103 {
104 	const VkVertexInputBindingDescription bindingDesc =
105 	{
106 		0u,									// uint32_t				binding;
107 		stride,								// uint32_t				stride;
108 		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
109 	};
110 	const VkVertexInputAttributeDescription attributeDesc =
111 	{
112 		0u,									// uint32_t			location;
113 		0u,									// uint32_t			binding;
114 		vertexFormat,						// VkFormat			format;
115 		0u,									// uint32_t			offset;
116 	};
117 
118 	m_vertexInputBindings.clear();
119 	m_vertexInputBindings.push_back(bindingDesc);
120 
121 	m_vertexInputAttributes.clear();
122 	m_vertexInputAttributes.push_back(attributeDesc);
123 
124 	return *this;
125 }
126 
127 template<typename T>
dataPointer(const std::vector<T> & vec)128 inline const T* dataPointer (const std::vector<T>& vec)
129 {
130 	return (vec.size() != 0 ? &vec[0] : DE_NULL);
131 }
132 
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass)133 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&	vk,
134 												 const VkDevice			device,
135 												 const VkPipelineLayout	pipelineLayout,
136 												 const VkRenderPass		renderPass)
137 {
138 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
139 	{
140 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
141 		DE_NULL,														// const void*                                 pNext;
142 		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
143 		static_cast<deUint32>(m_vertexInputBindings.size()),			// uint32_t                                    vertexBindingDescriptionCount;
144 		dataPointer(m_vertexInputBindings),								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
145 		static_cast<deUint32>(m_vertexInputAttributes.size()),			// uint32_t                                    vertexAttributeDescriptionCount;
146 		dataPointer(m_vertexInputAttributes),							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
147 	};
148 
149 	const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
150 																										 : m_primitiveTopology;
151 
152 	VkBool32	primitiveRestartEnable = VK_TRUE;
153 	switch(m_primitiveTopology)
154 	{
155 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
156 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
157 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
158 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
159 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
160 		case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
161 			primitiveRestartEnable = VK_FALSE;
162 			break;
163 		default:
164 			break;
165 	};
166 
167 	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
168 	{
169 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
170 		DE_NULL,														// const void*                                 pNext;
171 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
172 		topology,														// VkPrimitiveTopology                         topology;
173 		primitiveRestartEnable,											// VkBool32                                    primitiveRestartEnable;
174 	};
175 
176 	const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
177 	{
178 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
179 		DE_NULL,														// const void*                                 pNext;
180 		(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
181 		m_patchControlPoints,											// uint32_t                                    patchControlPoints;
182 	};
183 
184 	const VkViewport viewport = makeViewport(
185 		0.0f, 0.0f,
186 		static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
187 		0.0f, 1.0f);
188 
189 	const VkRect2D scissor = {
190 		makeOffset2D(0, 0),
191 		makeExtent2D(m_renderSize.x(), m_renderSize.y()),
192 	};
193 
194 	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
195 	{
196 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
197 		DE_NULL,												// const void*                                 pNext;
198 		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
199 		1u,														// uint32_t                                    viewportCount;
200 		&viewport,												// const VkViewport*                           pViewports;
201 		1u,														// uint32_t                                    scissorCount;
202 		&scissor,												// const VkRect2D*                             pScissors;
203 	};
204 
205 	const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
206 	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
207 	{
208 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
209 		DE_NULL,														// const void*                              pNext;
210 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
211 		VK_FALSE,														// VkBool32                                 depthClampEnable;
212 		isRasterizationDisabled,										// VkBool32                                 rasterizerDiscardEnable;
213 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
214 		m_cullModeFlags,												// VkCullModeFlags							cullMode;
215 		m_frontFace,													// VkFrontFace								frontFace;
216 		VK_FALSE,														// VkBool32									depthBiasEnable;
217 		0.0f,															// float									depthBiasConstantFactor;
218 		0.0f,															// float									depthBiasClamp;
219 		0.0f,															// float									depthBiasSlopeFactor;
220 		1.0f,															// float									lineWidth;
221 	};
222 
223 	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
224 	{
225 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
226 		DE_NULL,													// const void*								pNext;
227 		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
228 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
229 		VK_FALSE,													// VkBool32									sampleShadingEnable;
230 		0.0f,														// float									minSampleShading;
231 		DE_NULL,													// const VkSampleMask*						pSampleMask;
232 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
233 		VK_FALSE													// VkBool32									alphaToOneEnable;
234 	};
235 
236 	const VkStencilOpState stencilOpState = makeStencilOpState(
237 		VK_STENCIL_OP_KEEP,		// stencil fail
238 		VK_STENCIL_OP_KEEP,		// depth & stencil pass
239 		VK_STENCIL_OP_KEEP,		// depth only fail
240 		VK_COMPARE_OP_NEVER,	// compare op
241 		0u,						// compare mask
242 		0u,						// write mask
243 		0u);					// reference
244 
245 	const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
246 	{
247 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
248 		DE_NULL,													// const void*								pNext;
249 		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
250 		VK_FALSE,													// VkBool32									depthTestEnable;
251 		VK_FALSE,													// VkBool32									depthWriteEnable;
252 		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
253 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
254 		VK_FALSE,													// VkBool32									stencilTestEnable;
255 		stencilOpState,												// VkStencilOpState							front;
256 		stencilOpState,												// VkStencilOpState							back;
257 		0.0f,														// float									minDepthBounds;
258 		1.0f,														// float									maxDepthBounds;
259 	};
260 
261 	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
262 	const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
263 	{
264 		m_blendEnable,						// VkBool32					blendEnable;
265 		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
266 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
267 		VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
268 		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
269 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
270 		VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
271 		colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
272 	};
273 
274 	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
275 	{
276 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
277 		DE_NULL,													// const void*									pNext;
278 		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
279 		VK_FALSE,													// VkBool32										logicOpEnable;
280 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
281 		1u,															// deUint32										attachmentCount;
282 		&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
283 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
284 	};
285 
286 	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
287 	{
288 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType									sType;
289 		DE_NULL,																// const void*										pNext;
290 		(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags							flags;
291 		static_cast<deUint32>(m_shaderStages.size()),							// deUint32											stageCount;
292 		&m_shaderStages[0],														// const VkPipelineShaderStageCreateInfo*			pStages;
293 		&vertexInputStateInfo,													// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
294 		&pipelineInputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
295 		(m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*		pTessellationState;
296 		(isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo),		// const VkPipelineViewportStateCreateInfo*			pViewportState;
297 		&pipelineRasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
298 		(isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo),	// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
299 		(isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo),	// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
300 		(isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo),		// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
301 		DE_NULL,																// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
302 		pipelineLayout,															// VkPipelineLayout									layout;
303 		renderPass,																// VkRenderPass										renderPass;
304 		0u,																		// deUint32											subpass;
305 		DE_NULL,																// VkPipeline										basePipelineHandle;
306 		0,																		// deInt32											basePipelineIndex;
307 	};
308 
309 	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
310 }
311 
inputTypeToGLString(const VkPrimitiveTopology & inputType)312 std::string inputTypeToGLString (const VkPrimitiveTopology& inputType)
313 {
314 	switch (inputType)
315 	{
316 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
317 			return "points";
318 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
319 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
320 			return "lines";
321 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
322 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
323 			return "lines_adjacency";
324 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
325 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
326 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
327 			return "triangles";
328 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
329 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
330 			return "triangles_adjacency";
331 		default:
332 			DE_ASSERT(DE_FALSE);
333 			return "error";
334 	}
335 }
336 
outputTypeToGLString(const VkPrimitiveTopology & outputType)337 std::string outputTypeToGLString (const VkPrimitiveTopology& outputType)
338 {
339 	switch (outputType)
340 	{
341 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
342 			return "points";
343 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
344 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
345 				return "line_strip";
346 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
347 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
348 			return "triangle_strip";
349 		default:
350 			DE_ASSERT(DE_FALSE);
351 			return "error";
352 	}
353 }
354 
calcOutputVertices(const VkPrimitiveTopology & inputType)355 size_t calcOutputVertices (const VkPrimitiveTopology&  inputType)
356 {
357 	switch (inputType)
358 	{
359 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
360 			return 1 * 3;
361 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
362 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
363 			return 2 * 3;
364 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
365 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
366 			return 4 * 3;
367 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
368 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
369 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
370 			return 3 * 3;
371 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
372 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
373 			return 6 * 3;
374 		default:
375 			DE_ASSERT(DE_FALSE);
376 			return 0;
377 	}
378 }
379 
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)380 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
381 										 const VkBufferUsageFlags	usage)
382 {
383 	const VkBufferCreateInfo bufferCreateInfo =
384 	{
385 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
386 		DE_NULL,								// const void*			pNext;
387 		(VkBufferCreateFlags)0,					// VkBufferCreateFlags	flags;
388 		bufferSize,								// VkDeviceSize			size;
389 		usage,									// VkBufferUsageFlags	usage;
390 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
391 		0u,										// deUint32				queueFamilyIndexCount;
392 		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
393 	};
394 	return bufferCreateInfo;
395 }
396 
makeImageCreateInfo(const tcu::IVec2 & size,const VkFormat format,const VkImageUsageFlags usage,const deUint32 numArrayLayers)397 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage, const deUint32 numArrayLayers)
398 {
399 	const VkImageCreateInfo imageInfo =
400 	{
401 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
402 		DE_NULL,									// const void*              pNext;
403 		(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
404 		VK_IMAGE_TYPE_2D,							// VkImageType              imageType;
405 		format,										// VkFormat                 format;
406 		makeExtent3D(size.x(), size.y(), 1),		// VkExtent3D               extent;
407 		1u,											// uint32_t                 mipLevels;
408 		numArrayLayers,								// uint32_t                 arrayLayers;
409 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits    samples;
410 		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
411 		usage,										// VkImageUsageFlags        usage;
412 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
413 		0u,											// uint32_t                 queueFamilyIndexCount;
414 		DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
415 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
416 	};
417 	return imageInfo;
418 }
419 
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)420 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
421 										 const VkDevice					device,
422 										 const VkDescriptorPool			descriptorPool,
423 										 const VkDescriptorSetLayout	setLayout)
424 {
425 	const VkDescriptorSetAllocateInfo info =
426 	{
427 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
428 		DE_NULL,											// const void*					pNext;
429 		descriptorPool,										// VkDescriptorPool				descriptorPool;
430 		1u,													// deUint32						descriptorSetCount;
431 		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
432 	};
433 	return allocateDescriptorSet(vk, device, &info);
434 }
435 
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat)436 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, const VkDevice device, const VkFormat colorFormat)
437 {
438 	const VkAttachmentDescription colorAttachmentDescription =
439 	{
440 		(VkAttachmentDescriptionFlags)0,				// VkAttachmentDescriptionFlags		flags;
441 		colorFormat,									// VkFormat							format;
442 		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits			samples;
443 		VK_ATTACHMENT_LOAD_OP_CLEAR,					// VkAttachmentLoadOp				loadOp;
444 		VK_ATTACHMENT_STORE_OP_STORE,					// VkAttachmentStoreOp				storeOp;
445 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// VkAttachmentLoadOp				stencilLoadOp;
446 		VK_ATTACHMENT_STORE_OP_DONT_CARE,				// VkAttachmentStoreOp				stencilStoreOp;
447 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout					initialLayout;
448 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		// VkImageLayout					finalLayout;
449 	};
450 
451 	const VkAttachmentReference colorAttachmentReference =
452 	{
453 		0u,												// deUint32			attachment;
454 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		// VkImageLayout	layout;
455 	};
456 
457 	const VkAttachmentReference depthAttachmentReference =
458 	{
459 		VK_ATTACHMENT_UNUSED,							// deUint32			attachment;
460 		VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout	layout;
461 	};
462 
463 	const VkSubpassDescription subpassDescription =
464 	{
465 		(VkSubpassDescriptionFlags)0,					// VkSubpassDescriptionFlags		flags;
466 		VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint				pipelineBindPoint;
467 		0u,												// deUint32							inputAttachmentCount;
468 		DE_NULL,										// const VkAttachmentReference*		pInputAttachments;
469 		1u,												// deUint32							colorAttachmentCount;
470 		&colorAttachmentReference,						// const VkAttachmentReference*		pColorAttachments;
471 		DE_NULL,										// const VkAttachmentReference*		pResolveAttachments;
472 		&depthAttachmentReference,						// const VkAttachmentReference*		pDepthStencilAttachment;
473 		0u,												// deUint32							preserveAttachmentCount;
474 		DE_NULL											// const deUint32*					pPreserveAttachments;
475 	};
476 
477 	const VkRenderPassCreateInfo renderPassInfo =
478 	{
479 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// VkStructureType					sType;
480 		DE_NULL,										// const void*						pNext;
481 		(VkRenderPassCreateFlags)0,						// VkRenderPassCreateFlags			flags;
482 		1u,												// deUint32							attachmentCount;
483 		&colorAttachmentDescription,					// const VkAttachmentDescription*	pAttachments;
484 		1u,												// deUint32							subpassCount;
485 		&subpassDescription,							// const VkSubpassDescription*		pSubpasses;
486 		0u,												// deUint32							dependencyCount;
487 		DE_NULL											// const VkSubpassDependency*		pDependencies;
488 	};
489 
490 	return createRenderPass(vk, device, &renderPassInfo);
491 }
492 
makeImageView(const DeviceInterface & vk,const VkDevice vkDevice,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)493 Move<VkImageView> makeImageView (const DeviceInterface&			vk,
494 								 const VkDevice					vkDevice,
495 								 const VkImage					image,
496 								 const VkImageViewType			viewType,
497 								 const VkFormat					format,
498 								 const VkImageSubresourceRange	subresourceRange)
499 {
500 	const VkImageViewCreateInfo imageViewParams =
501 	{
502 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
503 		DE_NULL,									// const void*				pNext;
504 		(VkImageViewCreateFlags)0,					// VkImageViewCreateFlags	flags;
505 		image,										// VkImage					image;
506 		viewType,									// VkImageViewType			viewType;
507 		format,										// VkFormat					format;
508 		makeComponentMappingRGBA(),					// VkComponentMapping		components;
509 		subresourceRange,							// VkImageSubresourceRange	subresourceRange;
510 	};
511 	return createImageView(vk, vkDevice, &imageViewParams);
512 }
513 
makeBufferImageCopy(const VkExtent3D extent,const VkImageSubresourceLayers subresourceLayers)514 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D					extent,
515 									   const VkImageSubresourceLayers	subresourceLayers)
516 {
517 	const VkBufferImageCopy copyParams =
518 	{
519 		0ull,										//	VkDeviceSize				bufferOffset;
520 		0u,											//	deUint32					bufferRowLength;
521 		0u,											//	deUint32					bufferImageHeight;
522 		subresourceLayers,							//	VkImageSubresourceLayers	imageSubresource;
523 		makeOffset3D(0, 0, 0),						//	VkOffset3D					imageOffset;
524 		extent,										//	VkExtent3D					imageExtent;
525 	};
526 	return copyParams;
527 }
528 
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)529 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
530 										   const VkDevice				device,
531 										   const VkDescriptorSetLayout	descriptorSetLayout)
532 {
533 	const VkPipelineLayoutCreateInfo info =
534 	{
535 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,							// VkStructureType				sType;
536 		DE_NULL,																// const void*					pNext;
537 		(VkPipelineLayoutCreateFlags)0,											// VkPipelineLayoutCreateFlags	flags;
538 		(descriptorSetLayout != DE_NULL ? 1u : 0u),								// deUint32						setLayoutCount;
539 		(descriptorSetLayout != DE_NULL ? &descriptorSetLayout : DE_NULL),		// const VkDescriptorSetLayout*	pSetLayouts;
540 		0u,																		// deUint32						pushConstantRangeCount;
541 		DE_NULL,																// const VkPushConstantRange*	pPushConstantRanges;
542 	};
543 	return createPipelineLayout(vk, device, &info);
544 }
545 
makeFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const VkImageView colorAttachment,const deUint32 width,const deUint32 height,const deUint32 layers)546 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&	vk,
547 									 const VkDevice			device,
548 									 const VkRenderPass		renderPass,
549 									 const VkImageView		colorAttachment,
550 									 const deUint32			width,
551 									 const deUint32			height,
552 									 const deUint32			layers)
553 {
554 	const VkFramebufferCreateInfo framebufferInfo = {
555 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
556 		DE_NULL,										// const void*                                 pNext;
557 		(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
558 		renderPass,										// VkRenderPass                                renderPass;
559 		1u,												// uint32_t                                    attachmentCount;
560 		&colorAttachment,								// const VkImageView*                          pAttachments;
561 		width,											// uint32_t                                    width;
562 		height,											// uint32_t                                    height;
563 		layers,											// uint32_t                                    layers;
564 	};
565 
566 	return createFramebuffer(vk, device, &framebufferInfo);
567 }
568 
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)569 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
570 {
571 	const VkCommandPoolCreateInfo info =
572 	{
573 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
574 		DE_NULL,											// const void*				pNext;
575 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
576 		queueFamilyIndex,									// deUint32					queueFamilyIndex;
577 	};
578 	return createCommandPool(vk, device, &info);
579 }
580 
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)581 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
582 {
583 	const VkCommandBufferAllocateInfo info =
584 	{
585 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
586 		DE_NULL,											// const void*			pNext;
587 		commandPool,										// VkCommandPool		commandPool;
588 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
589 		1u,													// deUint32				commandBufferCount;
590 	};
591 	return allocateCommandBuffer(vk, device, &info);
592 }
593 
makeImageMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange subresourceRange)594 VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
595 											 const VkAccessFlags			dstAccessMask,
596 											 const VkImageLayout			oldLayout,
597 											 const VkImageLayout			newLayout,
598 											 const VkImage					image,
599 											 const VkImageSubresourceRange	subresourceRange)
600 {
601 	const VkImageMemoryBarrier barrier =
602 	{
603 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
604 		DE_NULL,										// const void*				pNext;
605 		srcAccessMask,									// VkAccessFlags			outputMask;
606 		dstAccessMask,									// VkAccessFlags			inputMask;
607 		oldLayout,										// VkImageLayout			oldLayout;
608 		newLayout,										// VkImageLayout			newLayout;
609 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
610 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
611 		image,											// VkImage					image;
612 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
613 	};
614 	return barrier;
615 }
616 
makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkBuffer buffer,const VkDeviceSize offset,const VkDeviceSize bufferSizeBytes)617 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
618 											   const VkAccessFlags	dstAccessMask,
619 											   const VkBuffer		buffer,
620 											   const VkDeviceSize	offset,
621 											   const VkDeviceSize	bufferSizeBytes)
622 {
623 	const VkBufferMemoryBarrier barrier =
624 	{
625 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
626 		DE_NULL,									// const void*		pNext;
627 		srcAccessMask,								// VkAccessFlags	srcAccessMask;
628 		dstAccessMask,								// VkAccessFlags	dstAccessMask;
629 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
630 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
631 		buffer,										// VkBuffer			buffer;
632 		offset,										// VkDeviceSize		offset;
633 		bufferSizeBytes,							// VkDeviceSize		size;
634 	};
635 	return barrier;
636 }
637 
beginRenderPass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor)638 void beginRenderPass (const DeviceInterface&	vk,
639 					  const VkCommandBuffer		commandBuffer,
640 					  const VkRenderPass		renderPass,
641 					  const VkFramebuffer		framebuffer,
642 					  const VkRect2D&			renderArea,
643 					  const tcu::Vec4&			clearColor)
644 {
645 	const VkClearValue clearValue = makeClearValueColor(clearColor);
646 
647 	const VkRenderPassBeginInfo renderPassBeginInfo = {
648 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
649 		DE_NULL,										// const void*             pNext;
650 		renderPass,										// VkRenderPass            renderPass;
651 		framebuffer,									// VkFramebuffer           framebuffer;
652 		renderArea,										// VkRect2D                renderArea;
653 		1u,												// uint32_t                clearValueCount;
654 		&clearValue,									// const VkClearValue*     pClearValues;
655 	};
656 
657 	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
658 }
659 
endRenderPass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)660 void endRenderPass (const DeviceInterface&	vk,
661 					const VkCommandBuffer	commandBuffer)
662 {
663 	vk.cmdEndRenderPass(commandBuffer);
664 }
665 
beginCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)666 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
667 {
668 	const VkCommandBufferBeginInfo info =
669 	{
670 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
671 		DE_NULL,										// const void*                              pNext;
672 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
673 		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
674 	};
675 	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
676 }
677 
endCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)678 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
679 {
680 	VK_CHECK(vk.endCommandBuffer(commandBuffer));
681 }
682 
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer)683 void submitCommandsAndWait (const DeviceInterface&	vk,
684 							const VkDevice			device,
685 							const VkQueue			queue,
686 							const VkCommandBuffer	commandBuffer)
687 {
688 	const VkFenceCreateInfo fenceInfo =
689 	{
690 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
691 		DE_NULL,								// const void*			pNext;
692 		(VkFenceCreateFlags)0,					// VkFenceCreateFlags	flags;
693 	};
694 	const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
695 
696 	const VkSubmitInfo submitInfo =
697 	{
698 		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
699 		DE_NULL,							// const void*                    pNext;
700 		0u,									// uint32_t                       waitSemaphoreCount;
701 		DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
702 		DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
703 		1u,									// uint32_t                       commandBufferCount;
704 		&commandBuffer,						// const VkCommandBuffer*         pCommandBuffers;
705 		0u,									// uint32_t                       signalSemaphoreCount;
706 		DE_NULL,							// const VkSemaphore*             pSignalSemaphores;
707 	};
708 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
709 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
710 }
711 
compareWithFileImage(Context & context,const tcu::ConstPixelBufferAccess & resultImage,std::string testName)712 bool compareWithFileImage (Context& context, const tcu::ConstPixelBufferAccess& resultImage, std::string testName)
713 {
714 	tcu::TextureLevel referenceImage;
715 	std::string fileName="vulkan/data/geometry/"+testName+".png";
716 	tcu::ImageIO::loadPNG(referenceImage, context.getTestContext().getArchive(), fileName.c_str());
717 
718 	if (tcu::fuzzyCompare(context.getTestContext().getLog(), "ImageComparison", "Image Comparison",
719 								referenceImage.getAccess(), resultImage, 0.001f, tcu::COMPARE_LOG_RESULT))
720 		return tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(), "ImageComparison", "Image Comparison",
721 														referenceImage.getAccess(), resultImage, tcu::UVec4(1u, 1u, 1u, 1u), tcu::IVec3(2,2,2), false, tcu::COMPARE_LOG_RESULT);
722 	else
723 		return false;
724 }
725 
bindImage(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkImage image,const MemoryRequirement requirement)726 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
727 {
728 	de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
729 	VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
730 	return alloc;
731 }
732 
bindBuffer(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkBuffer buffer,const MemoryRequirement requirement)733 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
734 {
735 	de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
736 	VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
737 	return alloc;
738 }
739 
zeroBuffer(const DeviceInterface & vk,const VkDevice device,const Allocation & alloc,const VkDeviceSize size)740 void zeroBuffer (const DeviceInterface& vk, const VkDevice device, const Allocation& alloc, const VkDeviceSize size)
741 {
742 	deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(size));
743 	flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), size);
744 }
745 
checkPointSize(const InstanceInterface & vki,const VkPhysicalDevice physDevice)746 VkBool32 checkPointSize (const InstanceInterface& vki, const VkPhysicalDevice physDevice)
747 {
748 	const VkPhysicalDeviceFeatures	features	= getPhysicalDeviceFeatures  (vki, physDevice);
749 	return features.shaderTessellationAndGeometryPointSize;
750 }
751 
checkGeometryShaderSupport(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const int numGeometryShaderInvocations)752 void checkGeometryShaderSupport (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const int numGeometryShaderInvocations)
753 {
754 	const VkPhysicalDeviceFeatures	features	= getPhysicalDeviceFeatures  (vki, physDevice);
755 	const VkPhysicalDeviceLimits	limits		= getPhysicalDeviceProperties(vki, physDevice).limits;
756 
757 	if (!features.geometryShader)
758 		TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
759 
760 	if (numGeometryShaderInvocations != 0 && limits.maxGeometryShaderInvocations < static_cast<deUint32>(numGeometryShaderInvocations))
761 		TCU_THROW(NotSupportedError, ("Unsupported limit: maxGeometryShaderInvocations < " + de::toString(numGeometryShaderInvocations)).c_str());
762 }
763 
764 } //geometry
765 } //vkt
766