Home | History | Annotate | Download | only in pipeline
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 The Khronos Group Inc.
      6  * Copyright (c) 2015 Imagination Technologies Ltd.
      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 Depth Tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktPipelineDepthTests.hpp"
     26 #include "vktPipelineClearUtil.hpp"
     27 #include "vktPipelineImageUtil.hpp"
     28 #include "vktPipelineVertexUtil.hpp"
     29 #include "vktPipelineReferenceRenderer.hpp"
     30 #include "vktTestCase.hpp"
     31 #include "vktTestCaseUtil.hpp"
     32 #include "vkImageUtil.hpp"
     33 #include "vkMemUtil.hpp"
     34 #include "vkPrograms.hpp"
     35 #include "vkQueryUtil.hpp"
     36 #include "vkRef.hpp"
     37 #include "vkRefUtil.hpp"
     38 #include "vkTypeUtil.hpp"
     39 #include "tcuImageCompare.hpp"
     40 #include "deUniquePtr.hpp"
     41 #include "deStringUtil.hpp"
     42 #include "deMemory.h"
     43 
     44 #include <sstream>
     45 #include <vector>
     46 
     47 namespace vkt
     48 {
     49 namespace pipeline
     50 {
     51 
     52 using namespace vk;
     53 
     54 namespace
     55 {
     56 
     57 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
     58 {
     59 	VkFormatProperties formatProps;
     60 
     61 	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
     62 
     63 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
     64 }
     65 
     66 tcu::TestStatus testSupportsDepthStencilFormat (Context& context, VkFormat format)
     67 {
     68 	DE_ASSERT(vk::isDepthStencilFormat(format));
     69 
     70 	if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
     71 		return tcu::TestStatus::pass("Format can be used in depth/stencil attachment");
     72 	else
     73 		return tcu::TestStatus::fail("Unsupported depth/stencil attachment format");
     74 }
     75 
     76 tcu::TestStatus testSupportsAtLeastOneDepthStencilFormat (Context& context, const std::vector<VkFormat> formats)
     77 {
     78 	std::ostringstream	supportedFormatsMsg;
     79 	bool				pass					= false;
     80 
     81 	DE_ASSERT(!formats.empty());
     82 
     83 	for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++)
     84 	{
     85 		const VkFormat format = formats[formatNdx];
     86 
     87 		DE_ASSERT(vk::isDepthStencilFormat(format));
     88 
     89 		if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
     90 		{
     91 			pass = true;
     92 			supportedFormatsMsg << vk::getFormatName(format);
     93 
     94 			if (formatNdx < formats.size() - 1)
     95 				supportedFormatsMsg << ", ";
     96 		}
     97 	}
     98 
     99 	if (pass)
    100 		return tcu::TestStatus::pass(std::string("Supported depth/stencil formats: ") + supportedFormatsMsg.str());
    101 	else
    102 		return tcu::TestStatus::fail("All depth/stencil formats are unsupported");
    103 }
    104 
    105 class DepthTest : public vkt::TestCase
    106 {
    107 public:
    108 	enum
    109 	{
    110 		QUAD_COUNT = 4
    111 	};
    112 
    113 	static const float					quadDepths[QUAD_COUNT];
    114 
    115 										DepthTest				(tcu::TestContext&		testContext,
    116 																 const std::string&		name,
    117 																 const std::string&		description,
    118 																 const VkFormat			depthFormat,
    119 																 const VkCompareOp		depthCompareOps[QUAD_COUNT]);
    120 	virtual								~DepthTest				(void);
    121 	virtual void						initPrograms			(SourceCollections& programCollection) const;
    122 	virtual TestInstance*				createInstance			(Context& context) const;
    123 
    124 private:
    125 	const VkFormat						m_depthFormat;
    126 	VkCompareOp							m_depthCompareOps[QUAD_COUNT];
    127 };
    128 
    129 class DepthTestInstance : public vkt::TestInstance
    130 {
    131 public:
    132 										DepthTestInstance		(Context& context, const VkFormat depthFormat, const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT]);
    133 	virtual								~DepthTestInstance		(void);
    134 	virtual tcu::TestStatus				iterate					(void);
    135 
    136 private:
    137 	tcu::TestStatus						verifyImage				(void);
    138 
    139 private:
    140 	VkCompareOp							m_depthCompareOps[DepthTest::QUAD_COUNT];
    141 	const tcu::UVec2					m_renderSize;
    142 	const VkFormat						m_colorFormat;
    143 	const VkFormat						m_depthFormat;
    144 	VkImageSubresourceRange				m_depthImageSubresourceRange;
    145 
    146 	Move<VkImage>						m_colorImage;
    147 	de::MovePtr<Allocation>				m_colorImageAlloc;
    148 	Move<VkImage>						m_depthImage;
    149 	de::MovePtr<Allocation>				m_depthImageAlloc;
    150 	Move<VkImageView>					m_colorAttachmentView;
    151 	Move<VkImageView>					m_depthAttachmentView;
    152 	Move<VkRenderPass>					m_renderPass;
    153 	Move<VkFramebuffer>					m_framebuffer;
    154 
    155 	Move<VkShaderModule>				m_vertexShaderModule;
    156 	Move<VkShaderModule>				m_fragmentShaderModule;
    157 
    158 	Move<VkBuffer>						m_vertexBuffer;
    159 	std::vector<Vertex4RGBA>			m_vertices;
    160 	de::MovePtr<Allocation>				m_vertexBufferAlloc;
    161 
    162 	Move<VkPipelineLayout>				m_pipelineLayout;
    163 	Move<VkPipeline>					m_graphicsPipelines[DepthTest::QUAD_COUNT];
    164 
    165 	Move<VkCommandPool>					m_cmdPool;
    166 	Move<VkCommandBuffer>				m_cmdBuffer;
    167 
    168 	Move<VkFence>						m_fence;
    169 };
    170 
    171 const float DepthTest::quadDepths[QUAD_COUNT] =
    172 {
    173 	0.1f,
    174 	0.0f,
    175 	0.3f,
    176 	0.2f
    177 };
    178 
    179 DepthTest::DepthTest (tcu::TestContext&		testContext,
    180 					  const std::string&	name,
    181 					  const std::string&	description,
    182 					  const VkFormat		depthFormat,
    183 					  const VkCompareOp		depthCompareOps[QUAD_COUNT])
    184 	: vkt::TestCase	(testContext, name, description)
    185 	, m_depthFormat	(depthFormat)
    186 {
    187 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT);
    188 }
    189 
    190 DepthTest::~DepthTest (void)
    191 {
    192 }
    193 
    194 TestInstance* DepthTest::createInstance (Context& context) const
    195 {
    196 	return new DepthTestInstance(context, m_depthFormat, m_depthCompareOps);
    197 }
    198 
    199 void DepthTest::initPrograms (SourceCollections& programCollection) const
    200 {
    201 	programCollection.glslSources.add("color_vert") << glu::VertexSource(
    202 		"#version 310 es\n"
    203 		"layout(location = 0) in vec4 position;\n"
    204 		"layout(location = 1) in vec4 color;\n"
    205 		"layout(location = 0) out highp vec4 vtxColor;\n"
    206 		"void main (void)\n"
    207 		"{\n"
    208 		"	gl_Position = position;\n"
    209 		"	vtxColor = color;\n"
    210 		"}\n");
    211 
    212 	programCollection.glslSources.add("color_frag") << glu::FragmentSource(
    213 		"#version 310 es\n"
    214 		"layout(location = 0) in highp vec4 vtxColor;\n"
    215 		"layout(location = 0) out highp vec4 fragColor;\n"
    216 		"void main (void)\n"
    217 		"{\n"
    218 		"	fragColor = vtxColor;\n"
    219 		"}\n");
    220 }
    221 
    222 DepthTestInstance::DepthTestInstance (Context&				context,
    223 									  const VkFormat		depthFormat,
    224 									  const VkCompareOp		depthCompareOps[DepthTest::QUAD_COUNT])
    225 	: vkt::TestInstance	(context)
    226 	, m_renderSize		(32, 32)
    227 	, m_colorFormat		(VK_FORMAT_R8G8B8A8_UNORM)
    228 	, m_depthFormat		(depthFormat)
    229 {
    230 	const DeviceInterface&		vk						= context.getDeviceInterface();
    231 	const VkDevice				vkDevice				= context.getDevice();
    232 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
    233 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
    234 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
    235 
    236 	// Copy depth operators
    237 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT);
    238 
    239 	// Create color image
    240 	{
    241 		const VkImageCreateInfo colorImageParams =
    242 		{
    243 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
    244 			DE_NULL,																	// const void*				pNext;
    245 			0u,																			// VkImageCreateFlags		flags;
    246 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
    247 			m_colorFormat,																// VkFormat					format;
    248 			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
    249 			1u,																			// deUint32					mipLevels;
    250 			1u,																			// deUint32					arrayLayers;
    251 			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
    252 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
    253 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
    254 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
    255 			1u,																			// deUint32					queueFamilyIndexCount;
    256 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
    257 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
    258 		};
    259 
    260 		m_colorImage			= createImage(vk, vkDevice, &colorImageParams);
    261 
    262 		// Allocate and bind color image memory
    263 		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
    264 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
    265 	}
    266 
    267 	// Create depth image
    268 	{
    269 		// Check format support
    270 		if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat))
    271 			throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat));
    272 
    273 		const VkImageCreateInfo depthImageParams =
    274 		{
    275 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
    276 			DE_NULL,										// const void*				pNext;
    277 			0u,												// VkImageCreateFlags		flags;
    278 			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
    279 			m_depthFormat,									// VkFormat					format;
    280 			{ m_renderSize.x(), m_renderSize.y(), 1u },		// VkExtent3D				extent;
    281 			1u,												// deUint32					mipLevels;
    282 			1u,												// deUint32					arrayLayers;
    283 			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
    284 			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
    285 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,	// VkImageUsageFlags		usage;
    286 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
    287 			1u,												// deUint32					queueFamilyIndexCount;
    288 			&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
    289 			VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
    290 		};
    291 
    292 		m_depthImage = createImage(vk, vkDevice, &depthImageParams);
    293 
    294 		// Allocate and bind depth image memory
    295 		m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
    296 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
    297 
    298 		const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
    299 																									  : VK_IMAGE_ASPECT_DEPTH_BIT);
    300 		m_depthImageSubresourceRange    = makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers);
    301 	}
    302 
    303 	// Create color attachment view
    304 	{
    305 		const VkImageViewCreateInfo colorAttachmentViewParams =
    306 		{
    307 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
    308 			DE_NULL,										// const void*				pNext;
    309 			0u,												// VkImageViewCreateFlags	flags;
    310 			*m_colorImage,									// VkImage					image;
    311 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
    312 			m_colorFormat,									// VkFormat					format;
    313 			componentMappingRGBA,							// VkComponentMapping		components;
    314 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
    315 		};
    316 
    317 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
    318 	}
    319 
    320 	// Create depth attachment view
    321 	{
    322 		const VkImageViewCreateInfo depthAttachmentViewParams =
    323 		{
    324 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
    325 			DE_NULL,										// const void*				pNext;
    326 			0u,												// VkImageViewCreateFlags	flags;
    327 			*m_depthImage,									// VkImage					image;
    328 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
    329 			m_depthFormat,									// VkFormat					format;
    330 			componentMappingRGBA,							// VkComponentMapping		components;
    331 			m_depthImageSubresourceRange,					// VkImageSubresourceRange	subresourceRange;
    332 		};
    333 
    334 		m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
    335 	}
    336 
    337 	// Create render pass
    338 	{
    339 		const VkAttachmentDescription colorAttachmentDescription =
    340 		{
    341 			0u,													// VkAttachmentDescriptionFlags		flags;
    342 			m_colorFormat,										// VkFormat							format;
    343 			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
    344 			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
    345 			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
    346 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
    347 			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
    348 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
    349 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
    350 		};
    351 
    352 		const VkAttachmentDescription depthAttachmentDescription =
    353 		{
    354 			0u,													// VkAttachmentDescriptionFlags		flags;
    355 			m_depthFormat,										// VkFormat							format;
    356 			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
    357 			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
    358 			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				storeOp;
    359 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
    360 			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
    361 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
    362 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					finalLayout;
    363 		};
    364 
    365 		const VkAttachmentDescription attachments[2] =
    366 		{
    367 			colorAttachmentDescription,
    368 			depthAttachmentDescription
    369 		};
    370 
    371 		const VkAttachmentReference colorAttachmentReference =
    372 		{
    373 			0u,													// deUint32			attachment;
    374 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
    375 		};
    376 
    377 		const VkAttachmentReference depthAttachmentReference =
    378 		{
    379 			1u,													// deUint32			attachment;
    380 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
    381 		};
    382 
    383 		const VkSubpassDescription subpassDescription =
    384 		{
    385 			0u,													// VkSubpassDescriptionFlags		flags;
    386 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
    387 			0u,													// deUint32							inputAttachmentCount;
    388 			DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
    389 			1u,													// deUint32							colorAttachmentCount;
    390 			&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
    391 			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
    392 			&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
    393 			0u,													// deUint32							preserveAttachmentCount;
    394 			DE_NULL												// const VkAttachmentReference*		pPreserveAttachments;
    395 		};
    396 
    397 		const VkRenderPassCreateInfo renderPassParams =
    398 		{
    399 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
    400 			DE_NULL,											// const void*						pNext;
    401 			0u,													// VkRenderPassCreateFlags			flags;
    402 			2u,													// deUint32							attachmentCount;
    403 			attachments,										// const VkAttachmentDescription*	pAttachments;
    404 			1u,													// deUint32							subpassCount;
    405 			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
    406 			0u,													// deUint32							dependencyCount;
    407 			DE_NULL												// const VkSubpassDependency*		pDependencies;
    408 		};
    409 
    410 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
    411 	}
    412 
    413 	// Create framebuffer
    414 	{
    415 		const VkImageView attachmentBindInfos[2] =
    416 		{
    417 			*m_colorAttachmentView,
    418 			*m_depthAttachmentView,
    419 		};
    420 
    421 		const VkFramebufferCreateInfo framebufferParams =
    422 		{
    423 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
    424 			DE_NULL,											// const void*					pNext;
    425 			0u,													// VkFramebufferCreateFlags		flags;
    426 			*m_renderPass,										// VkRenderPass					renderPass;
    427 			2u,													// deUint32						attachmentCount;
    428 			attachmentBindInfos,								// const VkImageView*			pAttachments;
    429 			(deUint32)m_renderSize.x(),							// deUint32						width;
    430 			(deUint32)m_renderSize.y(),							// deUint32						height;
    431 			1u													// deUint32						layers;
    432 		};
    433 
    434 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
    435 	}
    436 
    437 	// Create pipeline layout
    438 	{
    439 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
    440 		{
    441 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
    442 			DE_NULL,											// const void*						pNext;
    443 			0u,													// VkPipelineLayoutCreateFlags		flags;
    444 			0u,													// deUint32							setLayoutCount;
    445 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
    446 			0u,													// deUint32							pushConstantRangeCount;
    447 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
    448 		};
    449 
    450 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
    451 	}
    452 
    453 	// Shader modules
    454 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
    455 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
    456 
    457 	// Create pipeline
    458 	{
    459 		const VkPipelineShaderStageCreateInfo shaderStages[2] =
    460 		{
    461 			{
    462 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
    463 				DE_NULL,												// const void*							pNext;
    464 				0u,														// VkPipelineShaderStageCreateFlags		flags;
    465 				VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage;
    466 				*m_vertexShaderModule,									// VkShaderModule						module;
    467 				"main",													// const char*							pName;
    468 				DE_NULL													// const VkSpecializationInfo*			pSpecializationInfo;
    469 			},
    470 			{
    471 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
    472 				DE_NULL,												// const void*							pNext;
    473 				0u,														// VkPipelineShaderStageCreateFlags		flags;
    474 				VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits				stage;
    475 				*m_fragmentShaderModule,								// VkShaderModule						module;
    476 				"main",													// const char*							pName;
    477 				DE_NULL													// const VkSpecializationInfo*			pSpecializationInfo;
    478 			}
    479 		};
    480 
    481 		const VkVertexInputBindingDescription vertexInputBindingDescription =
    482 		{
    483 			0u,									// deUint32					binding;
    484 			sizeof(Vertex4RGBA),				// deUint32					strideInBytes;
    485 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputStepRate	inputRate;
    486 		};
    487 
    488 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
    489 		{
    490 			{
    491 				0u,									// deUint32	location;
    492 				0u,									// deUint32	binding;
    493 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
    494 				0u									// deUint32	offset;
    495 			},
    496 			{
    497 				1u,									// deUint32	location;
    498 				0u,									// deUint32	binding;
    499 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
    500 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
    501 			}
    502 		};
    503 
    504 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
    505 		{
    506 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
    507 			DE_NULL,														// const void*								pNext;
    508 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
    509 			1u,																// deUint32									vertexBindingDescriptionCount;
    510 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
    511 			2u,																// deUint32									vertexAttributeDescriptionCount;
    512 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
    513 		};
    514 
    515 		const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
    516 		{
    517 			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
    518 			DE_NULL,														// const void*								pNext;
    519 			0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
    520 			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
    521 			false															// VkBool32									primitiveRestartEnable;
    522 		};
    523 
    524 		const VkViewport viewport =
    525 		{
    526 			0.0f,						// float	x;
    527 			0.0f,						// float	y;
    528 			(float)m_renderSize.x(),	// float	width;
    529 			(float)m_renderSize.y(),	// float	height;
    530 			0.0f,						// float	minDepth;
    531 			1.0f						// float	maxDepth;
    532 		};
    533 		const VkRect2D scissor =
    534 		{
    535 			{ 0, 0 },												// VkOffset2D  offset;
    536 			{ m_renderSize.x(), m_renderSize.y() }					// VkExtent2D  extent;
    537 		};
    538 		const VkPipelineViewportStateCreateInfo viewportStateParams =
    539 		{
    540 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
    541 			DE_NULL,														// const void*							pNext;
    542 			0u,																// VkPipelineViewportStateCreateFlags	flags;
    543 			1u,																// deUint32								viewportCount;
    544 			&viewport,														// const VkViewport*					pViewports;
    545 			1u,																// deUint32								scissorCount;
    546 			&scissor														// const VkRect2D*						pScissors;
    547 		};
    548 
    549 		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
    550 		{
    551 			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
    552 			DE_NULL,														// const void*								pNext;
    553 			0u,																// VkPipelineRasterizationStateCreateFlags	flags;
    554 			false,															// VkBool32									depthClampEnable;
    555 			false,															// VkBool32									rasterizerDiscardEnable;
    556 			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
    557 			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
    558 			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
    559 			VK_FALSE,														// VkBool32									depthBiasEnable;
    560 			0.0f,															// float									depthBiasConstantFactor;
    561 			0.0f,															// float									depthBiasClamp;
    562 			0.0f,															// float									depthBiasSlopeFactor;
    563 			1.0f,															// float									lineWidth;
    564 		};
    565 
    566 		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
    567 		{
    568 			false,																		// VkBool32					blendEnable;
    569 			VK_BLEND_FACTOR_ONE,														// VkBlendFactor			srcColorBlendFactor;
    570 			VK_BLEND_FACTOR_ZERO,														// VkBlendFactor			dstColorBlendFactor;
    571 			VK_BLEND_OP_ADD,															// VkBlendOp				colorBlendOp;
    572 			VK_BLEND_FACTOR_ONE,														// VkBlendFactor			srcAlphaBlendFactor;
    573 			VK_BLEND_FACTOR_ZERO,														// VkBlendFactor			dstAlphaBlendFactor;
    574 			VK_BLEND_OP_ADD,															// VkBlendOp				alphaBlendOp;
    575 			VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |						// VkColorComponentFlags	colorWriteMask;
    576 				VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
    577 		};
    578 
    579 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
    580 		{
    581 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
    582 			DE_NULL,													// const void*									pNext;
    583 			0,															// VkPipelineColorBlendStateCreateFlags			flags;
    584 			false,														// VkBool32										logicOpEnable;
    585 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
    586 			1u,															// deUint32										attachmentCount;
    587 			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
    588 			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
    589 		};
    590 
    591 		const VkPipelineMultisampleStateCreateInfo	multisampleStateParams	=
    592 		{
    593 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
    594 			DE_NULL,													// const void*								pNext;
    595 			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
    596 			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
    597 			false,														// VkBool32									sampleShadingEnable;
    598 			0.0f,														// float									minSampleShading;
    599 			DE_NULL,													// const VkSampleMask*						pSampleMask;
    600 			false,														// VkBool32									alphaToCoverageEnable;
    601 			false														// VkBool32									alphaToOneEnable;
    602 		};
    603 		VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
    604 		{
    605 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
    606 			DE_NULL,													// const void*								pNext;
    607 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
    608 			true,														// VkBool32									depthTestEnable;
    609 			true,														// VkBool32									depthWriteEnable;
    610 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
    611 			false,														// VkBool32									depthBoundsTestEnable;
    612 			false,														// VkBool32									stencilTestEnable;
    613 			// VkStencilOpState	front;
    614 			{
    615 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
    616 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
    617 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
    618 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
    619 				0u,						// deUint32		compareMask;
    620 				0u,						// deUint32		writeMask;
    621 				0u,						// deUint32		reference;
    622 			},
    623 			// VkStencilOpState	back;
    624 			{
    625 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
    626 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
    627 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
    628 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
    629 				0u,						// deUint32		compareMask;
    630 				0u,						// deUint32		writeMask;
    631 				0u,						// deUint32		reference;
    632 			},
    633 			0.0f,														// float			minDepthBounds;
    634 			1.0f,														// float			maxDepthBounds;
    635 		};
    636 
    637 		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
    638 		{
    639 			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
    640 			DE_NULL,											// const void*										pNext;
    641 			0u,													// VkPipelineCreateFlags							flags;
    642 			2u,													// deUint32											stageCount;
    643 			shaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
    644 			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
    645 			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
    646 			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
    647 			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
    648 			&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
    649 			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
    650 			&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
    651 			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
    652 			(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
    653 			*m_pipelineLayout,									// VkPipelineLayout									layout;
    654 			*m_renderPass,										// VkRenderPass										renderPass;
    655 			0u,													// deUint32											subpass;
    656 			0u,													// VkPipeline										basePipelineHandle;
    657 			0u,													// deInt32											basePipelineIndex;
    658 		};
    659 
    660 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
    661 		{
    662 			depthStencilStateParams.depthCompareOp	= depthCompareOps[quadNdx];
    663 			m_graphicsPipelines[quadNdx]			= createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
    664 		}
    665 	}
    666 
    667 	// Create vertex buffer
    668 	{
    669 		const VkBufferCreateInfo vertexBufferParams =
    670 		{
    671 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    672 			DE_NULL,									// const void*			pNext;
    673 			0u,											// VkBufferCreateFlags	flags;
    674 			1024u,										// VkDeviceSize			size;
    675 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
    676 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    677 			1u,											// deUint32				queueFamilyIndexCount;
    678 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
    679 		};
    680 
    681 		m_vertices			= createOverlappingQuads();
    682 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
    683 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
    684 
    685 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
    686 
    687 		// Adjust depths
    688 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
    689 			for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
    690 				m_vertices[quadNdx * 6 + vertexNdx].position.z() = DepthTest::quadDepths[quadNdx];
    691 
    692 		// Load vertices into vertex buffer
    693 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
    694 		flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
    695 	}
    696 
    697 	// Create command pool
    698 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
    699 
    700 	// Create command buffer
    701 	{
    702 		const VkCommandBufferBeginInfo cmdBufferBeginInfo =
    703 		{
    704 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
    705 			DE_NULL,										// const void*						pNext;
    706 			0u,												// VkCommandBufferUsageFlags		flags;
    707 			(const VkCommandBufferInheritanceInfo*)DE_NULL,
    708 		};
    709 
    710 		const VkClearValue attachmentClearValues[2] =
    711 		{
    712 			defaultClearValue(m_colorFormat),
    713 			defaultClearValue(m_depthFormat),
    714 		};
    715 
    716 		const VkRenderPassBeginInfo renderPassBeginInfo =
    717 		{
    718 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
    719 			DE_NULL,												// const void*			pNext;
    720 			*m_renderPass,											// VkRenderPass			renderPass;
    721 			*m_framebuffer,											// VkFramebuffer		framebuffer;
    722 			{ { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } },	// VkRect2D				renderArea;
    723 			2,														// deUint32				clearValueCount;
    724 			attachmentClearValues									// const VkClearValue*	pClearValues;
    725 		};
    726 
    727 		const VkImageMemoryBarrier imageLayoutBarriers[] =
    728 		{
    729 			// color image layout transition
    730 			{
    731 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
    732 				DE_NULL,																// const void*                pNext;
    733 				(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
    734 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags              dstAccessMask;
    735 				VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
    736 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,								// VkImageLayout              newLayout;
    737 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
    738 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
    739 				*m_colorImage,															// VkImage                    image;
    740 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange    subresourceRange;
    741 			},
    742 			// depth image layout transition
    743 			{
    744 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
    745 				DE_NULL,																// const void*                pNext;
    746 				(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
    747 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,							// VkAccessFlags              dstAccessMask;
    748 				VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
    749 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,						// VkImageLayout              newLayout;
    750 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
    751 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
    752 				*m_depthImage,															// VkImage                    image;
    753 				m_depthImageSubresourceRange,											// VkImageSubresourceRange    subresourceRange;
    754 			},
    755 		};
    756 
    757 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
    758 
    759 		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
    760 
    761 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
    762 			0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageLayoutBarriers), imageLayoutBarriers);
    763 
    764 		vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
    765 
    766 		const VkDeviceSize		quadOffset		= (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
    767 
    768 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
    769 		{
    770 			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
    771 
    772 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
    773 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
    774 			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
    775 		}
    776 
    777 		vk.cmdEndRenderPass(*m_cmdBuffer);
    778 		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
    779 	}
    780 
    781 	// Create fence
    782 	m_fence = createFence(vk, vkDevice);
    783 }
    784 
    785 DepthTestInstance::~DepthTestInstance (void)
    786 {
    787 }
    788 
    789 tcu::TestStatus DepthTestInstance::iterate (void)
    790 {
    791 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
    792 	const VkDevice				vkDevice	= m_context.getDevice();
    793 	const VkQueue				queue		= m_context.getUniversalQueue();
    794 	const VkSubmitInfo			submitInfo	=
    795 	{
    796 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
    797 		DE_NULL,						// const void*				pNext;
    798 		0u,								// deUint32					waitSemaphoreCount;
    799 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
    800 		(const VkPipelineStageFlags*)DE_NULL,
    801 		1u,								// deUint32					commandBufferCount;
    802 		&m_cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
    803 		0u,								// deUint32					signalSemaphoreCount;
    804 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
    805 	};
    806 
    807 	VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
    808 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
    809 	VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
    810 
    811 	return verifyImage();
    812 }
    813 
    814 tcu::TestStatus DepthTestInstance::verifyImage (void)
    815 {
    816 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
    817 	const tcu::TextureFormat	tcuDepthFormat	= mapVkFormat(m_depthFormat);
    818 	const ColorVertexShader		vertexShader;
    819 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
    820 	const rr::Program			program			(&vertexShader, &fragmentShader);
    821 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
    822 	bool						compareOk		= false;
    823 
    824 	// Render reference image
    825 	{
    826 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
    827 		{
    828 			// Set depth state
    829 			rr::RenderState renderState(refRenderer.getViewportState());
    830 			renderState.fragOps.depthTestEnabled = true;
    831 			renderState.fragOps.depthFunc = mapVkCompareOp(m_depthCompareOps[quadNdx]);
    832 
    833 			refRenderer.draw(renderState,
    834 							 rr::PRIMITIVETYPE_TRIANGLES,
    835 							 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
    836 													  m_vertices.begin() + (quadNdx + 1) * 6));
    837 		}
    838 	}
    839 
    840 	// Compare result with reference image
    841 	{
    842 		const DeviceInterface&			vk					= m_context.getDeviceInterface();
    843 		const VkDevice					vkDevice			= m_context.getDevice();
    844 		const VkQueue					queue				= m_context.getUniversalQueue();
    845 		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
    846 		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
    847 		de::MovePtr<tcu::TextureLevel>	result				= readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
    848 
    849 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
    850 															  "IntImageCompare",
    851 															  "Image comparison",
    852 															  refRenderer.getAccess(),
    853 															  result->getAccess(),
    854 															  tcu::UVec4(2, 2, 2, 2),
    855 															  tcu::IVec3(1, 1, 0),
    856 															  true,
    857 															  tcu::COMPARE_LOG_RESULT);
    858 	}
    859 
    860 	if (compareOk)
    861 		return tcu::TestStatus::pass("Result image matches reference");
    862 	else
    863 		return tcu::TestStatus::fail("Image mismatch");
    864 }
    865 
    866 std::string getFormatCaseName (const VkFormat format)
    867 {
    868 	const std::string	fullName	= getFormatName(format);
    869 
    870 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
    871 
    872 	return de::toLower(fullName.substr(10));
    873 }
    874 
    875 std::string	getCompareOpsName (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
    876 {
    877 	std::ostringstream name;
    878 
    879 	for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
    880 	{
    881 		const std::string	fullOpName	= getCompareOpName(quadDepthOps[quadNdx]);
    882 
    883 		DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_"));
    884 
    885 		name << de::toLower(fullOpName.substr(14));
    886 
    887 		if (quadNdx < DepthTest::QUAD_COUNT - 1)
    888 			name << "_";
    889 	}
    890 
    891 	return name.str();
    892 }
    893 
    894 std::string	getCompareOpsDescription (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
    895 {
    896 	std::ostringstream desc;
    897 	desc << "Draws " << DepthTest::QUAD_COUNT << " quads with depth compare ops: ";
    898 
    899 	for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
    900 	{
    901 		desc << getCompareOpName(quadDepthOps[quadNdx]) << " at depth " << DepthTest::quadDepths[quadNdx];
    902 
    903 		if (quadNdx < DepthTest::QUAD_COUNT - 1)
    904 			desc << ", ";
    905 	}
    906 	return desc.str();
    907 }
    908 
    909 
    910 } // anonymous
    911 
    912 tcu::TestCaseGroup* createDepthTests (tcu::TestContext& testCtx)
    913 {
    914 	const VkFormat depthFormats[] =
    915 	{
    916 		VK_FORMAT_D16_UNORM,
    917 		VK_FORMAT_X8_D24_UNORM_PACK32,
    918 		VK_FORMAT_D32_SFLOAT,
    919 		VK_FORMAT_D16_UNORM_S8_UINT,
    920 		VK_FORMAT_D24_UNORM_S8_UINT,
    921 		VK_FORMAT_D32_SFLOAT_S8_UINT
    922 	};
    923 
    924 	// Each entry configures the depth compare operators of QUAD_COUNT quads.
    925 	// All entries cover pair-wise combinations of compare operators.
    926 	const VkCompareOp depthOps[][DepthTest::QUAD_COUNT] =
    927 	{
    928 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL },
    929 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER },
    930 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL },
    931 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
    932 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
    933 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS },
    934 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER },
    935 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
    936 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS },
    937 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
    938 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
    939 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL },
    940 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL },
    941 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS },
    942 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
    943 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS },
    944 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
    945 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER },
    946 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
    947 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
    948 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER },
    949 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER },
    950 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL },
    951 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
    952 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL },
    953 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL },
    954 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS },
    955 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
    956 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER },
    957 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
    958 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL },
    959 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
    960 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS },
    961 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL },
    962 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER },
    963 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL },
    964 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL },
    965 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER },
    966 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL },
    967 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL },
    968 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
    969 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS },
    970 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS },
    971 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL },
    972 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
    973 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL },
    974 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
    975 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
    976 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
    977 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS },
    978 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS },
    979 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER },
    980 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL },
    981 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
    982 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS },
    983 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
    984 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL },
    985 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
    986 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL },
    987 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER },
    988 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER },
    989 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
    990 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL },
    991 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
    992 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER },
    993 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
    994 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
    995 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
    996 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
    997 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER },
    998 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
    999 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL },
   1000 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS },
   1001 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER }
   1002 	};
   1003 
   1004 	de::MovePtr<tcu::TestCaseGroup> depthTests (new tcu::TestCaseGroup(testCtx, "depth", "Depth tests"));
   1005 
   1006 	// Tests for format features
   1007 	{
   1008 		de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests (new tcu::TestCaseGroup(testCtx, "format_features", "Checks depth format features"));
   1009 
   1010 		// Formats that must be supported in all implementations
   1011 		addFunctionCase(formatFeaturesTests.get(),
   1012 						"support_d16_unorm",
   1013 						"Tests if VK_FORMAT_D16_UNORM is supported as depth/stencil attachment format",
   1014 						testSupportsDepthStencilFormat,
   1015 						VK_FORMAT_D16_UNORM);
   1016 
   1017 		// Sets where at least one of the formats must be supported
   1018 		const VkFormat	depthOnlyFormats[]		= { VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT };
   1019 		const VkFormat	depthStencilFormats[]	= { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
   1020 
   1021 		addFunctionCase(formatFeaturesTests.get(),
   1022 						"support_d24_unorm_or_d32_sfloat",
   1023 						"Tests if any of VK_FORMAT_D24_UNORM_X8 or VK_FORMAT_D32_SFLOAT are supported as depth/stencil attachment format",
   1024 						testSupportsAtLeastOneDepthStencilFormat,
   1025 						std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats)));
   1026 
   1027 		addFunctionCase(formatFeaturesTests.get(),
   1028 						"support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint",
   1029 						"Tests if any of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT are supported as depth/stencil attachment format",
   1030 						testSupportsAtLeastOneDepthStencilFormat,
   1031 						std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats)));
   1032 
   1033 		depthTests->addChild(formatFeaturesTests.release());
   1034 	}
   1035 
   1036 	// Tests for format and compare operators
   1037 	{
   1038 		de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different depth formats"));
   1039 
   1040 		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++)
   1041 		{
   1042 			de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
   1043 																					getFormatCaseName(depthFormats[formatNdx]).c_str(),
   1044 																					(std::string("Uses format ") + getFormatName(depthFormats[formatNdx])).c_str()));
   1045 			de::MovePtr<tcu::TestCaseGroup>	compareOpsTests	(new tcu::TestCaseGroup(testCtx, "compare_ops", "Combines depth compare operators"));
   1046 
   1047 			for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++)
   1048 			{
   1049 				compareOpsTests->addChild(new DepthTest(testCtx,
   1050 														getCompareOpsName(depthOps[opsNdx]),
   1051 														getCompareOpsDescription(depthOps[opsNdx]),
   1052 														depthFormats[formatNdx],
   1053 														depthOps[opsNdx]));
   1054 			}
   1055 			formatTest->addChild(compareOpsTests.release());
   1056 			formatTests->addChild(formatTest.release());
   1057 		}
   1058 		depthTests->addChild(formatTests.release());
   1059 	}
   1060 
   1061 	return depthTests.release();
   1062 }
   1063 
   1064 } // pipeline
   1065 } // vkt
   1066