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
47namespace vkt
48{
49namespace pipeline
50{
51
52using namespace vk;
53
54namespace
55{
56
57bool 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
66tcu::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
76tcu::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
105class DepthTest : public vkt::TestCase
106{
107public:
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
124private:
125	const VkFormat						m_depthFormat;
126	VkCompareOp							m_depthCompareOps[QUAD_COUNT];
127};
128
129class DepthTestInstance : public vkt::TestInstance
130{
131public:
132										DepthTestInstance		(Context& context, const VkFormat depthFormat, const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT]);
133	virtual								~DepthTestInstance		(void);
134	virtual tcu::TestStatus				iterate					(void);
135
136private:
137	tcu::TestStatus						verifyImage				(void);
138
139private:
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
171const float DepthTest::quadDepths[QUAD_COUNT] =
172{
173	0.1f,
174	0.0f,
175	0.3f,
176	0.2f
177};
178
179DepthTest::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
190DepthTest::~DepthTest (void)
191{
192}
193
194TestInstance* DepthTest::createInstance (Context& context) const
195{
196	return new DepthTestInstance(context, m_depthFormat, m_depthCompareOps);
197}
198
199void 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
222DepthTestInstance::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
785DepthTestInstance::~DepthTestInstance (void)
786{
787}
788
789tcu::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
814tcu::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
866std::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
875std::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
894std::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
912tcu::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