Home | History | Annotate | Download | only in geometry
      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 
     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 
    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>
    128 inline const T* dataPointer (const std::vector<T>& vec)
    129 {
    130 	return (vec.size() != 0 ? &vec[0] : DE_NULL);
    131 }
    132 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    569 VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
    570 											 const VkAccessFlags			dstAccessMask,
    571 											 const VkImageLayout			oldLayout,
    572 											 const VkImageLayout			newLayout,
    573 											 const VkImage					image,
    574 											 const VkImageSubresourceRange	subresourceRange)
    575 {
    576 	const VkImageMemoryBarrier barrier =
    577 	{
    578 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
    579 		DE_NULL,										// const void*				pNext;
    580 		srcAccessMask,									// VkAccessFlags			outputMask;
    581 		dstAccessMask,									// VkAccessFlags			inputMask;
    582 		oldLayout,										// VkImageLayout			oldLayout;
    583 		newLayout,										// VkImageLayout			newLayout;
    584 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
    585 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
    586 		image,											// VkImage					image;
    587 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
    588 	};
    589 	return barrier;
    590 }
    591 
    592 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
    593 											   const VkAccessFlags	dstAccessMask,
    594 											   const VkBuffer		buffer,
    595 											   const VkDeviceSize	offset,
    596 											   const VkDeviceSize	bufferSizeBytes)
    597 {
    598 	const VkBufferMemoryBarrier barrier =
    599 	{
    600 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
    601 		DE_NULL,									// const void*		pNext;
    602 		srcAccessMask,								// VkAccessFlags	srcAccessMask;
    603 		dstAccessMask,								// VkAccessFlags	dstAccessMask;
    604 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
    605 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
    606 		buffer,										// VkBuffer			buffer;
    607 		offset,										// VkDeviceSize		offset;
    608 		bufferSizeBytes,							// VkDeviceSize		size;
    609 	};
    610 	return barrier;
    611 }
    612 
    613 void beginRenderPass (const DeviceInterface&	vk,
    614 					  const VkCommandBuffer		commandBuffer,
    615 					  const VkRenderPass		renderPass,
    616 					  const VkFramebuffer		framebuffer,
    617 					  const VkRect2D&			renderArea,
    618 					  const tcu::Vec4&			clearColor)
    619 {
    620 	const VkClearValue clearValue = makeClearValueColor(clearColor);
    621 
    622 	const VkRenderPassBeginInfo renderPassBeginInfo = {
    623 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
    624 		DE_NULL,										// const void*             pNext;
    625 		renderPass,										// VkRenderPass            renderPass;
    626 		framebuffer,									// VkFramebuffer           framebuffer;
    627 		renderArea,										// VkRect2D                renderArea;
    628 		1u,												// uint32_t                clearValueCount;
    629 		&clearValue,									// const VkClearValue*     pClearValues;
    630 	};
    631 
    632 	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
    633 }
    634 
    635 void endRenderPass (const DeviceInterface&	vk,
    636 					const VkCommandBuffer	commandBuffer)
    637 {
    638 	vk.cmdEndRenderPass(commandBuffer);
    639 }
    640 
    641 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
    642 {
    643 	const VkCommandBufferBeginInfo info =
    644 	{
    645 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
    646 		DE_NULL,										// const void*                              pNext;
    647 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
    648 		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
    649 	};
    650 	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
    651 }
    652 
    653 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
    654 {
    655 	VK_CHECK(vk.endCommandBuffer(commandBuffer));
    656 }
    657 
    658 void submitCommandsAndWait (const DeviceInterface&	vk,
    659 							const VkDevice			device,
    660 							const VkQueue			queue,
    661 							const VkCommandBuffer	commandBuffer)
    662 {
    663 	const Unique<VkFence> fence(createFence(vk, device));
    664 
    665 	const VkSubmitInfo submitInfo =
    666 	{
    667 		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
    668 		DE_NULL,							// const void*                    pNext;
    669 		0u,									// uint32_t                       waitSemaphoreCount;
    670 		DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
    671 		DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
    672 		1u,									// uint32_t                       commandBufferCount;
    673 		&commandBuffer,						// const VkCommandBuffer*         pCommandBuffers;
    674 		0u,									// uint32_t                       signalSemaphoreCount;
    675 		DE_NULL,							// const VkSemaphore*             pSignalSemaphores;
    676 	};
    677 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
    678 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
    679 }
    680 
    681 bool compareWithFileImage (Context& context, const tcu::ConstPixelBufferAccess& resultImage, std::string testName)
    682 {
    683 	tcu::TextureLevel referenceImage;
    684 	std::string fileName="vulkan/data/geometry/"+testName+".png";
    685 	tcu::ImageIO::loadPNG(referenceImage, context.getTestContext().getArchive(), fileName.c_str());
    686 
    687 	if (tcu::fuzzyCompare(context.getTestContext().getLog(), "ImageComparison", "Image Comparison",
    688 								referenceImage.getAccess(), resultImage, 0.001f, tcu::COMPARE_LOG_RESULT))
    689 		return tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(), "ImageComparison", "Image Comparison",
    690 														referenceImage.getAccess(), resultImage, tcu::UVec4(1u, 1u, 1u, 1u), tcu::IVec3(2,2,2), false, tcu::COMPARE_LOG_RESULT);
    691 	else
    692 		return false;
    693 }
    694 
    695 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
    696 {
    697 	de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
    698 	VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
    699 	return alloc;
    700 }
    701 
    702 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
    703 {
    704 	de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
    705 	VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
    706 	return alloc;
    707 }
    708 
    709 void zeroBuffer (const DeviceInterface& vk, const VkDevice device, const Allocation& alloc, const VkDeviceSize size)
    710 {
    711 	deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(size));
    712 	flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), size);
    713 }
    714 
    715 VkBool32 checkPointSize (const InstanceInterface& vki, const VkPhysicalDevice physDevice)
    716 {
    717 	const VkPhysicalDeviceFeatures	features	= getPhysicalDeviceFeatures  (vki, physDevice);
    718 	return features.shaderTessellationAndGeometryPointSize;
    719 }
    720 
    721 void checkGeometryShaderSupport (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const int numGeometryShaderInvocations)
    722 {
    723 	const VkPhysicalDeviceFeatures	features	= getPhysicalDeviceFeatures  (vki, physDevice);
    724 	const VkPhysicalDeviceLimits	limits		= getPhysicalDeviceProperties(vki, physDevice).limits;
    725 
    726 	if (!features.geometryShader)
    727 		TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
    728 
    729 	if (numGeometryShaderInvocations != 0 && limits.maxGeometryShaderInvocations < static_cast<deUint32>(numGeometryShaderInvocations))
    730 		TCU_THROW(NotSupportedError, ("Unsupported limit: maxGeometryShaderInvocations < " + de::toString(numGeometryShaderInvocations)).c_str());
    731 }
    732 
    733 } //geometry
    734 } //vkt
    735