Home | History | Annotate | Download | only in renderpass
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2018 The Khronos Group 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 VK_KHR_depth_stencil_resolve tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktRenderPassDepthStencilResolveTests.hpp"
     25 #include "vktRenderPassTestsUtil.hpp"
     26 
     27 #include "vktTestCaseUtil.hpp"
     28 #include "vktTestGroupUtil.hpp"
     29 
     30 #include "vkDefs.hpp"
     31 #include "vkDeviceUtil.hpp"
     32 #include "vkImageUtil.hpp"
     33 #include "vkMemUtil.hpp"
     34 #include "vkPlatform.hpp"
     35 #include "vkPrograms.hpp"
     36 #include "vkQueryUtil.hpp"
     37 #include "vkRef.hpp"
     38 #include "vkRefUtil.hpp"
     39 #include "vkTypeUtil.hpp"
     40 #include "vkCmdUtil.hpp"
     41 #include "vkObjUtil.hpp"
     42 
     43 #include "tcuImageCompare.hpp"
     44 #include "tcuFormatUtil.hpp"
     45 #include "tcuResultCollector.hpp"
     46 #include "tcuTestLog.hpp"
     47 #include "tcuTextureUtil.hpp"
     48 
     49 #include "deUniquePtr.hpp"
     50 #include "deSharedPtr.hpp"
     51 #include "deMath.h"
     52 #include <limits>
     53 
     54 using namespace vk;
     55 
     56 using tcu::Vec4;
     57 using tcu::TestLog;
     58 
     59 typedef de::SharedPtr<vk::Unique<VkImage> >		VkImageSp;
     60 typedef de::SharedPtr<vk::Unique<VkImageView> >	VkImageViewSp;
     61 typedef de::SharedPtr<vk::Unique<VkBuffer> >	VkBufferSp;
     62 typedef de::SharedPtr<vk::Unique<VkPipeline> >	VkPipelineSp;
     63 typedef de::SharedPtr<Allocation>				AllocationSp;
     64 
     65 namespace vkt
     66 {
     67 namespace
     68 {
     69 
     70 using namespace renderpass;
     71 
     72 template<typename T>
     73 de::SharedPtr<T> safeSharedPtr (T* ptr)
     74 {
     75 	try
     76 	{
     77 		return de::SharedPtr<T>(ptr);
     78 	}
     79 	catch (...)
     80 	{
     81 		delete ptr;
     82 		throw;
     83 	}
     84 }
     85 
     86 enum VerifyBuffer
     87 {
     88 	VB_DEPTH = 0,
     89 	VB_STENCIL
     90 };
     91 
     92 struct TestConfig
     93 {
     94 	VkFormat					format;
     95 	deUint32					width;
     96 	deUint32					height;
     97 	deUint32					imageLayers;
     98 	deUint32					viewLayers;
     99 	deUint32					resolveBaseLayer;
    100 	VkRect2D					renderArea;
    101 	VkImageAspectFlags			aspectFlag;
    102 	deUint32					sampleCount;
    103 	VkResolveModeFlagBitsKHR	depthResolveMode;
    104 	VkResolveModeFlagBitsKHR	stencilResolveMode;
    105 	VerifyBuffer				verifyBuffer;
    106 	VkClearDepthStencilValue	clearValue;
    107 	float						depthExpectedValue;
    108 	deUint8						stencilExpectedValue;
    109 };
    110 
    111 float get16bitDepthComponent(deUint8* pixelPtr)
    112 {
    113 	deUint16* value = reinterpret_cast<deUint16*>(pixelPtr);
    114 	return static_cast<float>(*value) / 65535.0f;
    115 }
    116 
    117 float get24bitDepthComponent(deUint8* pixelPtr)
    118 {
    119 	const bool littleEndian = (DE_ENDIANNESS == DE_LITTLE_ENDIAN);
    120 	deUint32 value = (((deUint32)pixelPtr[0]) << (!littleEndian * 16u)) |
    121 						(((deUint32)pixelPtr[1]) <<  8u) |
    122 						(((deUint32)pixelPtr[2]) << ( littleEndian * 16u));
    123 	return static_cast<float>(value) / 16777215.0f;
    124 }
    125 
    126 float get32bitDepthComponent(deUint8* pixelPtr)
    127 {
    128 	return *(reinterpret_cast<float*>(pixelPtr));
    129 }
    130 
    131 class DepthStencilResolveTest : public TestInstance
    132 {
    133 public:
    134 								DepthStencilResolveTest		(Context& context, TestConfig config);
    135 	virtual						~DepthStencilResolveTest	(void);
    136 
    137 	virtual tcu::TestStatus		iterate (void);
    138 
    139 protected:
    140 	bool						isFeaturesSupported				(void);
    141 	VkSampleCountFlagBits		sampleCountBitFromSampleCount	(deUint32 count) const;
    142 
    143 	VkImageSp					createImage						(deUint32 sampleCount, VkImageUsageFlags additionalUsage = 0u);
    144 	AllocationSp				createImageMemory				(VkImageSp image);
    145 	VkImageViewSp				createImageView					(VkImageSp image, deUint32 baseArrayLayer);
    146 	AllocationSp				createBufferMemory				(void);
    147 	VkBufferSp					createBuffer					(void);
    148 
    149 	Move<VkRenderPass>			createRenderPass				(void);
    150 	Move<VkFramebuffer>			createFramebuffer				(VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView);
    151 	Move<VkPipelineLayout>		createRenderPipelineLayout		(void);
    152 	Move<VkPipeline>			createRenderPipeline			(VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout);
    153 
    154 	void						submit							(void);
    155 	bool						verifyDepth						(void);
    156 	bool						verifyStencil					(void);
    157 
    158 protected:
    159 	const TestConfig				m_config;
    160 	const bool						m_featureSupported;
    161 
    162 	const InstanceInterface&		m_vki;
    163 	const DeviceInterface&			m_vkd;
    164 	VkDevice						m_device;
    165 	VkPhysicalDevice				m_physicalDevice;
    166 
    167 	VkImageSp						m_multisampleImage;
    168 	AllocationSp					m_multisampleImageMemory;
    169 	VkImageViewSp					m_multisampleImageView;
    170 	VkImageSp						m_singlesampleImage;
    171 	AllocationSp					m_singlesampleImageMemory;
    172 	VkImageViewSp					m_singlesampleImageView;
    173 	VkBufferSp						m_buffer;
    174 	AllocationSp					m_bufferMemory;
    175 
    176 	Unique<VkRenderPass>			m_renderPass;
    177 	Unique<VkFramebuffer>			m_framebuffer;
    178 	Unique<VkPipelineLayout>		m_renderPipelineLayout;
    179 	Unique<VkPipeline>				m_renderPipeline;
    180 
    181 	const Unique<VkCommandPool>		m_commandPool;
    182 };
    183 
    184 DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config)
    185 	: TestInstance				(context)
    186 	, m_config					(config)
    187 	, m_featureSupported		(isFeaturesSupported())
    188 	, m_vki						(context.getInstanceInterface())
    189 	, m_vkd						(context.getDeviceInterface())
    190 	, m_device					(context.getDevice())
    191 	, m_physicalDevice			(context.getPhysicalDevice())
    192 
    193 	, m_multisampleImage		(createImage(m_config.sampleCount))
    194 	, m_multisampleImageMemory	(createImageMemory(m_multisampleImage))
    195 	, m_multisampleImageView	(createImageView(m_multisampleImage, 0u))
    196 
    197 	, m_singlesampleImage		(createImage(1, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
    198 	, m_singlesampleImageMemory	(createImageMemory(m_singlesampleImage))
    199 	, m_singlesampleImageView	(createImageView(m_singlesampleImage, m_config.resolveBaseLayer))
    200 
    201 	, m_buffer					(createBuffer())
    202 	, m_bufferMemory			(createBufferMemory())
    203 
    204 	, m_renderPass				(createRenderPass())
    205 	, m_framebuffer				(createFramebuffer(*m_renderPass, m_multisampleImageView, m_singlesampleImageView))
    206 	, m_renderPipelineLayout	(createRenderPipelineLayout())
    207 	, m_renderPipeline			(createRenderPipeline(*m_renderPass, *m_renderPipelineLayout))
    208 
    209 
    210 	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
    211 {
    212 }
    213 
    214 DepthStencilResolveTest::~DepthStencilResolveTest (void)
    215 {
    216 }
    217 
    218 bool DepthStencilResolveTest::isFeaturesSupported()
    219 {
    220 	m_context.requireDeviceExtension("VK_KHR_depth_stencil_resolve");
    221 	if (m_config.imageLayers > 1)
    222 		m_context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
    223 
    224 	VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsResolveProperties;
    225 	deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
    226 	dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
    227 	dsResolveProperties.pNext = DE_NULL;
    228 
    229 	VkPhysicalDeviceProperties2 deviceProperties;
    230 	deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
    231 	deviceProperties.pNext = &dsResolveProperties;
    232 
    233 	// perform query to get supported float control properties
    234 	const VkPhysicalDevice			physicalDevice		= m_context.getPhysicalDevice();
    235 	const vk::InstanceInterface&	instanceInterface	= m_context.getInstanceInterface();
    236 	instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
    237 
    238 	// check if both modes are supported
    239 	VkResolveModeFlagBitsKHR depthResolveMode		= m_config.depthResolveMode;
    240 	VkResolveModeFlagBitsKHR stencilResolveMode		= m_config.stencilResolveMode;
    241 	if ((depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
    242 		!(depthResolveMode & dsResolveProperties.supportedDepthResolveModes))
    243 		TCU_THROW(NotSupportedError, "Depth resolve mode not supported");
    244 	if ((stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
    245 		!(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes))
    246 		TCU_THROW(NotSupportedError, "Stencil resolve mode not supported");
    247 
    248 	// check if the implementation supports setting the depth and stencil resolve
    249 	// modes to different values when one of those modes is VK_RESOLVE_MODE_NONE_KHR
    250 	if (dsResolveProperties.independentResolveNone)
    251 	{
    252 		if ((!dsResolveProperties.independentResolve) &&
    253 			(depthResolveMode != stencilResolveMode) &&
    254 			(depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
    255 			(stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR))
    256 			TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
    257 	}
    258 	else if (depthResolveMode != stencilResolveMode)
    259 	{
    260 		// when independentResolveNone is VK_FALSE then both modes must be the same
    261 		TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
    262 	}
    263 
    264 	// check if the implementation supports all combinations of the supported depth and stencil resolve modes
    265 	if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode))
    266 		TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
    267 
    268 	return true;
    269 }
    270 
    271 VkSampleCountFlagBits DepthStencilResolveTest::sampleCountBitFromSampleCount (deUint32 count) const
    272 {
    273 	switch (count)
    274 	{
    275 		case 1:  return VK_SAMPLE_COUNT_1_BIT;
    276 		case 2:  return VK_SAMPLE_COUNT_2_BIT;
    277 		case 4:  return VK_SAMPLE_COUNT_4_BIT;
    278 		case 8:  return VK_SAMPLE_COUNT_8_BIT;
    279 		case 16: return VK_SAMPLE_COUNT_16_BIT;
    280 		case 32: return VK_SAMPLE_COUNT_32_BIT;
    281 		case 64: return VK_SAMPLE_COUNT_64_BIT;
    282 
    283 		default:
    284 			DE_FATAL("Invalid sample count");
    285 			return (VkSampleCountFlagBits)0x0;
    286 	}
    287 }
    288 
    289 VkImageSp DepthStencilResolveTest::createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage)
    290 {
    291 	const tcu::TextureFormat	format(mapVkFormat(m_config.format));
    292 	const VkImageTiling			imageTiling(VK_IMAGE_TILING_OPTIMAL);
    293 	VkSampleCountFlagBits		sampleCountBit(sampleCountBitFromSampleCount(sampleCount));
    294 	VkImageUsageFlags			usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | additionalUsage;
    295 
    296 	VkImageFormatProperties imageFormatProperties;
    297 	if (m_vki.getPhysicalDeviceImageFormatProperties(m_physicalDevice, m_config.format, VK_IMAGE_TYPE_2D, imageTiling,
    298 													 usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
    299 	{
    300 		TCU_THROW(NotSupportedError, "Format not supported");
    301 	}
    302 	if (imageFormatProperties.sampleCounts < sampleCount)
    303 	{
    304 		TCU_THROW(NotSupportedError, "Sample count not supported");
    305 	}
    306 	if (imageFormatProperties.maxArrayLayers < m_config.imageLayers)
    307 	{
    308 		TCU_THROW(NotSupportedError, "Layers count not supported");
    309 	}
    310 
    311 	const VkExtent3D imageExtent =
    312 	{
    313 		m_config.width,
    314 		m_config.height,
    315 		1u
    316 	};
    317 
    318 	if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order)))
    319 		TCU_THROW(NotSupportedError, "Format can't be used as depth/stencil attachment");
    320 
    321 	if (imageFormatProperties.maxExtent.width < imageExtent.width
    322 		|| imageFormatProperties.maxExtent.height < imageExtent.height
    323 		|| ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
    324 		|| imageFormatProperties.maxArrayLayers < m_config.imageLayers)
    325 	{
    326 		TCU_THROW(NotSupportedError, "Image type not supported");
    327 	}
    328 
    329 	const VkImageCreateInfo pCreateInfo =
    330 	{
    331 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
    332 		DE_NULL,
    333 		0u,
    334 		VK_IMAGE_TYPE_2D,
    335 		m_config.format,
    336 		imageExtent,
    337 		1u,
    338 		m_config.imageLayers,
    339 		sampleCountBit,
    340 		imageTiling,
    341 		usage,
    342 		VK_SHARING_MODE_EXCLUSIVE,
    343 		0u,
    344 		DE_NULL,
    345 		VK_IMAGE_LAYOUT_UNDEFINED
    346 	};
    347 
    348 	return safeSharedPtr(new Unique<VkImage>(vk::createImage(m_vkd, m_device, &pCreateInfo)));
    349 }
    350 
    351 AllocationSp DepthStencilResolveTest::createImageMemory (VkImageSp image)
    352 {
    353 	Allocator& allocator = m_context.getDefaultAllocator();
    354 
    355 	de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, **image), MemoryRequirement::Any));
    356 	VK_CHECK(m_vkd.bindImageMemory(m_device, **image, allocation->getMemory(), allocation->getOffset()));
    357 	return safeSharedPtr(allocation.release());
    358 }
    359 
    360 VkImageViewSp DepthStencilResolveTest::createImageView (VkImageSp image, deUint32 baseArrayLayer)
    361 {
    362 	const VkImageSubresourceRange range =
    363 	{
    364 		m_config.aspectFlag,
    365 		0u,
    366 		1u,
    367 		baseArrayLayer,
    368 		m_config.viewLayers
    369 	};
    370 
    371 	const VkImageViewCreateInfo pCreateInfo =
    372 	{
    373 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
    374 		DE_NULL,
    375 		0u,
    376 		**image,
    377 		(m_config.viewLayers > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
    378 		m_config.format,
    379 		makeComponentMappingRGBA(),
    380 		range,
    381 	};
    382 	return safeSharedPtr(new Unique<VkImageView>(vk::createImageView(m_vkd, m_device, &pCreateInfo)));
    383 }
    384 
    385 Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (void)
    386 {
    387 	const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount));
    388 
    389 	const AttachmentDescription2 multisampleAttachment		// VkAttachmentDescription2KHR
    390 	(
    391 															// VkStructureType					sType;
    392 		DE_NULL,											// const void*						pNext;
    393 		0u,													// VkAttachmentDescriptionFlags		flags;
    394 		m_config.format,									// VkFormat							format;
    395 		samples,											// VkSampleCountFlagBits			samples;
    396 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
    397 		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				storeOp;
    398 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp;
    399 		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
    400 		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
    401 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL				// VkImageLayout					finalLayout;
    402 	);
    403 	const AttachmentReference2 multisampleAttachmentRef		// VkAttachmentReference2KHR
    404 	(
    405 															// VkStructureType					sType;
    406 		DE_NULL,											// const void*						pNext;
    407 		0u,													// deUint32							attachment;
    408 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					layout;
    409 		0u													// VkImageAspectFlags				aspectMask;
    410 	);
    411 
    412 	const AttachmentDescription2 singlesampleAttachment		// VkAttachmentDescription2KHR
    413 	(
    414 															// VkStructureType					sType;
    415 		DE_NULL,											// const void*						pNext;
    416 		0u,													// VkAttachmentDescriptionFlags		flags;
    417 		m_config.format,									// VkFormat							format;
    418 		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
    419 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
    420 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
    421 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp;
    422 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				stencilStoreOp;
    423 		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
    424 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL				// VkImageLayout					finalLayout;
    425 	);
    426 	AttachmentReference2 singlesampleAttachmentRef			// VkAttachmentReference2KHR
    427 	(
    428 															// VkStructureType					sType;
    429 		DE_NULL,											// const void*						pNext;
    430 		1u,													// deUint32							attachment;
    431 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					layout;
    432 		0u													// VkImageAspectFlags				aspectMask;
    433 	);
    434 
    435 	std::vector<AttachmentDescription2> attachments;
    436 	attachments.push_back(multisampleAttachment);
    437 	attachments.push_back(singlesampleAttachment);
    438 
    439 	VkSubpassDescriptionDepthStencilResolveKHR dsResolveDescription =
    440 	{
    441 		VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR,
    442 		DE_NULL,																// const void*						pNext;
    443 		m_config.depthResolveMode,												// VkResolveModeFlagBitsKHR			depthResolveMode;
    444 		m_config.stencilResolveMode,											// VkResolveModeFlagBitsKHR			stencilResolveMode;
    445 		&singlesampleAttachmentRef												// VkAttachmentReference2KHR		pDepthStencilResolveAttachment;
    446 	};
    447 
    448 	const SubpassDescription2 subpass					// VkSubpassDescription2KHR
    449 	(
    450 														// VkStructureType						sType;
    451 		&dsResolveDescription,							// const void*							pNext;
    452 		(VkSubpassDescriptionFlags)0,					// VkSubpassDescriptionFlags			flags;
    453 		VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint					pipelineBindPoint;
    454 		0u,												// deUint32								viewMask;
    455 		0u,												// deUint32								inputAttachmentCount;
    456 		DE_NULL,										// const VkAttachmentReference2KHR*		pInputAttachments;
    457 		0u,												// deUint32								colorAttachmentCount;
    458 		DE_NULL,										// const VkAttachmentReference2KHR*		pColorAttachments;
    459 		DE_NULL,										// const VkAttachmentReference2KHR*		pResolveAttachments;
    460 		&multisampleAttachmentRef,						// const VkAttachmentReference2KHR*		pDepthStencilAttachment;
    461 		0u,												// deUint32								preserveAttachmentCount;
    462 		DE_NULL											// const deUint32*						pPreserveAttachments;
    463 	);
    464 
    465 	const RenderPassCreateInfo2 renderPassCreator		// VkRenderPassCreateInfo2KHR
    466 	(
    467 														// VkStructureType						sType;
    468 		DE_NULL,										// const void*							pNext;
    469 		(VkRenderPassCreateFlags)0u,					// VkRenderPassCreateFlags				flags;
    470 		(deUint32)attachments.size(),					// deUint32								attachmentCount;
    471 		&attachments[0],								// const VkAttachmentDescription2KHR*	pAttachments;
    472 		1u,												// deUint32								subpassCount;
    473 		&subpass,										// const VkSubpassDescription2KHR*		pSubpasses;
    474 		0u,												// deUint32								dependencyCount;
    475 		DE_NULL,										// const VkSubpassDependency2KHR*		pDependencies;
    476 		0u,												// deUint32								correlatedViewMaskCount;
    477 		DE_NULL											// const deUint32*						pCorrelatedViewMasks;
    478 	);
    479 
    480 	return renderPassCreator.createRenderPass(m_vkd, m_device);
    481 }
    482 
    483 Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView)
    484 {
    485 	std::vector<VkImageView> attachments;
    486 	attachments.push_back(**multisampleImageView);
    487 	attachments.push_back(**singlesampleImageView);
    488 
    489 	const VkFramebufferCreateInfo createInfo =
    490 	{
    491 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
    492 		DE_NULL,
    493 		0u,
    494 
    495 		renderPass,
    496 		(deUint32)attachments.size(),
    497 		&attachments[0],
    498 
    499 		m_config.width,
    500 		m_config.height,
    501 		m_config.viewLayers
    502 	};
    503 
    504 	return vk::createFramebuffer(m_vkd, m_device, &createInfo);
    505 }
    506 
    507 Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void)
    508 {
    509 	VkPushConstantRange pushConstant =
    510 	{
    511 		VK_SHADER_STAGE_FRAGMENT_BIT,
    512 		0u,
    513 		4u
    514 	};
    515 
    516 	deUint32				pushConstantRangeCount	= 0u;
    517 	VkPushConstantRange*	pPushConstantRanges		= DE_NULL;
    518 	if (m_config.verifyBuffer == VB_STENCIL)
    519 	{
    520 		pushConstantRangeCount	= 1u;
    521 		pPushConstantRanges		= &pushConstant;
    522 	}
    523 
    524 	const VkPipelineLayoutCreateInfo createInfo	=
    525 	{
    526 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
    527 		DE_NULL,
    528 		(vk::VkPipelineLayoutCreateFlags)0,
    529 
    530 		0u,
    531 		DE_NULL,
    532 
    533 		pushConstantRangeCount,
    534 		pPushConstantRanges
    535 	};
    536 
    537 	return vk::createPipelineLayout(m_vkd, m_device, &createInfo);
    538 }
    539 
    540 Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout)
    541 {
    542 	const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL);
    543 	const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
    544 
    545 	const Unique<VkShaderModule>	vertexShaderModule		(createShaderModule(m_vkd, m_device, binaryCollection.get("quad-vert"), 0u));
    546 	const Unique<VkShaderModule>	fragmentShaderModule	(createShaderModule(m_vkd, m_device, binaryCollection.get("quad-frag"), 0u));
    547 	const Move<VkShaderModule>		geometryShaderModule	(m_config.imageLayers == 1 ? Move<VkShaderModule>() : createShaderModule(m_vkd, m_device, binaryCollection.get("quad-geom"), 0u));
    548 
    549 	const VkPipelineVertexInputStateCreateInfo vertexInputState =
    550 	{
    551 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
    552 		DE_NULL,
    553 		(VkPipelineVertexInputStateCreateFlags)0u,
    554 
    555 		0u,
    556 		DE_NULL,
    557 
    558 		0u,
    559 		DE_NULL
    560 	};
    561 	const tcu::UVec2				view		(m_config.width, m_config.height);
    562 	const std::vector<VkViewport>	viewports	(1, makeViewport(view));
    563 	const std::vector<VkRect2D>		scissors	(1, m_config.renderArea);
    564 
    565 	const VkPipelineMultisampleStateCreateInfo multisampleState =
    566 	{
    567 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
    568 		DE_NULL,
    569 		(VkPipelineMultisampleStateCreateFlags)0u,
    570 
    571 		sampleCountBitFromSampleCount(m_config.sampleCount),
    572 		VK_FALSE,
    573 		0.0f,
    574 		DE_NULL,
    575 		VK_FALSE,
    576 		VK_FALSE,
    577 	};
    578 	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
    579 	{
    580 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
    581 		DE_NULL,
    582 		(VkPipelineDepthStencilStateCreateFlags)0u,
    583 
    584 		VK_TRUE,							// depthTestEnable
    585 		VK_TRUE,
    586 		VK_COMPARE_OP_ALWAYS,
    587 		VK_FALSE,
    588 		testingStencil,						// stencilTestEnable
    589 		{
    590 			VK_STENCIL_OP_REPLACE,			// failOp
    591 			VK_STENCIL_OP_REPLACE,			// passOp
    592 			VK_STENCIL_OP_REPLACE,			// depthFailOp
    593 			VK_COMPARE_OP_ALWAYS,			// compareOp
    594 			0xFFu,							// compareMask
    595 			0xFFu,							// writeMask
    596 			1								// reference
    597 		},
    598 		{
    599 			VK_STENCIL_OP_REPLACE,
    600 			VK_STENCIL_OP_REPLACE,
    601 			VK_STENCIL_OP_REPLACE,
    602 			VK_COMPARE_OP_ALWAYS,
    603 			0xFFu,
    604 			0xFFu,
    605 			1
    606 		},
    607 		0.0f,
    608 		1.0f
    609 	};
    610 
    611 	std::vector<VkDynamicState> dynamicState;
    612 	dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
    613 	const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
    614 	{
    615 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType                      sType;
    616 		DE_NULL,												// const void*                          pNext;
    617 		(VkPipelineDynamicStateCreateFlags)0u,					// VkPipelineDynamicStateCreateFlags    flags;
    618 		static_cast<deUint32>(dynamicState.size()),				// deUint32                             dynamicStateCount;
    619 		&dynamicState[0]										// const VkDynamicState*                pDynamicStates;
    620 	};
    621 
    622 	return makeGraphicsPipeline(m_vkd,															// const DeviceInterface&                        vk
    623 								m_device,														// const VkDevice                                device
    624 								renderPipelineLayout,											// const VkPipelineLayout                        pipelineLayout
    625 								*vertexShaderModule,											// const VkShaderModule                          vertexShaderModule
    626 								DE_NULL,														// const VkShaderModule                          tessellationControlShaderModule
    627 								DE_NULL,														// const VkShaderModule                          tessellationEvalShaderModule
    628 								m_config.imageLayers == 1 ? DE_NULL : *geometryShaderModule,	// const VkShaderModule                          geometryShaderModule
    629 								*fragmentShaderModule,											// const VkShaderModule                          fragmentShaderModule
    630 								renderPass,														// const VkRenderPass                            renderPass
    631 								viewports,														// const std::vector<VkViewport>&                viewports
    632 								scissors,														// const std::vector<VkRect2D>&                  scissors
    633 								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// const VkPrimitiveTopology                     topology
    634 								0u,																// const deUint32                                subpass
    635 								0u,																// const deUint32                                patchControlPoints
    636 								&vertexInputState,												// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
    637 								DE_NULL,														// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
    638 								&multisampleState,												// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
    639 								&depthStencilState,												// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
    640 								DE_NULL,														// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
    641 								testingStencil ? &dynamicStateCreateInfo : DE_NULL);			// const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
    642 }
    643 
    644 AllocationSp DepthStencilResolveTest::createBufferMemory (void)
    645 {
    646 	Allocator&				allocator = m_context.getDefaultAllocator();
    647 	de::MovePtr<Allocation> allocation(allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, **m_buffer), MemoryRequirement::HostVisible));
    648 	VK_CHECK(m_vkd.bindBufferMemory(m_device, **m_buffer, allocation->getMemory(), allocation->getOffset()));
    649 	return safeSharedPtr(allocation.release());
    650 }
    651 
    652 VkBufferSp DepthStencilResolveTest::createBuffer (void)
    653 {
    654 	const VkBufferUsageFlags	bufferUsage			(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    655 	const tcu::TextureFormat	textureFormat		(mapVkFormat(m_config.format));
    656 	const VkDeviceSize			pixelSize			(textureFormat.getPixelSize());
    657 	const VkBufferCreateInfo	createInfo			=
    658 	{
    659 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
    660 		DE_NULL,
    661 		0u,
    662 
    663 		m_config.width * m_config.height * m_config.imageLayers * pixelSize,
    664 		bufferUsage,
    665 
    666 		VK_SHARING_MODE_EXCLUSIVE,
    667 		0u,
    668 		DE_NULL
    669 	};
    670 	return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo)));
    671 }
    672 
    673 void DepthStencilResolveTest::submit (void)
    674 {
    675 	const DeviceInterface&						vkd					(m_context.getDeviceInterface());
    676 	const VkDevice								device				(m_context.getDevice());
    677 	const Unique<VkCommandBuffer>				commandBuffer		(allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
    678 	const RenderpassSubpass2::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
    679 	const RenderpassSubpass2::SubpassEndInfo	subpassEndInfo		(DE_NULL);
    680 
    681 	beginCommandBuffer(vkd, *commandBuffer);
    682 
    683 	{
    684 		VkClearValue clearValues[2];
    685 		clearValues[0].depthStencil = m_config.clearValue;
    686 		clearValues[1].depthStencil = m_config.clearValue;
    687 
    688 		const VkRenderPassBeginInfo beginInfo =
    689 		{
    690 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
    691 			DE_NULL,
    692 
    693 			*m_renderPass,
    694 			*m_framebuffer,
    695 
    696 			{
    697 				{ 0u, 0u },
    698 				{ m_config.width, m_config.height }
    699 			},
    700 
    701 			2u,
    702 			clearValues
    703 		};
    704 		RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
    705 	}
    706 
    707 	// Render
    708 	bool testingDepth = (m_config.verifyBuffer == VB_DEPTH);
    709 	if (testingDepth)
    710 	{
    711 		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
    712 		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
    713 	}
    714 	else
    715 	{
    716 		// For stencil we can set reference value for just one sample at a time
    717 		// so we need to do as many passes as there are samples, first half
    718 		// of samples is initialized with 1 and second half with 255
    719 		const deUint32 halfOfSamples = m_config.sampleCount >> 1;
    720 		for (deUint32 renderPass = 0 ; renderPass < m_config.sampleCount ; renderPass++)
    721 		{
    722 			deUint32 stencilReference = 1 + 254 * (renderPass >= halfOfSamples);
    723 			vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
    724 			vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(renderPass), &renderPass);
    725 			vkd.cmdSetStencilReference(*commandBuffer, VK_STENCIL_FRONT_AND_BACK, stencilReference);
    726 			vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
    727 		}
    728 	}
    729 
    730 	RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
    731 
    732 	// Memory barriers between rendering and copying
    733 	{
    734 		const VkImageMemoryBarrier barrier =
    735 		{
    736 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
    737 			DE_NULL,
    738 
    739 			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
    740 			VK_ACCESS_TRANSFER_READ_BIT,
    741 
    742 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
    743 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
    744 
    745 			VK_QUEUE_FAMILY_IGNORED,
    746 			VK_QUEUE_FAMILY_IGNORED,
    747 
    748 			**m_singlesampleImage,
    749 			{
    750 				m_config.aspectFlag,
    751 				0u,
    752 				1u,
    753 				0u,
    754 				m_config.viewLayers
    755 			}
    756 		};
    757 
    758 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
    759 	}
    760 
    761 	// Copy image memory to buffers
    762 	const VkBufferImageCopy region =
    763 	{
    764 		0u,
    765 		0u,
    766 		0u,
    767 		{
    768 			testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT,
    769 			0u,
    770 			0u,
    771 			m_config.viewLayers,
    772 		},
    773 		{ 0u, 0u, 0u },
    774 		{ m_config.width, m_config.height, 1u }
    775 	};
    776 
    777 	vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, &region);
    778 
    779 	// Memory barriers between copies and host access
    780 	{
    781 		const VkBufferMemoryBarrier barrier =
    782 		{
    783 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
    784 			DE_NULL,
    785 
    786 			VK_ACCESS_TRANSFER_WRITE_BIT,
    787 			VK_ACCESS_HOST_READ_BIT,
    788 
    789 			VK_QUEUE_FAMILY_IGNORED,
    790 			VK_QUEUE_FAMILY_IGNORED,
    791 
    792 			**m_buffer,
    793 			0u,
    794 			VK_WHOLE_SIZE
    795 		};
    796 
    797 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
    798 	}
    799 
    800 	endCommandBuffer(vkd, *commandBuffer);
    801 
    802 	submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
    803 }
    804 
    805 bool DepthStencilResolveTest::verifyDepth (void)
    806 {
    807 	deUint32			layerSize	= m_config.width * m_config.height;
    808 	deUint32			valuesCount	= layerSize * m_config.viewLayers;
    809 	deUint8*			pixelPtr	= static_cast<deUint8*>(m_bufferMemory->getHostPtr());
    810 
    811 	float expectedValue = m_config.depthExpectedValue;
    812 	if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE_KHR)
    813 		expectedValue = m_config.clearValue.depth;
    814 
    815 	// depth data in buffer is tightly packed, ConstPixelBufferAccess
    816 	// coludn't be used for depth value extraction as it cant interpret
    817 	// formats containing just depth component
    818 
    819 	typedef float (*DepthComponentGetterFn)(deUint8*);
    820 	VkFormat				format				= m_config.format;
    821 	DepthComponentGetterFn	getDepthComponent	= &get16bitDepthComponent;
    822 	deUint32				pixelStep			= 2;
    823 	float					epsilon				= 0.002f;
    824 
    825 	if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) ||
    826 		(format == VK_FORMAT_D24_UNORM_S8_UINT))
    827 	{
    828 		getDepthComponent	= &get24bitDepthComponent;
    829 		pixelStep			= 4;
    830 	}
    831 	else if ((format == VK_FORMAT_D32_SFLOAT) ||
    832 				(format == VK_FORMAT_D32_SFLOAT_S8_UINT))
    833 	{
    834 		getDepthComponent	= &get32bitDepthComponent;
    835 		pixelStep			= 4;
    836 	}
    837 
    838 	for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
    839 	{
    840 		float depth = (*getDepthComponent)(pixelPtr);
    841 		pixelPtr += pixelStep;
    842 
    843 		// check if pixel data is outside of render area
    844 		deInt32 layerIndex		= valueIndex / layerSize;
    845 		deInt32 inLayerIndex	= valueIndex % layerSize;
    846 		deInt32 x				= inLayerIndex % m_config.width;
    847 		deInt32 y				= (inLayerIndex - x) / m_config.width;
    848 		deInt32 x1				= m_config.renderArea.offset.x;
    849 		deInt32 y1				= m_config.renderArea.offset.y;
    850 		deInt32 x2				= x1 + m_config.renderArea.extent.width;
    851 		deInt32 y2				= y1 + m_config.renderArea.extent.height;
    852 		if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
    853 		{
    854 			// verify that outside of render area there are clear values
    855 			float error = deFloatAbs(depth - m_config.clearValue.depth);
    856 			if (error > epsilon)
    857 			{
    858 				m_context.getTestContext().getLog()
    859 				<< TestLog::Message << "(" << x << ", " << y
    860 				<< ", layer: " << layerIndex << ") is outside of render area but depth value is: "
    861 				<< depth << " (expected " << m_config.clearValue.depth << ")" << TestLog::EndMessage;
    862 				return false;
    863 			}
    864 
    865 			// value is correct, go to next one
    866 			continue;
    867 		}
    868 
    869 		float error = deFloatAbs(depth - expectedValue);
    870 		if (error > epsilon)
    871 		{
    872 			m_context.getTestContext().getLog() << TestLog::Message
    873 				<< "At (" << x << ", " << y << ", layer: " << layerIndex
    874 				<< ") depth value is: " << depth << " expected: "
    875 				<< expectedValue << TestLog::EndMessage;
    876 			return false;
    877 		}
    878 	}
    879 	m_context.getTestContext().getLog() << TestLog::Message
    880 		<< "Depth value is " << expectedValue
    881 		<< TestLog::EndMessage;
    882 
    883 	return true;
    884 }
    885 
    886 bool DepthStencilResolveTest::verifyStencil (void)
    887 {
    888 	deUint32			layerSize	= m_config.width * m_config.height;
    889 	deUint32			valuesCount	= layerSize * m_config.viewLayers;
    890 	deUint8*			pixelPtr	= static_cast<deUint8*>(m_bufferMemory->getHostPtr());
    891 
    892 	// when stencil is tested we are discarding invocations and
    893 	// because of that depth and stencil need to be tested separately
    894 
    895 	deUint8 expectedValue = m_config.stencilExpectedValue;
    896 	if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE_KHR)
    897 		expectedValue = static_cast<deUint8>(m_config.clearValue.stencil);
    898 
    899 	for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
    900 	{
    901 		deUint8 stencil			= *pixelPtr++;
    902 		deInt32 layerIndex		= valueIndex / layerSize;
    903 		deInt32 inLayerIndex	= valueIndex % layerSize;
    904 		deInt32 x				= inLayerIndex % m_config.width;
    905 		deInt32 y				= (inLayerIndex - x) / m_config.width;
    906 		deInt32 x1				= m_config.renderArea.offset.x;
    907 		deInt32 y1				= m_config.renderArea.offset.y;
    908 		deInt32 x2				= x1 + m_config.renderArea.extent.width;
    909 		deInt32 y2				= y1 + m_config.renderArea.extent.height;
    910 		if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
    911 		{
    912 			if (stencil != m_config.clearValue.stencil)
    913 			{
    914 				m_context.getTestContext().getLog()
    915 				<< TestLog::Message << "(" << x << ", " << y << ", layer: " << layerIndex
    916 				<< ") is outside of render area but stencil value is: "
    917 				<< stencil << " (expected " << m_config.clearValue.stencil << ")" << TestLog::EndMessage;
    918 				return false;
    919 			}
    920 
    921 			// value is correct, go to next one
    922 			continue;
    923 		}
    924 
    925 		if (stencil != expectedValue)
    926 		{
    927 			m_context.getTestContext().getLog() << TestLog::Message
    928 				<< "At (" << x << ", " << y << ", layer: " << layerIndex
    929 				<< ") stencil value is: " << static_cast<deUint32>(stencil)
    930 				<< " expected: " << static_cast<deUint32>(expectedValue)
    931 				<< TestLog::EndMessage;
    932 			return false;
    933 		}
    934 	}
    935 	m_context.getTestContext().getLog() << TestLog::Message
    936 		<< "Stencil value is "
    937 		<< static_cast<deUint32>(expectedValue)
    938 		<< TestLog::EndMessage;
    939 
    940 	return true;
    941 }
    942 
    943 tcu::TestStatus DepthStencilResolveTest::iterate (void)
    944 {
    945 	submit();
    946 
    947 	bool result = false;
    948 	if (m_config.verifyBuffer == VB_DEPTH)
    949 		result = verifyDepth();
    950 	else
    951 		result = verifyStencil();
    952 
    953 	if (result)
    954 		return tcu::TestStatus::pass("Pass");
    955 	return tcu::TestStatus::fail("Fail");
    956 }
    957 
    958 struct Programs
    959 {
    960 	void init (vk::SourceCollections& dst, TestConfig config) const
    961 	{
    962 		// geometry shader is only needed in multi-layer framebuffer resolve tests
    963 		if (config.imageLayers > 1)
    964 		{
    965 			const deUint32 layerCount = 3;
    966 
    967 			std::ostringstream src;
    968 			src << "#version 450\n"
    969 				<< "highp float;\n"
    970 				<< "\n"
    971 				<< "layout(triangles) in;\n"
    972 				<< "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n"
    973 				<< "\n"
    974 				<< "in gl_PerVertex {\n"
    975 				<< "    vec4 gl_Position;\n"
    976 				<< "} gl_in[];\n"
    977 				<< "\n"
    978 				<< "out gl_PerVertex {\n"
    979 				<< "    vec4 gl_Position;\n"
    980 				<< "};\n"
    981 				<< "\n"
    982 				<< "void main (void) {\n"
    983 				<< "    for (int layerNdx = 0; layerNdx < " << layerCount << "; ++layerNdx) {\n"
    984 				<< "        for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
    985 				<< "            gl_Position = gl_in[vertexNdx].gl_Position;\n"
    986 				<< "            gl_Layer    = layerNdx;\n"
    987 				<< "            EmitVertex();\n"
    988 				<< "        };\n"
    989 				<< "        EndPrimitive();\n"
    990 				<< "    };\n"
    991 				<< "}\n";
    992 
    993 			dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str());
    994 		}
    995 
    996 		dst.glslSources.add("quad-vert") << glu::VertexSource(
    997 			"#version 450\n"
    998 			"out gl_PerVertex {\n"
    999 			"\tvec4 gl_Position;\n"
   1000 			"};\n"
   1001 			"highp float;\n"
   1002 			"void main (void) {\n"
   1003 			"\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
   1004 			"\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
   1005 			"}\n");
   1006 
   1007 		if (config.verifyBuffer == VB_DEPTH)
   1008 		{
   1009 			dst.glslSources.add("quad-frag") << glu::FragmentSource(
   1010 				"#version 450\n"
   1011 				"precision highp float;\n"
   1012 				"precision highp int;\n"
   1013 				"void main (void)\n"
   1014 				"{\n"
   1015 				"  float sampleIndex = float(gl_SampleID);\n"				// sampleIndex is integer in range <0, 63>
   1016 				"  float valueIndex = round(mod(sampleIndex, 4.0));\n"		// limit possible depth values - count to 4
   1017 				"  float value = valueIndex + 2.0;\n"						// value is one of [2, 3, 4, 5]
   1018 				"  value = round(exp2(value));\n"							// value is one of [4, 8, 16, 32]
   1019 				"  bool condition = (int(value) == 8);\n"					// select second sample value (to make it smallest)
   1020 				"  value = round(value - float(condition) * 6.0);\n"		// value is one of [4, 2, 16, 32]
   1021 				"  gl_FragDepth = value / 100.0;\n"							// sample depth is one of [0.04, 0.02, 0.16, 0.32]
   1022 				"}\n");
   1023 		}
   1024 		else
   1025 		{
   1026 			dst.glslSources.add("quad-frag") << glu::FragmentSource(
   1027 				"#version 450\n"
   1028 				"precision highp float;\n"
   1029 				"precision highp int;\n"
   1030 				"layout(push_constant) uniform PushConstant {\n"
   1031 				"  highp int sampleID;\n"
   1032 				"} pushConstants;\n"
   1033 				"void main (void)\n"
   1034 				"{\n"
   1035 				"  if(gl_SampleID != pushConstants.sampleID)\n"
   1036 				"    discard;\n"
   1037 				"  gl_FragDepth = 0.5;\n"
   1038 				"}\n");
   1039 		}
   1040 	}
   1041 };
   1042 
   1043 void initTests (tcu::TestCaseGroup* group)
   1044 {
   1045 	typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;
   1046 
   1047 	struct FormatData
   1048 	{
   1049 		VkFormat		format;
   1050 		const char*		name;
   1051 		bool			hasDepth;
   1052 		bool			hasStencil;
   1053 	};
   1054 	FormatData formats[] =
   1055 	{
   1056 		{ VK_FORMAT_D16_UNORM,				"d16_unorm",			true,	false },
   1057 		{ VK_FORMAT_X8_D24_UNORM_PACK32,	"x8_d24_unorm_pack32",	true,	false },
   1058 		{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat",			true,	false },
   1059 		{ VK_FORMAT_S8_UINT,				"s8_uint",				false,	true },
   1060 		{ VK_FORMAT_D16_UNORM_S8_UINT,		"d16_unorm_s8_uint",	true,	true },
   1061 		{ VK_FORMAT_D24_UNORM_S8_UINT,		"d24_unorm_s8_uint",	true,	true },
   1062 		{ VK_FORMAT_D32_SFLOAT_S8_UINT,		"d32_sfloat_s8_uint",	true,	true },
   1063 	};
   1064 
   1065 	struct ResolveModeData
   1066 	{
   1067 		VkResolveModeFlagBitsKHR	flag;
   1068 		std::string					name;
   1069 	};
   1070 	ResolveModeData resolveModes[] =
   1071 	{
   1072 		{ VK_RESOLVE_MODE_NONE_KHR,				"none" },
   1073 		{ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,	"zero" },
   1074 		{ VK_RESOLVE_MODE_AVERAGE_BIT_KHR,		"average" },
   1075 		{ VK_RESOLVE_MODE_MIN_BIT_KHR,			"min" },
   1076 		{ VK_RESOLVE_MODE_MAX_BIT_KHR,			"max" },
   1077 	};
   1078 
   1079 	struct ImageTestData
   1080 	{
   1081 		const char*					groupName;
   1082 		deUint32					width;
   1083 		deUint32					height;
   1084 		deUint32					imageLayers;
   1085 		VkRect2D					renderArea;
   1086 		VkClearDepthStencilValue	clearValue;
   1087 	};
   1088 
   1089 	// NOTE: tests cant be executed for 1D and 3D images:
   1090 	// 1D images are not tested because acording to specyfication sampleCounts
   1091 	// will be set to VK_SAMPLE_COUNT_1_BIT when type is not VK_IMAGE_TYPE_2D
   1092 	// 3D images are not tested because VkFramebufferCreateInfo specification
   1093 	// states that: each element of pAttachments that is a 2D or 2D array image
   1094 	// view taken from a 3D image must not be a depth/stencil format
   1095 	ImageTestData imagesTestData[] =
   1096 	{
   1097 		{ "image_2d_32_32",	32, 32, 1, {{ 0,  0}, {32, 32}}, {0.000f, 0x00} },
   1098 		{ "image_2d_8_32",	 8, 32, 1, {{ 1,  1}, { 6, 30}}, {0.123f, 0x01} },
   1099 		{ "image_2d_49_13",	49, 13, 1, {{10,  5}, {20,  8}}, {1.000f, 0x05} },
   1100 		{ "image_2d_5_1",	 5,  1, 1, {{ 0,  0}, { 5,  1}}, {0.500f, 0x00} },
   1101 		{ "image_2d_17_1",	17,  1, 1, {{ 1,  0}, {15,  1}}, {0.789f, 0xfa} },
   1102 	};
   1103 	const deUint32 sampleCounts[] =
   1104 	{
   1105 		2u, 4u, 8u, 16u, 32u, 64u
   1106 	};
   1107 	const float depthExpectedValue[][6] =
   1108 	{
   1109 		// 2 samples	4			8			16			32			64
   1110 		{ 0.0f,			0.0f,		0.0f,		0.0f,		0.0f,		0.0f },		// RESOLVE_MODE_NONE - expect clear value
   1111 		{ 0.04f,		0.04f,		0.04f,		0.04f,		0.04f,		0.04f },	// RESOLVE_MODE_SAMPLE_ZERO_BIT
   1112 		{ 0.03f,		0.135f,		0.135f,		0.135f,		0.135f,		0.135f },	// RESOLVE_MODE_AVERAGE_BIT
   1113 		{ 0.02f,		0.02f,		0.02f,		0.02f,		0.02f,		0.02f },	// RESOLVE_MODE_MIN_BIT
   1114 		{ 0.04f,		0.32f,		0.32f,		0.32f,		0.32f,		0.32f },	// RESOLVE_MODE_MAX_BIT
   1115 	};
   1116 	const deUint8 stencilExpectedValue[][6] =
   1117 	{
   1118 		// 2 samples	4		8		16		32		64
   1119 		{ 0u,			0u,		0u,		0u,		0u,		0u },	// RESOLVE_MODE_NONE - expect clear value
   1120 		{ 1u,			1u,		1u,		1u,		1u,		1u },	// RESOLVE_MODE_SAMPLE_ZERO_BIT
   1121 		{ 0u,			0u,		0u,		0u,		0u,		0u },	// RESOLVE_MODE_AVERAGE_BIT - not supported
   1122 		{ 1u,			1u,		1u,		1u,		1u,		1u },	// RESOLVE_MODE_MIN_BIT
   1123 		{ 255u,			255u,	255u,	255u,	255u,	255u },	// RESOLVE_MODE_MAX_BIT
   1124 	};
   1125 
   1126 	tcu::TestContext& testCtx(group->getTestContext());
   1127 
   1128 	// iterate over image data
   1129 	for	 (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
   1130 	{
   1131 		ImageTestData imageData = imagesTestData[imageDataNdx];
   1132 
   1133 		// create test group for image data
   1134 		de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName));
   1135 
   1136 		// iterate over sampleCounts
   1137 		for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
   1138 		{
   1139 			const deUint32		sampleCount	(sampleCounts[sampleCountNdx]);
   1140 			const std::string	sampleName	("samples_" + de::toString(sampleCount));
   1141 
   1142 			// create test group for sample count
   1143 			de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
   1144 
   1145 			// iterate over depth/stencil formats
   1146 			for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
   1147 			{
   1148 				const FormatData&			formatData	= formats[formatNdx];
   1149 				VkFormat					format		= formatData.format;
   1150 				const char*					formatName	= formatData.name;
   1151 				const bool					hasDepth	= formatData.hasDepth;
   1152 				const bool					hasStencil	= formatData.hasStencil;
   1153 				VkImageAspectFlags			aspectFlags	= (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
   1154 														  (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
   1155 
   1156 				// create test group for format
   1157 				de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName));
   1158 
   1159 				// iterate over depth resolve modes
   1160 				for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++)
   1161 				{
   1162 					// iterate over stencil resolve modes
   1163 					for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
   1164 					{
   1165 						// there is no average resolve mode for stencil - go to next iteration
   1166 						ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
   1167 						if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
   1168 							continue;
   1169 
   1170 						// if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
   1171 						// depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
   1172 						ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
   1173 						if ((dResolve.flag == VK_RESOLVE_MODE_NONE_KHR) && (sResolve.flag == VK_RESOLVE_MODE_NONE_KHR))
   1174 							continue;
   1175 
   1176 						// If there is no depth, the depth resolve mode should be NONE, or
   1177 						// match the stencil resolve mode.
   1178 						if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
   1179 							(dResolve.flag != sResolve.flag))
   1180 							continue;
   1181 
   1182 						// If there is no stencil, the stencil resmove mode should be NONE, or
   1183 						// match the depth resolve mode.
   1184 						if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
   1185 							(dResolve.flag != sResolve.flag))
   1186 							continue;
   1187 
   1188 						std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
   1189 
   1190 						if (hasDepth)
   1191 						{
   1192 							std::string	name			= baseName + "_testing_depth";
   1193 							const char*	testName		= name.c_str();
   1194 							float		expectedValue	= depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
   1195 
   1196 							const TestConfig testConfig =
   1197 							{
   1198 								format,
   1199 								imageData.width,
   1200 								imageData.height,
   1201 								1u,
   1202 								1u,
   1203 								0u,
   1204 								imageData.renderArea,
   1205 								aspectFlags,
   1206 								sampleCount,
   1207 								dResolve.flag,
   1208 								sResolve.flag,
   1209 								VB_DEPTH,
   1210 								imageData.clearValue,
   1211 								expectedValue,
   1212 								0u
   1213 							};
   1214 							formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
   1215 						}
   1216 						if (hasStencil)
   1217 						{
   1218 							std::string	name			= baseName + "_testing_stencil";
   1219 							const char*	testName		= name.c_str();
   1220 							deUint8		expectedValue	= stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
   1221 
   1222 							const TestConfig testConfig =
   1223 							{
   1224 								format,
   1225 								imageData.width,
   1226 								imageData.height,
   1227 								1u,
   1228 								1u,
   1229 								0u,
   1230 								imageData.renderArea,
   1231 								aspectFlags,
   1232 								sampleCount,
   1233 								dResolve.flag,
   1234 								sResolve.flag,
   1235 								VB_STENCIL,
   1236 								imageData.clearValue,
   1237 								0.0f,
   1238 								expectedValue
   1239 							};
   1240 							formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
   1241 						}
   1242 					}
   1243 				}
   1244 
   1245 				sampleGroup->addChild(formatGroup.release());
   1246 			}
   1247 
   1248 			imageGroup->addChild(sampleGroup.release());
   1249 		}
   1250 
   1251 		group->addChild(imageGroup.release());
   1252 	}
   1253 
   1254 	{
   1255 		// layered texture tests are done for all stencil modes and depth modes - not all combinations
   1256 		// Test checks if all layer are resolved in multi-layered framebuffer and if we can have a framebuffer
   1257 		// which starts at a layer other than zero. Both parts are tested together by rendering to layers
   1258 		// 4-6 and resolving to layers 1-3.
   1259 		ImageTestData layeredTextureTestData =
   1260 		{
   1261 			"image_2d_16_64_6", 16, 64, 6, {{ 10,  10}, {6, 54}}, {1.0f, 0x0}
   1262 		};
   1263 
   1264 		de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName));
   1265 
   1266 		for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
   1267 		{
   1268 			const deUint32		sampleCount	(sampleCounts[sampleCountNdx]);
   1269 			const std::string	sampleName	("samples_" + de::toString(sampleCount));
   1270 
   1271 			// create test group for sample count
   1272 			de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
   1273 
   1274 			// iterate over depth/stencil formats
   1275 			for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
   1276 			{
   1277 				const FormatData&			formatData	= formats[formatNdx];
   1278 				VkFormat					format		= formatData.format;
   1279 				const char*					formatName	= formatData.name;
   1280 				const bool					hasDepth	= formatData.hasDepth;
   1281 				const bool					hasStencil	= formatData.hasStencil;
   1282 				VkImageAspectFlags			aspectFlags	= (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
   1283 														  (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
   1284 
   1285 				// create test group for format
   1286 				de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName));
   1287 
   1288 				for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
   1289 				{
   1290 					ResolveModeData& mode = resolveModes[resolveModeNdx];
   1291 
   1292 					if (hasDepth)
   1293 					{
   1294 						std::string	name			= "depth_" + mode.name;
   1295 						const char*	testName		= name.c_str();
   1296 						float		expectedValue	= depthExpectedValue[resolveModeNdx][sampleCountNdx];
   1297 						const TestConfig testConfig =
   1298 						{
   1299 							format,
   1300 							layeredTextureTestData.width,
   1301 							layeredTextureTestData.height,
   1302 							layeredTextureTestData.imageLayers,
   1303 							3u,
   1304 							0u,
   1305 							layeredTextureTestData.renderArea,
   1306 							aspectFlags,
   1307 							sampleCount,
   1308 							mode.flag,
   1309 							VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
   1310 							VB_DEPTH,
   1311 							layeredTextureTestData.clearValue,
   1312 							expectedValue,
   1313 							0u
   1314 						};
   1315 						formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
   1316 					}
   1317 
   1318 					// there is no average resolve mode for stencil - go to next iteration
   1319 					if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
   1320 						continue;
   1321 
   1322 					if (hasStencil)
   1323 					{
   1324 						std::string	name			= "stencil_" + mode.name;
   1325 						const char*	testName		= name.c_str();
   1326 						deUint8		expectedValue	= stencilExpectedValue[resolveModeNdx][sampleCountNdx];
   1327 						const TestConfig testConfig =
   1328 						{
   1329 							format,
   1330 							layeredTextureTestData.width,
   1331 							layeredTextureTestData.height,
   1332 							layeredTextureTestData.imageLayers,
   1333 							3u,
   1334 							0u,
   1335 							layeredTextureTestData.renderArea,
   1336 							aspectFlags,
   1337 							sampleCount,
   1338 							VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
   1339 							mode.flag,
   1340 							VB_STENCIL,
   1341 							layeredTextureTestData.clearValue,
   1342 							0.0f,
   1343 							expectedValue
   1344 						};
   1345 						formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
   1346 					}
   1347 				}
   1348 				sampleGroup->addChild(formatGroup.release());
   1349 			}
   1350 			imageGroup->addChild(sampleGroup.release());
   1351 		}
   1352 
   1353 		group->addChild(imageGroup.release());
   1354 	}
   1355 }
   1356 
   1357 } // anonymous
   1358 
   1359 tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx)
   1360 {
   1361 	return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests);
   1362 }
   1363 
   1364 } // vkt
   1365