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 "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "deUniquePtr.hpp"
43 #include "deStringUtil.hpp"
44 #include "deMemory.h"
45 
46 #include <sstream>
47 #include <vector>
48 
49 namespace vkt
50 {
51 namespace pipeline
52 {
53 
54 using namespace vk;
55 
56 namespace
57 {
58 
isSupportedDepthStencilFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)59 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
60 {
61 	VkFormatProperties formatProps;
62 
63 	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
64 
65 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
66 }
67 
testSupportsDepthStencilFormat(Context & context,VkFormat format)68 tcu::TestStatus testSupportsDepthStencilFormat (Context& context, VkFormat format)
69 {
70 	DE_ASSERT(vk::isDepthStencilFormat(format));
71 
72 	if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
73 		return tcu::TestStatus::pass("Format can be used in depth/stencil attachment");
74 	else
75 		return tcu::TestStatus::fail("Unsupported depth/stencil attachment format");
76 }
77 
testSupportsAtLeastOneDepthStencilFormat(Context & context,const std::vector<VkFormat> formats)78 tcu::TestStatus testSupportsAtLeastOneDepthStencilFormat (Context& context, const std::vector<VkFormat> formats)
79 {
80 	std::ostringstream	supportedFormatsMsg;
81 	bool				pass					= false;
82 
83 	DE_ASSERT(!formats.empty());
84 
85 	for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++)
86 	{
87 		const VkFormat format = formats[formatNdx];
88 
89 		DE_ASSERT(vk::isDepthStencilFormat(format));
90 
91 		if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
92 		{
93 			pass = true;
94 			supportedFormatsMsg << vk::getFormatName(format);
95 
96 			if (formatNdx < formats.size() - 1)
97 				supportedFormatsMsg << ", ";
98 		}
99 	}
100 
101 	if (pass)
102 		return tcu::TestStatus::pass(std::string("Supported depth/stencil formats: ") + supportedFormatsMsg.str());
103 	else
104 		return tcu::TestStatus::fail("All depth/stencil formats are unsupported");
105 }
106 
107 class DepthTest : public vkt::TestCase
108 {
109 public:
110 	enum
111 	{
112 		QUAD_COUNT = 4
113 	};
114 
115 	static const float					quadDepths[QUAD_COUNT];
116 
117 										DepthTest				(tcu::TestContext&		testContext,
118 																 const std::string&		name,
119 																 const std::string&		description,
120 																 const VkFormat			depthFormat,
121 																 const VkCompareOp		depthCompareOps[QUAD_COUNT],
122 																 const bool				depthBoundsTestEnable			= false,
123 																 const float			depthBoundsMin					= 0.0f,
124 																 const float			depthBoundsMax					= 1.0f,
125 																 const bool				depthTestEnable					= true,
126 																 const bool				stencilTestEnable				= false);
127 	virtual								~DepthTest				(void);
128 	virtual void						initPrograms			(SourceCollections& programCollection) const;
129 	virtual TestInstance*				createInstance			(Context& context) const;
130 
131 private:
132 	const VkFormat						m_depthFormat;
133 	const bool							m_depthBoundsTestEnable;
134 	const float							m_depthBoundsMin;
135 	const float							m_depthBoundsMax;
136 	const bool							m_depthTestEnable;
137 	const bool							m_stencilTestEnable;
138 	VkCompareOp							m_depthCompareOps[QUAD_COUNT];
139 };
140 
141 class DepthTestInstance : public vkt::TestInstance
142 {
143 public:
144 										DepthTestInstance		(Context&			context,
145 																 const VkFormat		depthFormat,
146 																 const VkCompareOp	depthCompareOps[DepthTest::QUAD_COUNT],
147 																 const bool			depthBoundsTestEnable,
148 																 const float		depthBoundsMin,
149 																 const float		depthBoundsMax,
150 																 const bool			depthTestEnable,
151 																 const bool			stencilTestEnable);
152 	virtual								~DepthTestInstance		(void);
153 	virtual tcu::TestStatus				iterate					(void);
154 
155 private:
156 	tcu::TestStatus						verifyImage				(void);
157 
158 private:
159 	VkCompareOp							m_depthCompareOps[DepthTest::QUAD_COUNT];
160 	const tcu::UVec2					m_renderSize;
161 	const VkFormat						m_colorFormat;
162 	const VkFormat						m_depthFormat;
163 	const bool							m_depthBoundsTestEnable;
164 	const float							m_depthBoundsMin;
165 	const float							m_depthBoundsMax;
166 	const bool							m_depthTestEnable;
167 	const bool							m_stencilTestEnable;
168 	VkImageSubresourceRange				m_depthImageSubresourceRange;
169 
170 	Move<VkImage>						m_colorImage;
171 	de::MovePtr<Allocation>				m_colorImageAlloc;
172 	Move<VkImage>						m_depthImage;
173 	de::MovePtr<Allocation>				m_depthImageAlloc;
174 	Move<VkImageView>					m_colorAttachmentView;
175 	Move<VkImageView>					m_depthAttachmentView;
176 	Move<VkRenderPass>					m_renderPass;
177 	Move<VkFramebuffer>					m_framebuffer;
178 
179 	Move<VkShaderModule>				m_vertexShaderModule;
180 	Move<VkShaderModule>				m_fragmentShaderModule;
181 
182 	Move<VkBuffer>						m_vertexBuffer;
183 	std::vector<Vertex4RGBA>			m_vertices;
184 	de::MovePtr<Allocation>				m_vertexBufferAlloc;
185 
186 	Move<VkPipelineLayout>				m_pipelineLayout;
187 	Move<VkPipeline>					m_graphicsPipelines[DepthTest::QUAD_COUNT];
188 
189 	Move<VkCommandPool>					m_cmdPool;
190 	Move<VkCommandBuffer>				m_cmdBuffer;
191 };
192 
193 const float DepthTest::quadDepths[QUAD_COUNT] =
194 {
195 	0.1f,
196 	0.0f,
197 	0.3f,
198 	0.2f
199 };
200 
DepthTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkFormat depthFormat,const VkCompareOp depthCompareOps[QUAD_COUNT],const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable)201 DepthTest::DepthTest (tcu::TestContext&		testContext,
202 					  const std::string&	name,
203 					  const std::string&	description,
204 					  const VkFormat		depthFormat,
205 					  const VkCompareOp		depthCompareOps[QUAD_COUNT],
206 					  const bool			depthBoundsTestEnable,
207 					  const float			depthBoundsMin,
208 					  const float			depthBoundsMax,
209 					  const bool			depthTestEnable,
210 					  const bool			stencilTestEnable)
211 	: vkt::TestCase	(testContext, name, description)
212 	, m_depthFormat				(depthFormat)
213 	, m_depthBoundsTestEnable	(depthBoundsTestEnable)
214 	, m_depthBoundsMin			(depthBoundsMin)
215 	, m_depthBoundsMax			(depthBoundsMax)
216 	, m_depthTestEnable			(depthTestEnable)
217 	, m_stencilTestEnable		(stencilTestEnable)
218 {
219 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT);
220 }
221 
~DepthTest(void)222 DepthTest::~DepthTest (void)
223 {
224 }
225 
createInstance(Context & context) const226 TestInstance* DepthTest::createInstance (Context& context) const
227 {
228 	return new DepthTestInstance(context, m_depthFormat, m_depthCompareOps, m_depthBoundsTestEnable, m_depthBoundsMin, m_depthBoundsMax, m_depthTestEnable, m_stencilTestEnable);
229 }
230 
initPrograms(SourceCollections & programCollection) const231 void DepthTest::initPrograms (SourceCollections& programCollection) const
232 {
233 	programCollection.glslSources.add("color_vert") << glu::VertexSource(
234 		"#version 310 es\n"
235 		"layout(location = 0) in vec4 position;\n"
236 		"layout(location = 1) in vec4 color;\n"
237 		"layout(location = 0) out highp vec4 vtxColor;\n"
238 		"void main (void)\n"
239 		"{\n"
240 		"	gl_Position = position;\n"
241 		"	vtxColor = color;\n"
242 		"}\n");
243 
244 	programCollection.glslSources.add("color_frag") << glu::FragmentSource(
245 		"#version 310 es\n"
246 		"layout(location = 0) in highp vec4 vtxColor;\n"
247 		"layout(location = 0) out highp vec4 fragColor;\n"
248 		"void main (void)\n"
249 		"{\n"
250 		"	fragColor = vtxColor;\n"
251 		"}\n");
252 }
253 
DepthTestInstance(Context & context,const VkFormat depthFormat,const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable)254 DepthTestInstance::DepthTestInstance (Context&				context,
255 									  const VkFormat		depthFormat,
256 									  const VkCompareOp		depthCompareOps[DepthTest::QUAD_COUNT],
257 									  const bool			depthBoundsTestEnable,
258 									  const float			depthBoundsMin,
259 									  const float			depthBoundsMax,
260 									  const bool			depthTestEnable,
261 									  const bool			stencilTestEnable)
262 	: vkt::TestInstance			(context)
263 	, m_renderSize				(32, 32)
264 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
265 	, m_depthFormat				(depthFormat)
266 	, m_depthBoundsTestEnable	(depthBoundsTestEnable)
267 	, m_depthBoundsMin			(depthBoundsMin)
268 	, m_depthBoundsMax			(depthBoundsMax)
269 	, m_depthTestEnable			(depthTestEnable)
270 	, m_stencilTestEnable		(stencilTestEnable)
271 {
272 	const DeviceInterface&		vk						= context.getDeviceInterface();
273 	const VkDevice				vkDevice				= context.getDevice();
274 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
275 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
276 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
277 
278 	// Check depthBounds support
279 	if (m_depthBoundsTestEnable && !context.getDeviceFeatures().depthBounds)
280 		TCU_THROW(NotSupportedError, "depthBounds feature is not supported");
281 
282 	// Copy depth operators
283 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT);
284 
285 	// Create color image
286 	{
287 		const VkImageCreateInfo colorImageParams =
288 		{
289 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
290 			DE_NULL,																	// const void*				pNext;
291 			0u,																			// VkImageCreateFlags		flags;
292 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
293 			m_colorFormat,																// VkFormat					format;
294 			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
295 			1u,																			// deUint32					mipLevels;
296 			1u,																			// deUint32					arrayLayers;
297 			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
298 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
299 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
300 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
301 			1u,																			// deUint32					queueFamilyIndexCount;
302 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
303 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
304 		};
305 
306 		m_colorImage			= createImage(vk, vkDevice, &colorImageParams);
307 
308 		// Allocate and bind color image memory
309 		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
310 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
311 	}
312 
313 	// Create depth image
314 	{
315 		// Check format support
316 		if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat))
317 			throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat));
318 
319 		const VkImageCreateInfo depthImageParams =
320 		{
321 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
322 			DE_NULL,										// const void*				pNext;
323 			0u,												// VkImageCreateFlags		flags;
324 			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
325 			m_depthFormat,									// VkFormat					format;
326 			{ m_renderSize.x(), m_renderSize.y(), 1u },		// VkExtent3D				extent;
327 			1u,												// deUint32					mipLevels;
328 			1u,												// deUint32					arrayLayers;
329 			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
330 			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
331 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,	// VkImageUsageFlags		usage;
332 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
333 			1u,												// deUint32					queueFamilyIndexCount;
334 			&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
335 			VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
336 		};
337 
338 		m_depthImage = createImage(vk, vkDevice, &depthImageParams);
339 
340 		// Allocate and bind depth image memory
341 		m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
342 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
343 
344 		const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
345 																									  : VK_IMAGE_ASPECT_DEPTH_BIT);
346 		m_depthImageSubresourceRange    = makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers);
347 	}
348 
349 	// Create color attachment view
350 	{
351 		const VkImageViewCreateInfo colorAttachmentViewParams =
352 		{
353 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
354 			DE_NULL,										// const void*				pNext;
355 			0u,												// VkImageViewCreateFlags	flags;
356 			*m_colorImage,									// VkImage					image;
357 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
358 			m_colorFormat,									// VkFormat					format;
359 			componentMappingRGBA,							// VkComponentMapping		components;
360 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
361 		};
362 
363 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
364 	}
365 
366 	// Create depth attachment view
367 	{
368 		const VkImageViewCreateInfo depthAttachmentViewParams =
369 		{
370 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
371 			DE_NULL,										// const void*				pNext;
372 			0u,												// VkImageViewCreateFlags	flags;
373 			*m_depthImage,									// VkImage					image;
374 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
375 			m_depthFormat,									// VkFormat					format;
376 			componentMappingRGBA,							// VkComponentMapping		components;
377 			m_depthImageSubresourceRange,					// VkImageSubresourceRange	subresourceRange;
378 		};
379 
380 		m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
381 	}
382 
383 	// Create render pass
384 	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
385 
386 	// Create framebuffer
387 	{
388 		const VkImageView attachmentBindInfos[2] =
389 		{
390 			*m_colorAttachmentView,
391 			*m_depthAttachmentView,
392 		};
393 
394 		const VkFramebufferCreateInfo framebufferParams =
395 		{
396 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
397 			DE_NULL,											// const void*					pNext;
398 			0u,													// VkFramebufferCreateFlags		flags;
399 			*m_renderPass,										// VkRenderPass					renderPass;
400 			2u,													// deUint32						attachmentCount;
401 			attachmentBindInfos,								// const VkImageView*			pAttachments;
402 			(deUint32)m_renderSize.x(),							// deUint32						width;
403 			(deUint32)m_renderSize.y(),							// deUint32						height;
404 			1u													// deUint32						layers;
405 		};
406 
407 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
408 	}
409 
410 	// Create pipeline layout
411 	{
412 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
413 		{
414 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
415 			DE_NULL,											// const void*						pNext;
416 			0u,													// VkPipelineLayoutCreateFlags		flags;
417 			0u,													// deUint32							setLayoutCount;
418 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
419 			0u,													// deUint32							pushConstantRangeCount;
420 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
421 		};
422 
423 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
424 	}
425 
426 	// Shader modules
427 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
428 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
429 
430 	// Create pipeline
431 	{
432 		const std::vector<VkViewport>				viewports							(1, makeViewport(m_renderSize));
433 		const std::vector<VkRect2D>					scissors							(1, makeRect2D(m_renderSize));;
434 
435 		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
436 		{
437 			0u,							// deUint32					binding;
438 			sizeof(Vertex4RGBA),		// deUint32					strideInBytes;
439 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	inputRate;
440 		};
441 
442 		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[2]	=
443 		{
444 			{
445 				0u,									// deUint32	location;
446 				0u,									// deUint32	binding;
447 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
448 				0u									// deUint32	offset;
449 			},
450 			{
451 				1u,									// deUint32	location;
452 				0u,									// deUint32	binding;
453 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
454 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
455 			}
456 		};
457 
458 		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
459 		{
460 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
461 			DE_NULL,														// const void*								pNext;
462 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
463 			1u,																// deUint32									vertexBindingDescriptionCount;
464 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
465 			2u,																// deUint32									vertexAttributeDescriptionCount;
466 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
467 		};
468 
469 		VkPipelineDepthStencilStateCreateInfo		depthStencilStateParams				=
470 		{
471 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
472 			DE_NULL,													// const void*								pNext;
473 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
474 			m_depthTestEnable,											// VkBool32									depthTestEnable;
475 			true,														// VkBool32									depthWriteEnable;
476 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
477 			m_depthBoundsTestEnable,									// VkBool32									depthBoundsTestEnable;
478 			m_stencilTestEnable,										// VkBool32									stencilTestEnable;
479 			// VkStencilOpState	front;
480 			{
481 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
482 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
483 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
484 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
485 				0u,						// deUint32		compareMask;
486 				0u,						// deUint32		writeMask;
487 				0u,						// deUint32		reference;
488 			},
489 			// VkStencilOpState	back;
490 			{
491 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
492 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
493 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
494 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
495 				0u,						// deUint32		compareMask;
496 				0u,						// deUint32		writeMask;
497 				0u,						// deUint32		reference;
498 			},
499 			m_depthBoundsMin,			// float			minDepthBounds;
500 			m_depthBoundsMax,			// float			maxDepthBounds;
501 		};
502 
503 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
504 		{
505 			depthStencilStateParams.depthCompareOp	= depthCompareOps[quadNdx];
506 			m_graphicsPipelines[quadNdx]			= makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
507 																		   vkDevice,							// const VkDevice                                device
508 																		   *m_pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
509 																		   *m_vertexShaderModule,				// const VkShaderModule                          vertexShaderModule
510 																		   DE_NULL,								// const VkShaderModule                          tessellationControlModule
511 																		   DE_NULL,								// const VkShaderModule                          tessellationEvalModule
512 																		   DE_NULL,								// const VkShaderModule                          geometryShaderModule
513 																		   *m_fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
514 																		   *m_renderPass,						// const VkRenderPass                            renderPass
515 																		   viewports,							// const std::vector<VkViewport>&                viewports
516 																		   scissors,							// const std::vector<VkRect2D>&                  scissors
517 																		   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
518 																		   0u,									// const deUint32                                subpass
519 																		   0u,									// const deUint32                                patchControlPoints
520 																		   &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
521 																		   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
522 																		   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
523 																		   &depthStencilStateParams);			// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
524 		}
525 	}
526 
527 	// Create vertex buffer
528 	{
529 		const VkBufferCreateInfo vertexBufferParams =
530 		{
531 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
532 			DE_NULL,									// const void*			pNext;
533 			0u,											// VkBufferCreateFlags	flags;
534 			1024u,										// VkDeviceSize			size;
535 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
536 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
537 			1u,											// deUint32				queueFamilyIndexCount;
538 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
539 		};
540 
541 		m_vertices			= createOverlappingQuads();
542 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
543 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
544 
545 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
546 
547 		// Adjust depths
548 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
549 			for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
550 				m_vertices[quadNdx * 6 + vertexNdx].position.z() = DepthTest::quadDepths[quadNdx];
551 
552 		// Load vertices into vertex buffer
553 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
554 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
555 	}
556 
557 	// Create command pool
558 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
559 
560 	// Create command buffer
561 	{
562 		const VkClearValue attachmentClearValues[2] =
563 		{
564 			defaultClearValue(m_colorFormat),
565 			defaultClearValue(m_depthFormat),
566 		};
567 		const VkImageMemoryBarrier imageLayoutBarriers[] =
568 		{
569 			// color image layout transition
570 			{
571 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
572 				DE_NULL,																// const void*                pNext;
573 				(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
574 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags              dstAccessMask;
575 				VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
576 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,								// VkImageLayout              newLayout;
577 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
578 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
579 				*m_colorImage,															// VkImage                    image;
580 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange    subresourceRange;
581 			},
582 			// depth image layout transition
583 			{
584 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
585 				DE_NULL,																// const void*                pNext;
586 				(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
587 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,							// VkAccessFlags              dstAccessMask;
588 				VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
589 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,						// VkImageLayout              newLayout;
590 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
591 				VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
592 				*m_depthImage,															// VkImage                    image;
593 				m_depthImageSubresourceRange,											// VkImageSubresourceRange    subresourceRange;
594 			},
595 		};
596 
597 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
598 
599 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
600 
601 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
602 			VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
603 			0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageLayoutBarriers), imageLayoutBarriers);
604 
605 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
606 
607 		const VkDeviceSize		quadOffset		= (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
608 
609 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
610 		{
611 			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
612 
613 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
614 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
615 			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
616 		}
617 
618 		endRenderPass(vk, *m_cmdBuffer);
619 		endCommandBuffer(vk, *m_cmdBuffer);
620 	}
621 }
622 
~DepthTestInstance(void)623 DepthTestInstance::~DepthTestInstance (void)
624 {
625 }
626 
iterate(void)627 tcu::TestStatus DepthTestInstance::iterate (void)
628 {
629 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
630 	const VkDevice				vkDevice	= m_context.getDevice();
631 	const VkQueue				queue		= m_context.getUniversalQueue();
632 
633 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
634 
635 	return verifyImage();
636 }
637 
verifyImage(void)638 tcu::TestStatus DepthTestInstance::verifyImage (void)
639 {
640 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
641 	const tcu::TextureFormat	tcuDepthFormat	= mapVkFormat(m_depthFormat);
642 	const ColorVertexShader		vertexShader;
643 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
644 	const rr::Program			program			(&vertexShader, &fragmentShader);
645 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
646 	bool						compareOk		= false;
647 
648 	// Render reference image
649 	{
650 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
651 		{
652 			// Set depth state
653 			rr::RenderState renderState(refRenderer.getViewportState());
654 			renderState.fragOps.depthTestEnabled = true;
655 			renderState.fragOps.depthFunc = mapVkCompareOp(m_depthCompareOps[quadNdx]);
656 			if (m_depthBoundsTestEnable)
657 			{
658 				renderState.fragOps.depthBoundsTestEnabled = true;
659 				renderState.fragOps.minDepthBound = m_depthBoundsMin;
660 				renderState.fragOps.maxDepthBound = m_depthBoundsMax;
661 			}
662 
663 			refRenderer.draw(renderState,
664 							 rr::PRIMITIVETYPE_TRIANGLES,
665 							 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
666 													  m_vertices.begin() + (quadNdx + 1) * 6));
667 		}
668 	}
669 
670 	// Compare result with reference image
671 	{
672 		const DeviceInterface&			vk					= m_context.getDeviceInterface();
673 		const VkDevice					vkDevice			= m_context.getDevice();
674 		const VkQueue					queue				= m_context.getUniversalQueue();
675 		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
676 		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
677 		de::MovePtr<tcu::TextureLevel>	result				= readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
678 
679 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
680 															  "IntImageCompare",
681 															  "Image comparison",
682 															  refRenderer.getAccess(),
683 															  result->getAccess(),
684 															  tcu::UVec4(2, 2, 2, 2),
685 															  tcu::IVec3(1, 1, 0),
686 															  true,
687 															  tcu::COMPARE_LOG_RESULT);
688 	}
689 
690 	if (compareOk)
691 		return tcu::TestStatus::pass("Result image matches reference");
692 	else
693 		return tcu::TestStatus::fail("Image mismatch");
694 }
695 
getFormatCaseName(const VkFormat format)696 std::string getFormatCaseName (const VkFormat format)
697 {
698 	const std::string	fullName	= getFormatName(format);
699 
700 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
701 
702 	return de::toLower(fullName.substr(10));
703 }
704 
getCompareOpsName(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])705 std::string	getCompareOpsName (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
706 {
707 	std::ostringstream name;
708 
709 	for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
710 	{
711 		const std::string	fullOpName	= getCompareOpName(quadDepthOps[quadNdx]);
712 
713 		DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_"));
714 
715 		name << de::toLower(fullOpName.substr(14));
716 
717 		if (quadNdx < DepthTest::QUAD_COUNT - 1)
718 			name << "_";
719 	}
720 
721 	return name.str();
722 }
723 
getCompareOpsDescription(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])724 std::string	getCompareOpsDescription (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
725 {
726 	std::ostringstream desc;
727 	desc << "Draws " << DepthTest::QUAD_COUNT << " quads with depth compare ops: ";
728 
729 	for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
730 	{
731 		desc << getCompareOpName(quadDepthOps[quadNdx]) << " at depth " << DepthTest::quadDepths[quadNdx];
732 
733 		if (quadNdx < DepthTest::QUAD_COUNT - 1)
734 			desc << ", ";
735 	}
736 	return desc.str();
737 }
738 
739 
740 } // anonymous
741 
createDepthTests(tcu::TestContext & testCtx)742 tcu::TestCaseGroup* createDepthTests (tcu::TestContext& testCtx)
743 {
744 	const VkFormat depthFormats[] =
745 	{
746 		VK_FORMAT_D16_UNORM,
747 		VK_FORMAT_X8_D24_UNORM_PACK32,
748 		VK_FORMAT_D32_SFLOAT,
749 		VK_FORMAT_D16_UNORM_S8_UINT,
750 		VK_FORMAT_D24_UNORM_S8_UINT,
751 		VK_FORMAT_D32_SFLOAT_S8_UINT
752 	};
753 
754 	// Each entry configures the depth compare operators of QUAD_COUNT quads.
755 	// All entries cover pair-wise combinations of compare operators.
756 	const VkCompareOp depthOps[][DepthTest::QUAD_COUNT] =
757 	{
758 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL },
759 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER },
760 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL },
761 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
762 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
763 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS },
764 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER },
765 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
766 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS },
767 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
768 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
769 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL },
770 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL },
771 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS },
772 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
773 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS },
774 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
775 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER },
776 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
777 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
778 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER },
779 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER },
780 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL },
781 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
782 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL },
783 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL },
784 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS },
785 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
786 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER },
787 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
788 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL },
789 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
790 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS },
791 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL },
792 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER },
793 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL },
794 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL },
795 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER },
796 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL },
797 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL },
798 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
799 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS },
800 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS },
801 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL },
802 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
803 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL },
804 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
805 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
806 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
807 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS },
808 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS },
809 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER },
810 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL },
811 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
812 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS },
813 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
814 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL },
815 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
816 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL },
817 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER },
818 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER },
819 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
820 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL },
821 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
822 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER },
823 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
824 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
825 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
826 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
827 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER },
828 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
829 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL },
830 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS },
831 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER }
832 	};
833 
834 	de::MovePtr<tcu::TestCaseGroup> depthTests (new tcu::TestCaseGroup(testCtx, "depth", "Depth tests"));
835 
836 	// Tests for format features
837 	{
838 		de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests (new tcu::TestCaseGroup(testCtx, "format_features", "Checks depth format features"));
839 
840 		// Formats that must be supported in all implementations
841 		addFunctionCase(formatFeaturesTests.get(),
842 						"support_d16_unorm",
843 						"Tests if VK_FORMAT_D16_UNORM is supported as depth/stencil attachment format",
844 						testSupportsDepthStencilFormat,
845 						VK_FORMAT_D16_UNORM);
846 
847 		// Sets where at least one of the formats must be supported
848 		const VkFormat	depthOnlyFormats[]		= { VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT };
849 		const VkFormat	depthStencilFormats[]	= { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
850 
851 		addFunctionCase(formatFeaturesTests.get(),
852 						"support_d24_unorm_or_d32_sfloat",
853 						"Tests if any of VK_FORMAT_D24_UNORM_X8 or VK_FORMAT_D32_SFLOAT are supported as depth/stencil attachment format",
854 						testSupportsAtLeastOneDepthStencilFormat,
855 						std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats)));
856 
857 		addFunctionCase(formatFeaturesTests.get(),
858 						"support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint",
859 						"Tests if any of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT are supported as depth/stencil attachment format",
860 						testSupportsAtLeastOneDepthStencilFormat,
861 						std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats)));
862 
863 		depthTests->addChild(formatFeaturesTests.release());
864 	}
865 
866 	// Tests for format and compare operators
867 	{
868 		de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different depth formats"));
869 
870 		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++)
871 		{
872 			de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
873 																					getFormatCaseName(depthFormats[formatNdx]).c_str(),
874 																					(std::string("Uses format ") + getFormatName(depthFormats[formatNdx])).c_str()));
875 			de::MovePtr<tcu::TestCaseGroup>	compareOpsTests	(new tcu::TestCaseGroup(testCtx, "compare_ops", "Combines depth compare operators"));
876 
877 			for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++)
878 			{
879 				compareOpsTests->addChild(new DepthTest(testCtx,
880 														getCompareOpsName(depthOps[opsNdx]),
881 														getCompareOpsDescription(depthOps[opsNdx]),
882 														depthFormats[formatNdx],
883 														depthOps[opsNdx]));
884 
885 				compareOpsTests->addChild(new DepthTest(testCtx,
886 														getCompareOpsName(depthOps[opsNdx]) + "_depth_bounds_test",
887 														getCompareOpsDescription(depthOps[opsNdx]) + " with depth bounds test enabled",
888 														depthFormats[formatNdx],
889 														depthOps[opsNdx],
890 														true,
891 														0.1f,
892 														0.25f));
893 			}
894 			// Special VkPipelineDepthStencilStateCreateInfo known to have issues
895 			{
896 				const VkCompareOp depthOpsSpecial[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER };
897 
898 				compareOpsTests->addChild(new DepthTest(testCtx,
899 														"never_zerodepthbounds_depthdisabled_stencilenabled",
900 														"special VkPipelineDepthStencilStateCreateInfo",
901 														depthFormats[formatNdx],
902 														depthOpsSpecial,
903 														true,
904 														0.0f,
905 														0.0f,
906 														false,
907 														true));
908 			}
909 			formatTest->addChild(compareOpsTests.release());
910 			formatTests->addChild(formatTest.release());
911 		}
912 		depthTests->addChild(formatTests.release());
913 	}
914 
915 	return depthTests.release();
916 }
917 
918 } // pipeline
919 } // vkt
920