• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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				separateDepthStencilLayouts,
123 																 const bool				depthBoundsTestEnable			= false,
124 																 const float			depthBoundsMin					= 0.0f,
125 																 const float			depthBoundsMax					= 1.0f,
126 																 const bool				depthTestEnable					= true,
127 																 const bool				stencilTestEnable				= false,
128 																 const bool				colorAttachmentEnable			= true);
129 	virtual								~DepthTest				(void);
130 	virtual void						initPrograms			(SourceCollections& programCollection) const;
131 	virtual void						checkSupport			(Context& context) const;
132 	virtual TestInstance*				createInstance			(Context& context) const;
133 
134 private:
135 	const VkFormat						m_depthFormat;
136 	const bool							m_separateDepthStencilLayouts;
137 	const bool							m_depthBoundsTestEnable;
138 	const float							m_depthBoundsMin;
139 	const float							m_depthBoundsMax;
140 	const bool							m_depthTestEnable;
141 	const bool							m_stencilTestEnable;
142 	const bool							m_colorAttachmentEnable;
143 	VkCompareOp							m_depthCompareOps[QUAD_COUNT];
144 };
145 
146 class DepthTestInstance : public vkt::TestInstance
147 {
148 public:
149 										DepthTestInstance		(Context&			context,
150 																 const VkFormat		depthFormat,
151 																 const VkCompareOp	depthCompareOps[DepthTest::QUAD_COUNT],
152 																 const bool			separateDepthStencilLayouts,
153 																 const bool			depthBoundsTestEnable,
154 																 const float		depthBoundsMin,
155 																 const float		depthBoundsMax,
156 																 const bool			depthTestEnable,
157 																 const bool			stencilTestEnable,
158 																 const bool			colorAttachmentEnable);
159 	virtual								~DepthTestInstance		(void);
160 	virtual tcu::TestStatus				iterate					(void);
161 
162 private:
163 	tcu::TestStatus						verifyImage				(void);
164 
165 private:
166 	VkCompareOp							m_depthCompareOps[DepthTest::QUAD_COUNT];
167 	const tcu::UVec2					m_renderSize;
168 	const VkFormat						m_colorFormat;
169 	const VkFormat						m_depthFormat;
170 	const bool							m_separateDepthStencilLayouts;
171 	const bool							m_depthBoundsTestEnable;
172 	const float							m_depthBoundsMin;
173 	const float							m_depthBoundsMax;
174 	const bool							m_depthTestEnable;
175 	const bool							m_stencilTestEnable;
176 	const bool							m_colorAttachmentEnable;
177 	VkImageSubresourceRange				m_depthImageSubresourceRange;
178 
179 	Move<VkImage>						m_colorImage;
180 	de::MovePtr<Allocation>				m_colorImageAlloc;
181 	Move<VkImage>						m_depthImage;
182 	de::MovePtr<Allocation>				m_depthImageAlloc;
183 	Move<VkImageView>					m_colorAttachmentView;
184 	Move<VkImageView>					m_depthAttachmentView;
185 	Move<VkRenderPass>					m_renderPass;
186 	Move<VkFramebuffer>					m_framebuffer;
187 
188 	Move<VkShaderModule>				m_vertexShaderModule;
189 	Move<VkShaderModule>				m_fragmentShaderModule;
190 
191 	Move<VkBuffer>						m_vertexBuffer;
192 	std::vector<Vertex4RGBA>			m_vertices;
193 	de::MovePtr<Allocation>				m_vertexBufferAlloc;
194 
195 	Move<VkPipelineLayout>				m_pipelineLayout;
196 	Move<VkPipeline>					m_graphicsPipelines[DepthTest::QUAD_COUNT];
197 
198 	Move<VkCommandPool>					m_cmdPool;
199 	Move<VkCommandBuffer>				m_cmdBuffer;
200 };
201 
202 const float DepthTest::quadDepths[QUAD_COUNT] =
203 {
204 	0.1f,
205 	0.0f,
206 	0.3f,
207 	0.2f
208 };
209 
DepthTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkFormat depthFormat,const VkCompareOp depthCompareOps[QUAD_COUNT],const bool separateDepthStencilLayouts,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable)210 DepthTest::DepthTest (tcu::TestContext&		testContext,
211 					  const std::string&	name,
212 					  const std::string&	description,
213 					  const VkFormat		depthFormat,
214 					  const VkCompareOp		depthCompareOps[QUAD_COUNT],
215 					  const bool			separateDepthStencilLayouts,
216 					  const bool			depthBoundsTestEnable,
217 					  const float			depthBoundsMin,
218 					  const float			depthBoundsMax,
219 					  const bool			depthTestEnable,
220 					  const bool			stencilTestEnable,
221 					  const bool			colorAttachmentEnable)
222 	: vkt::TestCase	(testContext, name, description)
223 	, m_depthFormat					(depthFormat)
224 	, m_separateDepthStencilLayouts	(separateDepthStencilLayouts)
225 	, m_depthBoundsTestEnable		(depthBoundsTestEnable)
226 	, m_depthBoundsMin				(depthBoundsMin)
227 	, m_depthBoundsMax				(depthBoundsMax)
228 	, m_depthTestEnable				(depthTestEnable)
229 	, m_stencilTestEnable			(stencilTestEnable)
230 	, m_colorAttachmentEnable		(colorAttachmentEnable)
231 {
232 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT);
233 }
234 
~DepthTest(void)235 DepthTest::~DepthTest (void)
236 {
237 }
238 
checkSupport(Context & context) const239 void DepthTest::checkSupport (Context& context) const
240 {
241 	if (m_depthBoundsTestEnable)
242 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
243 
244 	if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat))
245 		throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat));
246 
247 	if (m_separateDepthStencilLayouts && !context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
248 		TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
249 }
250 
createInstance(Context & context) const251 TestInstance* DepthTest::createInstance (Context& context) const
252 {
253 	return new DepthTestInstance(context, m_depthFormat, m_depthCompareOps, m_separateDepthStencilLayouts, m_depthBoundsTestEnable, m_depthBoundsMin, m_depthBoundsMax, m_depthTestEnable, m_stencilTestEnable, m_colorAttachmentEnable);
254 }
255 
initPrograms(SourceCollections & programCollection) const256 void DepthTest::initPrograms (SourceCollections& programCollection) const
257 {
258 	if (m_colorAttachmentEnable)
259 	{
260 		programCollection.glslSources.add("color_vert") << glu::VertexSource(
261 			"#version 310 es\n"
262 			"layout(location = 0) in vec4 position;\n"
263 			"layout(location = 1) in vec4 color;\n"
264 			"layout(location = 0) out highp vec4 vtxColor;\n"
265 			"void main (void)\n"
266 			"{\n"
267 			"	gl_Position = position;\n"
268 			"	vtxColor = color;\n"
269 			"}\n");
270 
271 		programCollection.glslSources.add("color_frag") << glu::FragmentSource(
272 			"#version 310 es\n"
273 			"layout(location = 0) in highp vec4 vtxColor;\n"
274 			"layout(location = 0) out highp vec4 fragColor;\n"
275 			"void main (void)\n"
276 			"{\n"
277 			"	fragColor = vtxColor;\n"
278 			"}\n");
279 	}
280 	else
281 	{
282 		programCollection.glslSources.add("color_vert") << glu::VertexSource(
283 			"#version 310 es\n"
284 			"layout(location = 0) in vec4 position;\n"
285 			"layout(location = 1) in vec4 color;\n"
286 			"void main (void)\n"
287 			"{\n"
288 			"	gl_Position = position;\n"
289 			"}\n");
290 	}
291 
292 }
293 
DepthTestInstance(Context & context,const VkFormat depthFormat,const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],const bool separateDepthStencilLayouts,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable)294 DepthTestInstance::DepthTestInstance (Context&				context,
295 									  const VkFormat		depthFormat,
296 									  const VkCompareOp		depthCompareOps[DepthTest::QUAD_COUNT],
297 									  const bool			separateDepthStencilLayouts,
298 									  const bool			depthBoundsTestEnable,
299 									  const float			depthBoundsMin,
300 									  const float			depthBoundsMax,
301 									  const bool			depthTestEnable,
302 									  const bool			stencilTestEnable,
303 									  const bool			colorAttachmentEnable)
304 	: vkt::TestInstance				(context)
305 	, m_renderSize					(32, 32)
306 	, m_colorFormat					(colorAttachmentEnable ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_UNDEFINED)
307 	, m_depthFormat					(depthFormat)
308 	, m_separateDepthStencilLayouts	(separateDepthStencilLayouts)
309 	, m_depthBoundsTestEnable		(depthBoundsTestEnable)
310 	, m_depthBoundsMin				(depthBoundsMin)
311 	, m_depthBoundsMax				(depthBoundsMax)
312 	, m_depthTestEnable				(depthTestEnable)
313 	, m_stencilTestEnable			(stencilTestEnable)
314 	, m_colorAttachmentEnable		(colorAttachmentEnable)
315 {
316 	const DeviceInterface&		vk						= context.getDeviceInterface();
317 	const VkDevice				vkDevice				= context.getDevice();
318 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
319 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
320 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
321 
322 	// Copy depth operators
323 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT);
324 
325 	// Create color image
326 	if (m_colorAttachmentEnable)
327 	{
328 		const VkImageCreateInfo colorImageParams =
329 		{
330 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
331 			DE_NULL,																	// const void*				pNext;
332 			0u,																			// VkImageCreateFlags		flags;
333 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
334 			m_colorFormat,																// VkFormat					format;
335 			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
336 			1u,																			// deUint32					mipLevels;
337 			1u,																			// deUint32					arrayLayers;
338 			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
339 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
340 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
341 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
342 			1u,																			// deUint32					queueFamilyIndexCount;
343 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
344 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
345 		};
346 
347 		m_colorImage			= createImage(vk, vkDevice, &colorImageParams);
348 
349 		// Allocate and bind color image memory
350 		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
351 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
352 	}
353 
354 	// Create depth image
355 	{
356 		const VkImageCreateInfo depthImageParams =
357 		{
358 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
359 			DE_NULL,										// const void*				pNext;
360 			0u,												// VkImageCreateFlags		flags;
361 			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
362 			m_depthFormat,									// VkFormat					format;
363 			{ m_renderSize.x(), m_renderSize.y(), 1u },		// VkExtent3D				extent;
364 			1u,												// deUint32					mipLevels;
365 			1u,												// deUint32					arrayLayers;
366 			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
367 			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
368 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
369 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT,				// VkImageUsageFlags		usage;
370 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
371 			1u,												// deUint32					queueFamilyIndexCount;
372 			&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
373 			VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
374 		};
375 
376 		m_depthImage = createImage(vk, vkDevice, &depthImageParams);
377 
378 		// Allocate and bind depth image memory
379 		m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
380 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
381 
382 		const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
383 																									  : VK_IMAGE_ASPECT_DEPTH_BIT);
384 		m_depthImageSubresourceRange    = makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers);
385 	}
386 
387 	// Create color attachment view
388 	if (m_colorAttachmentEnable)
389 	{
390 		const VkImageViewCreateInfo colorAttachmentViewParams =
391 		{
392 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
393 			DE_NULL,										// const void*				pNext;
394 			0u,												// VkImageViewCreateFlags	flags;
395 			*m_colorImage,									// VkImage					image;
396 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
397 			m_colorFormat,									// VkFormat					format;
398 			componentMappingRGBA,							// VkComponentMapping		components;
399 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
400 		};
401 
402 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
403 	}
404 
405 	// Create depth attachment view
406 	{
407 		const VkImageViewCreateInfo depthAttachmentViewParams =
408 		{
409 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
410 			DE_NULL,										// const void*				pNext;
411 			0u,												// VkImageViewCreateFlags	flags;
412 			*m_depthImage,									// VkImage					image;
413 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
414 			m_depthFormat,									// VkFormat					format;
415 			componentMappingRGBA,							// VkComponentMapping		components;
416 			m_depthImageSubresourceRange,					// VkImageSubresourceRange	subresourceRange;
417 		};
418 
419 		m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
420 	}
421 
422 	// Create render pass
423 	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
424 
425 	// Create framebuffer
426 	{
427 		std::vector<VkImageView>		attachmentBindInfos;
428 
429 		if (m_colorAttachmentEnable)
430 			attachmentBindInfos.push_back(*m_colorAttachmentView);
431 
432 		attachmentBindInfos.push_back(*m_depthAttachmentView);
433 
434 		const VkFramebufferCreateInfo	framebufferParams	=
435 		{
436 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
437 			DE_NULL,											// const void*					pNext;
438 			0u,													// VkFramebufferCreateFlags		flags;
439 			*m_renderPass,										// VkRenderPass					renderPass;
440 			(deUint32)attachmentBindInfos.size(),				// deUint32						attachmentCount;
441 			attachmentBindInfos.data(),							// const VkImageView*			pAttachments;
442 			(deUint32)m_renderSize.x(),							// deUint32						width;
443 			(deUint32)m_renderSize.y(),							// deUint32						height;
444 			1u													// deUint32						layers;
445 		};
446 
447 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
448 	}
449 
450 	// Create pipeline layout
451 	{
452 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
453 		{
454 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
455 			DE_NULL,											// const void*						pNext;
456 			0u,													// VkPipelineLayoutCreateFlags		flags;
457 			0u,													// deUint32							setLayoutCount;
458 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
459 			0u,													// deUint32							pushConstantRangeCount;
460 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
461 		};
462 
463 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
464 	}
465 
466 	// Shader modules
467 	m_vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
468 	if (m_colorAttachmentEnable)
469 		m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
470 
471 	// Create pipeline
472 	{
473 		const std::vector<VkViewport>				viewports							(1, makeViewport(m_renderSize));
474 		const std::vector<VkRect2D>					scissors							(1, makeRect2D(m_renderSize));
475 
476 		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
477 		{
478 			0u,							// deUint32					binding;
479 			sizeof(Vertex4RGBA),		// deUint32					strideInBytes;
480 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	inputRate;
481 		};
482 
483 		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[2]	=
484 		{
485 			{
486 				0u,									// deUint32	location;
487 				0u,									// deUint32	binding;
488 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
489 				0u									// deUint32	offset;
490 			},
491 			{
492 				1u,									// deUint32	location;
493 				0u,									// deUint32	binding;
494 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
495 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
496 			}
497 		};
498 
499 		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
500 		{
501 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
502 			DE_NULL,														// const void*								pNext;
503 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
504 			1u,																// deUint32									vertexBindingDescriptionCount;
505 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
506 			2u,																// deUint32									vertexAttributeDescriptionCount;
507 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
508 		};
509 
510 		VkPipelineDepthStencilStateCreateInfo		depthStencilStateParams				=
511 		{
512 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
513 			DE_NULL,													// const void*								pNext;
514 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
515 			m_depthTestEnable,											// VkBool32									depthTestEnable;
516 			true,														// VkBool32									depthWriteEnable;
517 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
518 			m_depthBoundsTestEnable,									// VkBool32									depthBoundsTestEnable;
519 			m_stencilTestEnable,										// VkBool32									stencilTestEnable;
520 			// VkStencilOpState	front;
521 			{
522 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
523 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
524 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
525 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
526 				0u,						// deUint32		compareMask;
527 				0u,						// deUint32		writeMask;
528 				0u,						// deUint32		reference;
529 			},
530 			// VkStencilOpState	back;
531 			{
532 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
533 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
534 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
535 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
536 				0u,						// deUint32		compareMask;
537 				0u,						// deUint32		writeMask;
538 				0u,						// deUint32		reference;
539 			},
540 			m_depthBoundsMin,			// float			minDepthBounds;
541 			m_depthBoundsMax,			// float			maxDepthBounds;
542 		};
543 
544 		// Make sure rasterization is not disabled when the fragment shader is missing.
545 		const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateParams =
546 		{
547 			vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
548 			nullptr,														//	const void*								pNext;
549 			0u,																//	VkPipelineRasterizationStateCreateFlags	flags;
550 			VK_FALSE,														//	VkBool32								depthClampEnable;
551 			VK_FALSE,														//	VkBool32								rasterizerDiscardEnable;
552 			vk::VK_POLYGON_MODE_FILL,										//	VkPolygonMode							polygonMode;
553 			vk::VK_CULL_MODE_NONE,											//	VkCullModeFlags							cullMode;
554 			vk::VK_FRONT_FACE_COUNTER_CLOCKWISE,							//	VkFrontFace								frontFace;
555 			VK_FALSE,														//	VkBool32								depthBiasEnable;
556 			0.0f,															//	float									depthBiasConstantFactor;
557 			0.0f,															//	float									depthBiasClamp;
558 			0.0f,															//	float									depthBiasSlopeFactor;
559 			1.0f,															//	float									lineWidth;
560 		};
561 
562 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
563 		{
564 			depthStencilStateParams.depthCompareOp	= depthCompareOps[quadNdx];
565 			m_graphicsPipelines[quadNdx]			= makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
566 																		   vkDevice,							// const VkDevice                                device
567 																		   *m_pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
568 																		   *m_vertexShaderModule,				// const VkShaderModule                          vertexShaderModule
569 																		   DE_NULL,								// const VkShaderModule                          tessellationControlModule
570 																		   DE_NULL,								// const VkShaderModule                          tessellationEvalModule
571 																		   DE_NULL,								// const VkShaderModule                          geometryShaderModule
572 																		   *m_fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
573 																		   *m_renderPass,						// const VkRenderPass                            renderPass
574 																		   viewports,							// const std::vector<VkViewport>&                viewports
575 																		   scissors,							// const std::vector<VkRect2D>&                  scissors
576 																		   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
577 																		   0u,									// const deUint32                                subpass
578 																		   0u,									// const deUint32                                patchControlPoints
579 																		   &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
580 																		   &rasterizationStateParams,			// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
581 																		   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
582 																		   &depthStencilStateParams);			// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
583 		}
584 	}
585 
586 	// Create vertex buffer
587 	{
588 		const VkBufferCreateInfo vertexBufferParams =
589 		{
590 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
591 			DE_NULL,									// const void*			pNext;
592 			0u,											// VkBufferCreateFlags	flags;
593 			1024u,										// VkDeviceSize			size;
594 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
595 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
596 			1u,											// deUint32				queueFamilyIndexCount;
597 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
598 		};
599 
600 		m_vertices			= createOverlappingQuads();
601 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
602 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
603 
604 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
605 
606 		// Adjust depths
607 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
608 			for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
609 				m_vertices[quadNdx * 6 + vertexNdx].position.z() = DepthTest::quadDepths[quadNdx];
610 
611 		// Load vertices into vertex buffer
612 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
613 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
614 	}
615 
616 	// Create command pool
617 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
618 
619 	// Create command buffer
620 	{
621 		std::vector<VkClearValue>			attachmentClearValues;
622 
623 		if (m_colorAttachmentEnable)
624 			attachmentClearValues.push_back(defaultClearValue(m_colorFormat));
625 
626 		attachmentClearValues.push_back(defaultClearValue(m_depthFormat));
627 
628 		const VkImageMemoryBarrier			colorBarrier					=
629 		{
630 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
631 			DE_NULL,																// const void*                pNext;
632 			(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
633 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags              dstAccessMask;
634 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
635 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,								// VkImageLayout              newLayout;
636 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
637 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
638 			*m_colorImage,															// VkImage                    image;
639 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange    subresourceRange;
640 		};
641 
642 		VkImageSubresourceRange				depthBarrierSubresourceRange	= m_depthImageSubresourceRange;
643 		VkImageLayout						newLayout						= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
644 		if (m_separateDepthStencilLayouts)
645 		{
646 			depthBarrierSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
647 			newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR;
648 		}
649 
650 		const VkImageMemoryBarrier			depthBarrier					=
651 		{
652 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
653 			DE_NULL,																// const void*                pNext;
654 			(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
655 			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,							// VkAccessFlags              dstAccessMask;
656 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
657 			newLayout										,						// VkImageLayout              newLayout;
658 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
659 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
660 			*m_depthImage,															// VkImage                    image;
661 			depthBarrierSubresourceRange,											// VkImageSubresourceRange    subresourceRange;
662 		};
663 
664 		std::vector<VkImageMemoryBarrier>	imageLayoutBarriers;
665 
666 		if (m_colorAttachmentEnable)
667 			imageLayoutBarriers.push_back(colorBarrier);
668 
669 		imageLayoutBarriers.push_back(depthBarrier);
670 
671 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
672 
673 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
674 
675 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
676 			VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
677 			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), imageLayoutBarriers.data());
678 
679 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)attachmentClearValues.size(), attachmentClearValues.data());
680 
681 		const VkDeviceSize quadOffset = (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
682 
683 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
684 		{
685 			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
686 
687 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
688 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
689 			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
690 		}
691 
692 		endRenderPass(vk, *m_cmdBuffer);
693 		endCommandBuffer(vk, *m_cmdBuffer);
694 	}
695 }
696 
~DepthTestInstance(void)697 DepthTestInstance::~DepthTestInstance (void)
698 {
699 }
700 
iterate(void)701 tcu::TestStatus DepthTestInstance::iterate (void)
702 {
703 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
704 	const VkDevice				vkDevice	= m_context.getDevice();
705 	const VkQueue				queue		= m_context.getUniversalQueue();
706 
707 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
708 
709 	return verifyImage();
710 }
711 
verifyImage(void)712 tcu::TestStatus DepthTestInstance::verifyImage (void)
713 {
714 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
715 	const tcu::TextureFormat	tcuDepthFormat	= mapVkFormat(m_depthFormat);
716 	const ColorVertexShader		vertexShader;
717 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
718 	const rr::Program			program			(&vertexShader, &fragmentShader);
719 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
720 	bool						colorCompareOk	= false;
721 	bool						depthCompareOk	= false;
722 
723 	// Render reference image
724 	{
725 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
726 		{
727 			// Set depth state
728 			rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
729 			renderState.fragOps.depthTestEnabled = m_depthTestEnable;
730 			renderState.fragOps.depthFunc = mapVkCompareOp(m_depthCompareOps[quadNdx]);
731 			if (m_depthBoundsTestEnable)
732 			{
733 				renderState.fragOps.depthBoundsTestEnabled = true;
734 				renderState.fragOps.minDepthBound = m_depthBoundsMin;
735 				renderState.fragOps.maxDepthBound = m_depthBoundsMax;
736 			}
737 
738 			refRenderer.draw(renderState,
739 							 rr::PRIMITIVETYPE_TRIANGLES,
740 							 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
741 													  m_vertices.begin() + (quadNdx + 1) * 6));
742 		}
743 	}
744 
745 	// Compare color result with reference image
746 	if (m_colorAttachmentEnable)
747 	{
748 		const DeviceInterface&			vk					= m_context.getDeviceInterface();
749 		const VkDevice					vkDevice			= m_context.getDevice();
750 		const VkQueue					queue				= m_context.getUniversalQueue();
751 		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
752 		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
753 		de::MovePtr<tcu::TextureLevel>	result				= readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
754 
755 		colorCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
756 															  "IntImageCompare",
757 															  "Image comparison",
758 															  refRenderer.getAccess(),
759 															  result->getAccess(),
760 															  tcu::UVec4(2, 2, 2, 2),
761 															  tcu::IVec3(1, 1, 0),
762 															  true,
763 															  tcu::COMPARE_LOG_RESULT);
764 	}
765 	else
766 	{
767 		colorCompareOk = true;
768 	}
769 
770 	// Compare depth result with reference image
771 	{
772 		const DeviceInterface&			vk					= m_context.getDeviceInterface();
773 		const VkDevice					vkDevice			= m_context.getDevice();
774 		const VkQueue					queue				= m_context.getUniversalQueue();
775 		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
776 		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
777 		de::MovePtr<tcu::TextureLevel>	result				= readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_depthFormat, m_renderSize);
778 
779 		{
780 			de::MovePtr<tcu::TextureLevel>	convertedReferenceLevel;
781 			tcu::Maybe<tcu::TextureFormat>	convertedFormat;
782 
783 			if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_24_8_REV)
784 			{
785 				convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT24);
786 			}
787 			else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_16_8_8)
788 			{
789 				convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
790 			}
791 			else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV)
792 			{
793 				convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
794 			}
795 
796 			if (convertedFormat)
797 			{
798 				convertedReferenceLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(*convertedFormat, refRenderer.getDepthStencilAccess().getSize().x(), refRenderer.getDepthStencilAccess().getSize().y()));
799 				tcu::copy(convertedReferenceLevel->getAccess(), refRenderer.getDepthStencilAccess());
800 			}
801 
802 			float depthThreshold = 0.0f;
803 
804 			if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
805 			{
806 				const tcu::IVec4	formatBits = tcu::getTextureFormatBitDepth(result->getFormat());
807 				depthThreshold = 1.0f / static_cast<float>((1 << formatBits[0]) - 1);
808 			}
809 			else if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
810 			{
811 
812 				depthThreshold = 0.0000001f;
813 			}
814 			else
815 				TCU_FAIL("unrecognized format type class");
816 
817 			depthCompareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
818 														"DepthImageCompare",
819 														"Depth image comparison",
820 														convertedReferenceLevel ? convertedReferenceLevel->getAccess() : refRenderer.getDepthStencilAccess(),
821 														result->getAccess(),
822 														tcu::Vec4(depthThreshold, 0.0f, 0.0f, 0.0f),
823 														tcu::COMPARE_LOG_RESULT);
824 		}
825 	}
826 
827 	if (colorCompareOk && depthCompareOk)
828 		return tcu::TestStatus::pass("Result image matches reference");
829 	else
830 		return tcu::TestStatus::fail("Image mismatch");
831 }
832 
getFormatCaseName(const VkFormat format)833 std::string getFormatCaseName (const VkFormat format)
834 {
835 	const std::string	fullName	= getFormatName(format);
836 
837 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
838 
839 	return de::toLower(fullName.substr(10));
840 }
841 
getCompareOpsName(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])842 std::string	getCompareOpsName (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
843 {
844 	std::ostringstream name;
845 
846 	for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
847 	{
848 		const std::string	fullOpName	= getCompareOpName(quadDepthOps[quadNdx]);
849 
850 		DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_"));
851 
852 		name << de::toLower(fullOpName.substr(14));
853 
854 		if (quadNdx < DepthTest::QUAD_COUNT - 1)
855 			name << "_";
856 	}
857 
858 	return name.str();
859 }
860 
getCompareOpsDescription(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])861 std::string	getCompareOpsDescription (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
862 {
863 	std::ostringstream desc;
864 	desc << "Draws " << DepthTest::QUAD_COUNT << " quads with depth compare ops: ";
865 
866 	for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
867 	{
868 		desc << getCompareOpName(quadDepthOps[quadNdx]) << " at depth " << DepthTest::quadDepths[quadNdx];
869 
870 		if (quadNdx < DepthTest::QUAD_COUNT - 1)
871 			desc << ", ";
872 	}
873 	return desc.str();
874 }
875 
876 
877 } // anonymous
878 
createDepthTests(tcu::TestContext & testCtx)879 tcu::TestCaseGroup* createDepthTests (tcu::TestContext& testCtx)
880 {
881 	const VkFormat			depthFormats[]						=
882 	{
883 		VK_FORMAT_D16_UNORM,
884 		VK_FORMAT_X8_D24_UNORM_PACK32,
885 		VK_FORMAT_D32_SFLOAT,
886 		VK_FORMAT_D16_UNORM_S8_UINT,
887 		VK_FORMAT_D24_UNORM_S8_UINT,
888 		VK_FORMAT_D32_SFLOAT_S8_UINT
889 	};
890 
891 	// Each entry configures the depth compare operators of QUAD_COUNT quads.
892 	// All entries cover pair-wise combinations of compare operators.
893 	const VkCompareOp		depthOps[][DepthTest::QUAD_COUNT]	=
894 	{
895 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL },
896 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER },
897 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL },
898 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
899 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
900 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS },
901 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER },
902 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
903 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS },
904 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
905 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
906 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL },
907 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL },
908 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS },
909 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
910 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS },
911 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
912 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER },
913 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
914 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
915 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER },
916 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER },
917 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL },
918 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
919 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL },
920 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL },
921 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS },
922 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
923 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER },
924 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
925 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL },
926 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
927 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS },
928 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL },
929 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER },
930 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL },
931 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL },
932 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER },
933 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL },
934 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL },
935 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
936 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS },
937 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS },
938 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL },
939 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
940 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL },
941 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
942 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
943 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
944 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS },
945 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS },
946 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER },
947 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL },
948 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
949 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS },
950 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
951 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL },
952 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
953 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL },
954 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER },
955 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER },
956 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
957 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL },
958 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
959 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER },
960 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
961 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
962 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
963 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
964 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER },
965 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
966 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL },
967 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS },
968 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER }
969 	};
970 
971 	const bool						colorAttachmentEnabled[]	= { true, false };
972 
973 	de::MovePtr<tcu::TestCaseGroup>	depthTests					(new tcu::TestCaseGroup(testCtx, "depth", "Depth tests"));
974 	de::MovePtr<tcu::TestCaseGroup>	noColorAttachmentTests		(new tcu::TestCaseGroup(testCtx, "nocolor", "Depth tests with no color attachment"));
975 
976 	// Tests for format features
977 	{
978 		de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests (new tcu::TestCaseGroup(testCtx, "format_features", "Checks depth format features"));
979 
980 		// Formats that must be supported in all implementations
981 		addFunctionCase(formatFeaturesTests.get(),
982 				"support_d16_unorm",
983 				"Tests if VK_FORMAT_D16_UNORM is supported as depth/stencil attachment format",
984 				testSupportsDepthStencilFormat,
985 				VK_FORMAT_D16_UNORM);
986 
987 		// Sets where at least one of the formats must be supported
988 		const VkFormat	depthOnlyFormats[]		= { VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT };
989 		const VkFormat	depthStencilFormats[]	= { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
990 
991 		addFunctionCase(formatFeaturesTests.get(),
992 				"support_d24_unorm_or_d32_sfloat",
993 				"Tests if any of VK_FORMAT_D24_UNORM_X8 or VK_FORMAT_D32_SFLOAT are supported as depth/stencil attachment format",
994 				testSupportsAtLeastOneDepthStencilFormat,
995 				std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats)));
996 
997 		addFunctionCase(formatFeaturesTests.get(),
998 				"support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint",
999 				"Tests if any of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT are supported as depth/stencil attachment format",
1000 				testSupportsAtLeastOneDepthStencilFormat,
1001 				std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats)));
1002 
1003 		depthTests->addChild(formatFeaturesTests.release());
1004 	}
1005 
1006 	for (deUint32 colorAttachmentEnabledIdx = 0; colorAttachmentEnabledIdx < DE_LENGTH_OF_ARRAY(colorAttachmentEnabled); colorAttachmentEnabledIdx++)
1007 	{
1008 		const bool colorEnabled = colorAttachmentEnabled[colorAttachmentEnabledIdx];
1009 
1010 		// Tests for format and compare operators
1011 		{
1012 			de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different depth formats"));
1013 
1014 			for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++)
1015 			{
1016 				const bool		hasDepth					= tcu::hasDepthComponent(mapVkFormat(depthFormats[formatNdx]).order);
1017 				const bool		hasStencil					= tcu::hasStencilComponent(mapVkFormat(depthFormats[formatNdx]).order);
1018 				const int		separateLayoutsLoopCount	= (hasDepth && hasStencil) ? 2 : 1;
1019 
1020 				for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1021 				{
1022 					const bool			useSeparateDepthStencilLayouts	= bool(separateDepthStencilLayouts);
1023 
1024 					de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
1025 								(getFormatCaseName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "")).c_str(),
1026 								(std::string("Uses format ") + getFormatName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? " with separate depth/stencil layouts" : "")).c_str()));
1027 					de::MovePtr<tcu::TestCaseGroup>	compareOpsTests	(new tcu::TestCaseGroup(testCtx, "compare_ops", "Combines depth compare operators"));
1028 
1029 					for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++)
1030 					{
1031 						compareOpsTests->addChild(new DepthTest(testCtx,
1032 									getCompareOpsName(depthOps[opsNdx]),
1033 									getCompareOpsDescription(depthOps[opsNdx]),
1034 									depthFormats[formatNdx],
1035 									depthOps[opsNdx],
1036 									useSeparateDepthStencilLayouts));
1037 
1038 						compareOpsTests->addChild(new DepthTest(testCtx,
1039 									getCompareOpsName(depthOps[opsNdx]) + "_depth_bounds_test",
1040 									getCompareOpsDescription(depthOps[opsNdx]) + " with depth bounds test enabled",
1041 									depthFormats[formatNdx],
1042 									depthOps[opsNdx],
1043 									useSeparateDepthStencilLayouts,
1044 									true,
1045 									0.1f,
1046 									0.25f,
1047 									true,
1048 									false,
1049 									colorEnabled));
1050 					}
1051 					// Special VkPipelineDepthStencilStateCreateInfo known to have issues
1052 					{
1053 						const VkCompareOp depthOpsSpecial[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER };
1054 
1055 						compareOpsTests->addChild(new DepthTest(testCtx,
1056 									"never_zerodepthbounds_depthdisabled_stencilenabled",
1057 									"special VkPipelineDepthStencilStateCreateInfo",
1058 									depthFormats[formatNdx],
1059 									depthOpsSpecial,
1060 									useSeparateDepthStencilLayouts,
1061 									true,
1062 									0.0f,
1063 									0.0f,
1064 									false,
1065 									true,
1066 									colorEnabled));
1067 					}
1068 					formatTest->addChild(compareOpsTests.release());
1069 
1070 					// Test case with depth test enabled, but depth write disabled
1071 					de::MovePtr<tcu::TestCaseGroup>	depthTestDisabled(new tcu::TestCaseGroup(testCtx, "depth_test_disabled", "Test for disabled depth test"));
1072 					{
1073 						const VkCompareOp depthOpsDepthTestDisabled[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS };
1074 						depthTestDisabled->addChild(new DepthTest(testCtx,
1075 									"depth_write_enabled",
1076 									"Depth writes should not occur if depth test is disabled",
1077 									depthFormats[formatNdx],
1078 									depthOpsDepthTestDisabled,
1079 									useSeparateDepthStencilLayouts,
1080 									false,			/* depthBoundsTestEnable */
1081 									0.0f,			/* depthBoundMin*/
1082 									1.0f,			/* depthBoundMax*/
1083 									false,			/* depthTestEnable */
1084 									false,			/* stencilTestEnable */
1085 									colorEnabled	/* colorAttachmentEnable */));
1086 					}
1087 					formatTest->addChild(depthTestDisabled.release());
1088 					formatTests->addChild(formatTest.release());
1089 				}
1090 			}
1091 			if (colorEnabled)
1092 				depthTests->addChild(formatTests.release());
1093 			else
1094 				noColorAttachmentTests->addChild(formatTests.release());
1095 		}
1096 	}
1097 	depthTests->addChild(noColorAttachmentTests.release());
1098 
1099 	return depthTests.release();
1100 }
1101 
1102 } // pipeline
1103 } // vkt
1104