Home | History | Annotate | Download | only in vulkan
      1 /*-------------------------------------------------------------------------
      2  * Vulkan CTS Framework
      3  * --------------------
      4  *
      5  * Copyright (c) 2018 Google Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Utilities for creating commonly used Vulkan objects
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vkDefs.hpp"
     25 #include "vkRefUtil.hpp"
     26 #include "vkImageUtil.hpp"
     27 #include "vkObjUtil.hpp"
     28 #include "tcuVector.hpp"
     29 
     30 namespace vk
     31 {
     32 
     33 Move<VkPipeline> makeGraphicsPipeline(const DeviceInterface&						vk,
     34 									  const VkDevice								device,
     35 									  const VkPipelineLayout						pipelineLayout,
     36 									  const VkShaderModule							vertexShaderModule,
     37 									  const VkShaderModule							tessellationControlShaderModule,
     38 									  const VkShaderModule							tessellationEvalShaderModule,
     39 									  const VkShaderModule							geometryShaderModule,
     40 									  const VkShaderModule							fragmentShaderModule,
     41 									  const VkRenderPass							renderPass,
     42 									  const std::vector<VkViewport>&				viewports,
     43 									  const std::vector<VkRect2D>&					scissors,
     44 									  const VkPrimitiveTopology						topology,
     45 									  const deUint32								subpass,
     46 									  const deUint32								patchControlPoints,
     47 									  const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo,
     48 									  const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo,
     49 									  const VkPipelineMultisampleStateCreateInfo*	multisampleStateCreateInfo,
     50 									  const VkPipelineDepthStencilStateCreateInfo*	depthStencilStateCreateInfo,
     51 									  const VkPipelineColorBlendStateCreateInfo*	colorBlendStateCreateInfo,
     52 									  const VkPipelineDynamicStateCreateInfo*		dynamicStateCreateInfo)
     53 {
     54 	const VkBool32									disableRasterization				= (fragmentShaderModule == DE_NULL);
     55 	const bool										hasTessellation						= (tessellationControlShaderModule != DE_NULL || tessellationEvalShaderModule != DE_NULL);
     56 
     57 	VkPipelineShaderStageCreateInfo					stageCreateInfo						=
     58 	{
     59 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType
     60 		DE_NULL,												// const void*                         pNext
     61 		0u,														// VkPipelineShaderStageCreateFlags    flags
     62 		VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits               stage
     63 		DE_NULL,												// VkShaderModule                      module
     64 		"main",													// const char*                         pName
     65 		DE_NULL													// const VkSpecializationInfo*         pSpecializationInfo
     66 	};
     67 
     68 	std::vector<VkPipelineShaderStageCreateInfo>	pipelineShaderStageParams;
     69 
     70 	{
     71 		stageCreateInfo.stage	= VK_SHADER_STAGE_VERTEX_BIT;
     72 		stageCreateInfo.module	= vertexShaderModule;
     73 		pipelineShaderStageParams.push_back(stageCreateInfo);
     74 	}
     75 
     76 	if (tessellationControlShaderModule != DE_NULL)
     77 	{
     78 		stageCreateInfo.stage	= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
     79 		stageCreateInfo.module	= tessellationControlShaderModule;
     80 		pipelineShaderStageParams.push_back(stageCreateInfo);
     81 	}
     82 
     83 	if (tessellationEvalShaderModule != DE_NULL)
     84 	{
     85 		stageCreateInfo.stage	= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
     86 		stageCreateInfo.module	= tessellationEvalShaderModule;
     87 		pipelineShaderStageParams.push_back(stageCreateInfo);
     88 	}
     89 
     90 	if (geometryShaderModule != DE_NULL)
     91 	{
     92 		stageCreateInfo.stage	= VK_SHADER_STAGE_GEOMETRY_BIT;
     93 		stageCreateInfo.module	= geometryShaderModule;
     94 		pipelineShaderStageParams.push_back(stageCreateInfo);
     95 	}
     96 
     97 	if (fragmentShaderModule != DE_NULL)
     98 	{
     99 		stageCreateInfo.stage	= VK_SHADER_STAGE_FRAGMENT_BIT;
    100 		stageCreateInfo.module	= fragmentShaderModule;
    101 		pipelineShaderStageParams.push_back(stageCreateInfo);
    102 	}
    103 
    104 	const VkVertexInputBindingDescription			vertexInputBindingDescription		=
    105 	{
    106 		0u,								// deUint32             binding
    107 		sizeof(tcu::Vec4),				// deUint32             stride
    108 		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate    inputRate
    109 	};
    110 
    111 	const VkVertexInputAttributeDescription			vertexInputAttributeDescription		=
    112 	{
    113 		0u,								// deUint32    location
    114 		0u,								// deUint32    binding
    115 		VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat    format
    116 		0u								// deUint32    offset
    117 	};
    118 
    119 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfoDefault	=
    120 	{
    121 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType
    122 		DE_NULL,													// const void*                                 pNext
    123 		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags
    124 		1u,															// deUint32                                    vertexBindingDescriptionCount
    125 		&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions
    126 		1u,															// deUint32                                    vertexAttributeDescriptionCount
    127 		&vertexInputAttributeDescription							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
    128 	};
    129 
    130 	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateCreateInfo		=
    131 	{
    132 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                            sType
    133 		DE_NULL,														// const void*                                pNext
    134 		0u,																// VkPipelineInputAssemblyStateCreateFlags    flags
    135 		topology,														// VkPrimitiveTopology                        topology
    136 		VK_FALSE														// VkBool32                                   primitiveRestartEnable
    137 	};
    138 
    139 	const VkPipelineTessellationStateCreateInfo		tessStateCreateInfo					=
    140 	{
    141 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	// VkStructureType                           sType
    142 		DE_NULL,													// const void*                               pNext
    143 		0u,															// VkPipelineTessellationStateCreateFlags    flags
    144 		patchControlPoints											// deUint32                                  patchControlPoints
    145 	};
    146 
    147 	const VkPipelineViewportStateCreateInfo			viewportStateCreateInfo				=
    148 	{
    149 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType
    150 		DE_NULL,												// const void*                                 pNext
    151 		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags
    152 		viewports.empty() ? 1u : (deUint32)viewports.size(),	// deUint32                                    viewportCount
    153 		viewports.empty() ? DE_NULL : &viewports[0],			// const VkViewport*                           pViewports
    154 		viewports.empty() ? 1u : (deUint32)scissors.size(),		// deUint32                                    scissorCount
    155 		scissors.empty() ? DE_NULL : &scissors[0]				// const VkRect2D*                             pScissors
    156 	};
    157 
    158 	const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfoDefault	=
    159 	{
    160 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType                            sType
    161 		DE_NULL,													// const void*                                pNext
    162 		0u,															// VkPipelineRasterizationStateCreateFlags    flags
    163 		VK_FALSE,													// VkBool32                                   depthClampEnable
    164 		disableRasterization,										// VkBool32                                   rasterizerDiscardEnable
    165 		VK_POLYGON_MODE_FILL,										// VkPolygonMode                              polygonMode
    166 		VK_CULL_MODE_NONE,											// VkCullModeFlags                            cullMode
    167 		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace                                frontFace
    168 		VK_FALSE,													// VkBool32                                   depthBiasEnable
    169 		0.0f,														// float                                      depthBiasConstantFactor
    170 		0.0f,														// float                                      depthBiasClamp
    171 		0.0f,														// float                                      depthBiasSlopeFactor
    172 		1.0f														// float                                      lineWidth
    173 	};
    174 
    175 	const VkPipelineMultisampleStateCreateInfo		multisampleStateCreateInfoDefault	=
    176 	{
    177 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType                          sType
    178 		DE_NULL,													// const void*                              pNext
    179 		0u,															// VkPipelineMultisampleStateCreateFlags    flags
    180 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits                    rasterizationSamples
    181 		VK_FALSE,													// VkBool32                                 sampleShadingEnable
    182 		1.0f,														// float                                    minSampleShading
    183 		DE_NULL,													// const VkSampleMask*                      pSampleMask
    184 		VK_FALSE,													// VkBool32                                 alphaToCoverageEnable
    185 		VK_FALSE													// VkBool32                                 alphaToOneEnable
    186 	};
    187 
    188 	const VkStencilOpState							stencilOpState						=
    189 	{
    190 		VK_STENCIL_OP_KEEP,		// VkStencilOp    failOp
    191 		VK_STENCIL_OP_KEEP,		// VkStencilOp    passOp
    192 		VK_STENCIL_OP_KEEP,		// VkStencilOp    depthFailOp
    193 		VK_COMPARE_OP_NEVER,	// VkCompareOp    compareOp
    194 		0,						// deUint32       compareMask
    195 		0,						// deUint32       writeMask
    196 		0						// deUint32       reference
    197 	};
    198 
    199 	const VkPipelineDepthStencilStateCreateInfo		depthStencilStateCreateInfoDefault	=
    200 	{
    201 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType                          sType
    202 		DE_NULL,													// const void*                              pNext
    203 		0u,															// VkPipelineDepthStencilStateCreateFlags   flags
    204 		VK_FALSE,													// VkBool32                                 depthTestEnable
    205 		VK_FALSE,													// VkBool32                                 depthWriteEnable
    206 		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp                              depthCompareOp
    207 		VK_FALSE,													// VkBool32                                 depthBoundsTestEnable
    208 		VK_FALSE,													// VkBool32                                 stencilTestEnable
    209 		stencilOpState,												// VkStencilOpState                         front
    210 		stencilOpState,												// VkStencilOpState                         back
    211 		0.0f,														// float                                    minDepthBounds
    212 		1.0f,														// float                                    maxDepthBounds
    213 	};
    214 
    215 	const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState			=
    216 	{
    217 		VK_FALSE,					// VkBool32                 blendEnable
    218 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            srcColorBlendFactor
    219 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            dstColorBlendFactor
    220 		VK_BLEND_OP_ADD,			// VkBlendOp                colorBlendOp
    221 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            srcAlphaBlendFactor
    222 		VK_BLEND_FACTOR_ZERO,		// VkBlendFactor            dstAlphaBlendFactor
    223 		VK_BLEND_OP_ADD,			// VkBlendOp                alphaBlendOp
    224 		VK_COLOR_COMPONENT_R_BIT	// VkColorComponentFlags    colorWriteMask
    225 		| VK_COLOR_COMPONENT_G_BIT
    226 		| VK_COLOR_COMPONENT_B_BIT
    227 		| VK_COLOR_COMPONENT_A_BIT
    228 	};
    229 
    230 	const VkPipelineColorBlendStateCreateInfo		colorBlendStateCreateInfoDefault	=
    231 	{
    232 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType                               sType
    233 		DE_NULL,													// const void*                                   pNext
    234 		0u,															// VkPipelineColorBlendStateCreateFlags          flags
    235 		VK_FALSE,													// VkBool32                                      logicOpEnable
    236 		VK_LOGIC_OP_CLEAR,											// VkLogicOp                                     logicOp
    237 		1u,															// deUint32                                      attachmentCount
    238 		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*    pAttachments
    239 		{ 0.0f, 0.0f, 0.0f, 0.0f }									// float                                         blendConstants[4]
    240 	};
    241 
    242 	std::vector<VkDynamicState>						dynamicStates;
    243 
    244 	if (viewports.empty())
    245 		dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
    246 	if (scissors.empty())
    247 		dynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR);
    248 
    249 	const VkPipelineDynamicStateCreateInfo			dynamicStateCreateInfoDefault		=
    250 	{
    251 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType                      sType
    252 		DE_NULL,												// const void*                          pNext
    253 		0u,														// VkPipelineDynamicStateCreateFlags    flags
    254 		(deUint32)dynamicStates.size(),							// deUint32                             dynamicStateCount
    255 		dynamicStates.empty() ? DE_NULL : &dynamicStates[0]		// const VkDynamicState*                pDynamicStates
    256 	};
    257 
    258 	const VkPipelineDynamicStateCreateInfo*			dynamicStateCreateInfoDefaultPtr	= dynamicStates.empty() ? DE_NULL : &dynamicStateCreateInfoDefault;
    259 
    260 	const VkGraphicsPipelineCreateInfo				pipelineCreateInfo					=
    261 	{
    262 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,														// VkStructureType                                  sType
    263 		DE_NULL,																								// const void*                                      pNext
    264 		0u,																										// VkPipelineCreateFlags                            flags
    265 		(deUint32)pipelineShaderStageParams.size(),																// deUint32                                         stageCount
    266 		&pipelineShaderStageParams[0],																			// const VkPipelineShaderStageCreateInfo*           pStages
    267 		vertexInputStateCreateInfo ? vertexInputStateCreateInfo : &vertexInputStateCreateInfoDefault,			// const VkPipelineVertexInputStateCreateInfo*      pVertexInputState
    268 		&inputAssemblyStateCreateInfo,																			// const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState
    269 		hasTessellation ? &tessStateCreateInfo : DE_NULL,														// const VkPipelineTessellationStateCreateInfo*     pTessellationState
    270 		&viewportStateCreateInfo,																				// const VkPipelineViewportStateCreateInfo*         pViewportState
    271 		rasterizationStateCreateInfo ? rasterizationStateCreateInfo : &rasterizationStateCreateInfoDefault,		// const VkPipelineRasterizationStateCreateInfo*    pRasterizationState
    272 		multisampleStateCreateInfo ? multisampleStateCreateInfo: &multisampleStateCreateInfoDefault,			// const VkPipelineMultisampleStateCreateInfo*      pMultisampleState
    273 		depthStencilStateCreateInfo ? depthStencilStateCreateInfo : &depthStencilStateCreateInfoDefault,		// const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState
    274 		colorBlendStateCreateInfo ? colorBlendStateCreateInfo : &colorBlendStateCreateInfoDefault,				// const VkPipelineColorBlendStateCreateInfo*       pColorBlendState
    275 		dynamicStateCreateInfo ? dynamicStateCreateInfo : dynamicStateCreateInfoDefaultPtr,						// const VkPipelineDynamicStateCreateInfo*          pDynamicState
    276 		pipelineLayout,																							// VkPipelineLayout                                 layout
    277 		renderPass,																								// VkRenderPass                                     renderPass
    278 		subpass,																								// deUint32                                         subpass
    279 		DE_NULL,																								// VkPipeline                                       basePipelineHandle
    280 		0																										// deInt32                                          basePipelineIndex;
    281 	};
    282 
    283 	return createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
    284 }
    285 
    286 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&							vk,
    287 									   const VkDevice									device,
    288 									   const VkPipelineLayout							pipelineLayout,
    289 									   const VkShaderModule								vertexShaderModule,
    290 									   const VkShaderModule								tessellationControlShaderModule,
    291 									   const VkShaderModule								tessellationEvalShaderModule,
    292 									   const VkShaderModule								geometryShaderModule,
    293 									   const VkShaderModule								fragmentShaderModule,
    294 									   const VkRenderPass								renderPass,
    295 									   const deUint32									subpass,
    296 									   const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo,
    297 									   const VkPipelineInputAssemblyStateCreateInfo*	inputAssemblyStateCreateInfo,
    298 									   const VkPipelineTessellationStateCreateInfo*		tessStateCreateInfo,
    299 									   const VkPipelineViewportStateCreateInfo*			viewportStateCreateInfo,
    300 									   const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo,
    301 									   const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo,
    302 									   const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo,
    303 									   const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo,
    304 									   const VkPipelineDynamicStateCreateInfo*			dynamicStateCreateInfo)
    305 {
    306 	VkPipelineShaderStageCreateInfo					stageCreateInfo		=
    307 	{
    308 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType
    309 		DE_NULL,												// const void*                         pNext
    310 		0u,														// VkPipelineShaderStageCreateFlags    flags
    311 		VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits               stage
    312 		DE_NULL,												// VkShaderModule                      module
    313 		"main",													// const char*                         pName
    314 		DE_NULL													// const VkSpecializationInfo*         pSpecializationInfo
    315 	};
    316 
    317 	std::vector<VkPipelineShaderStageCreateInfo>	pipelineShaderStageParams;
    318 
    319 	{
    320 		stageCreateInfo.stage	= VK_SHADER_STAGE_VERTEX_BIT;
    321 		stageCreateInfo.module	= vertexShaderModule;
    322 		pipelineShaderStageParams.push_back(stageCreateInfo);
    323 	}
    324 
    325 	if (tessellationControlShaderModule != DE_NULL)
    326 	{
    327 		stageCreateInfo.stage	= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
    328 		stageCreateInfo.module	= tessellationControlShaderModule;
    329 		pipelineShaderStageParams.push_back(stageCreateInfo);
    330 	}
    331 
    332 	if (tessellationEvalShaderModule != DE_NULL)
    333 	{
    334 		stageCreateInfo.stage	= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
    335 		stageCreateInfo.module	= tessellationEvalShaderModule;
    336 		pipelineShaderStageParams.push_back(stageCreateInfo);
    337 	}
    338 
    339 	if (geometryShaderModule != DE_NULL)
    340 	{
    341 		stageCreateInfo.stage	= VK_SHADER_STAGE_GEOMETRY_BIT;
    342 		stageCreateInfo.module	= geometryShaderModule;
    343 		pipelineShaderStageParams.push_back(stageCreateInfo);
    344 	}
    345 
    346 	if (fragmentShaderModule != DE_NULL)
    347 	{
    348 		stageCreateInfo.stage	= VK_SHADER_STAGE_FRAGMENT_BIT;
    349 		stageCreateInfo.module	= fragmentShaderModule;
    350 		pipelineShaderStageParams.push_back(stageCreateInfo);
    351 	}
    352 
    353 	const VkGraphicsPipelineCreateInfo				pipelineCreateInfo	=
    354 	{
    355 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType                                  sType
    356 		DE_NULL,											// const void*                                      pNext
    357 		0u,													// VkPipelineCreateFlags                            flags
    358 		(deUint32)pipelineShaderStageParams.size(),			// deUint32                                         stageCount
    359 		&pipelineShaderStageParams[0],						// const VkPipelineShaderStageCreateInfo*           pStages
    360 		vertexInputStateCreateInfo,							// const VkPipelineVertexInputStateCreateInfo*      pVertexInputState
    361 		inputAssemblyStateCreateInfo,						// const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState
    362 		tessStateCreateInfo,								// const VkPipelineTessellationStateCreateInfo*     pTessellationState
    363 		viewportStateCreateInfo,							// const VkPipelineViewportStateCreateInfo*         pViewportState
    364 		rasterizationStateCreateInfo,						// const VkPipelineRasterizationStateCreateInfo*    pRasterizationState
    365 		multisampleStateCreateInfo,							// const VkPipelineMultisampleStateCreateInfo*      pMultisampleState
    366 		depthStencilStateCreateInfo,						// const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState
    367 		colorBlendStateCreateInfo,							// const VkPipelineColorBlendStateCreateInfo*       pColorBlendState
    368 		dynamicStateCreateInfo,								// const VkPipelineDynamicStateCreateInfo*          pDynamicState
    369 		pipelineLayout,										// VkPipelineLayout                                 layout
    370 		renderPass,											// VkRenderPass                                     renderPass
    371 		subpass,											// deUint32                                         subpass
    372 		DE_NULL,											// VkPipeline                                       basePipelineHandle
    373 		0													// deInt32                                          basePipelineIndex;
    374 	};
    375 
    376 	return createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
    377 }
    378 
    379 Move<VkRenderPass> makeRenderPass (const DeviceInterface&				vk,
    380 								   const VkDevice						device,
    381 								   const VkFormat						colorFormat,
    382 								   const VkFormat						depthStencilFormat,
    383 								   const VkAttachmentLoadOp				loadOperation,
    384 								   const VkImageLayout					finalLayoutColor,
    385 								   const VkImageLayout					finalLayoutDepthStencil,
    386 								   const VkImageLayout					subpassLayoutColor,
    387 								   const VkImageLayout					subpassLayoutDepthStencil,
    388 								   const VkAllocationCallbacks* const	allocationCallbacks)
    389 {
    390 	const bool								hasColor							= colorFormat != VK_FORMAT_UNDEFINED;
    391 	const bool								hasDepthStencil						= depthStencilFormat != VK_FORMAT_UNDEFINED;
    392 	const VkImageLayout						initialLayoutColor					= loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
    393 	const VkImageLayout						initialLayoutDepthStencil			= loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
    394 
    395 	const VkAttachmentDescription			colorAttachmentDescription			=
    396 	{
    397 		(VkAttachmentDescriptionFlags)0,	// VkAttachmentDescriptionFlags    flags
    398 		colorFormat,						// VkFormat                        format
    399 		VK_SAMPLE_COUNT_1_BIT,				// VkSampleCountFlagBits           samples
    400 		loadOperation,						// VkAttachmentLoadOp              loadOp
    401 		VK_ATTACHMENT_STORE_OP_STORE,		// VkAttachmentStoreOp             storeOp
    402 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	// VkAttachmentLoadOp              stencilLoadOp
    403 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	// VkAttachmentStoreOp             stencilStoreOp
    404 		initialLayoutColor,					// VkImageLayout                   initialLayout
    405 		finalLayoutColor					// VkImageLayout                   finalLayout
    406 	};
    407 
    408 	const VkAttachmentDescription			depthStencilAttachmentDescription	=
    409 	{
    410 		(VkAttachmentDescriptionFlags)0,	// VkAttachmentDescriptionFlags    flags
    411 		depthStencilFormat,					// VkFormat                        format
    412 		VK_SAMPLE_COUNT_1_BIT,				// VkSampleCountFlagBits           samples
    413 		loadOperation,						// VkAttachmentLoadOp              loadOp
    414 		VK_ATTACHMENT_STORE_OP_STORE,		// VkAttachmentStoreOp             storeOp
    415 		loadOperation,						// VkAttachmentLoadOp              stencilLoadOp
    416 		VK_ATTACHMENT_STORE_OP_STORE,		// VkAttachmentStoreOp             stencilStoreOp
    417 		initialLayoutDepthStencil,			// VkImageLayout                   initialLayout
    418 		finalLayoutDepthStencil				// VkImageLayout                   finalLayout
    419 	};
    420 
    421 	std::vector<VkAttachmentDescription>	attachmentDescriptions;
    422 
    423 	if (hasColor)
    424 		attachmentDescriptions.push_back(colorAttachmentDescription);
    425 	if (hasDepthStencil)
    426 		attachmentDescriptions.push_back(depthStencilAttachmentDescription);
    427 
    428 	const VkAttachmentReference				colorAttachmentRef					=
    429 	{
    430 		0u,					// deUint32         attachment
    431 		subpassLayoutColor	// VkImageLayout    layout
    432 	};
    433 
    434 	const VkAttachmentReference				depthStencilAttachmentRef			=
    435 	{
    436 		hasColor ? 1u : 0u,			// deUint32         attachment
    437 		subpassLayoutDepthStencil	// VkImageLayout    layout
    438 	};
    439 
    440 	const VkSubpassDescription				subpassDescription					=
    441 	{
    442 		(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags       flags
    443 		VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint             pipelineBindPoint
    444 		0u,														// deUint32                        inputAttachmentCount
    445 		DE_NULL,												// const VkAttachmentReference*    pInputAttachments
    446 		hasColor ? 1u : 0u,										// deUint32                        colorAttachmentCount
    447 		hasColor ? &colorAttachmentRef : DE_NULL,				// const VkAttachmentReference*    pColorAttachments
    448 		DE_NULL,												// const VkAttachmentReference*    pResolveAttachments
    449 		hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL,	// const VkAttachmentReference*    pDepthStencilAttachment
    450 		0u,														// deUint32                        preserveAttachmentCount
    451 		DE_NULL													// const deUint32*                 pPreserveAttachments
    452 	};
    453 
    454 	const VkRenderPassCreateInfo			renderPassInfo						=
    455 	{
    456 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType                   sType
    457 		DE_NULL,									// const void*                       pNext
    458 		(VkRenderPassCreateFlags)0,					// VkRenderPassCreateFlags           flags
    459 		(deUint32)attachmentDescriptions.size(),	// deUint32                          attachmentCount
    460 		&attachmentDescriptions[0],					// const VkAttachmentDescription*    pAttachments
    461 		1u,											// deUint32                          subpassCount
    462 		&subpassDescription,						// const VkSubpassDescription*       pSubpasses
    463 		0u,											// deUint32                          dependencyCount
    464 		DE_NULL										// const VkSubpassDependency*        pDependencies
    465 	};
    466 
    467 	return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
    468 }
    469 
    470 } // vk
    471