• 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  * Copyright (c) 2023 LunarG, Inc.
8  * Copyright (c) 2023 Nintendo
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Depth Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktPipelineDepthTests.hpp"
28 #include "vktPipelineClearUtil.hpp"
29 #include "vktPipelineImageUtil.hpp"
30 #include "vktPipelineVertexUtil.hpp"
31 #include "vktPipelineReferenceRenderer.hpp"
32 #include "vktTestCase.hpp"
33 #include "vktTestCaseUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkRef.hpp"
39 #include "vkRefUtil.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkObjUtil.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "deUniquePtr.hpp"
45 #include "deStringUtil.hpp"
46 #include "deMemory.h"
47 
48 #include <sstream>
49 #include <vector>
50 
51 namespace vkt
52 {
53 namespace pipeline
54 {
55 
56 using namespace vk;
57 
58 namespace
59 {
60 
61 enum class DepthClipControlCase
62 {
63 	DISABLED			= 0,	// No depth clip control.
64 	NORMAL				= 1,	// Depth clip control with static viewport.
65 	NORMAL_W			= 2,	// Depth clip control with static viewport and .w different from 1.0f
66 	BEFORE_STATIC		= 3,	// Set dynamic viewport state, then bind a static pipeline.
67 	BEFORE_DYNAMIC		= 4,	// Set dynamic viewport state, bind dynamic pipeline.
68 	BEFORE_TWO_DYNAMICS	= 5,	// Set dynamic viewport state, bind dynamic pipeline with [0,1] view volume, then bind dynamic pipeline with [-1,1] view volume.
69 	AFTER_DYNAMIC		= 6,	// Bind dynamic pipeline, then set dynamic viewport state.
70 };
71 
isSupportedDepthStencilFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)72 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
73 {
74 	VkFormatProperties formatProps;
75 
76 	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
77 
78 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
79 }
80 
testSupportsDepthStencilFormat(Context & context,VkFormat format)81 tcu::TestStatus testSupportsDepthStencilFormat (Context& context, VkFormat format)
82 {
83 	DE_ASSERT(vk::isDepthStencilFormat(format));
84 
85 	if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
86 		return tcu::TestStatus::pass("Format can be used in depth/stencil attachment");
87 	else
88 		return tcu::TestStatus::fail("Unsupported depth/stencil attachment format");
89 }
90 
testSupportsAtLeastOneDepthStencilFormat(Context & context,const std::vector<VkFormat> formats)91 tcu::TestStatus testSupportsAtLeastOneDepthStencilFormat (Context& context, const std::vector<VkFormat> formats)
92 {
93 	std::ostringstream	supportedFormatsMsg;
94 	bool				pass					= false;
95 
96 	DE_ASSERT(!formats.empty());
97 
98 	for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++)
99 	{
100 		const VkFormat format = formats[formatNdx];
101 
102 		DE_ASSERT(vk::isDepthStencilFormat(format));
103 
104 		if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
105 		{
106 			pass = true;
107 			supportedFormatsMsg << vk::getFormatName(format);
108 
109 			if (formatNdx < formats.size() - 1)
110 				supportedFormatsMsg << ", ";
111 		}
112 	}
113 
114 	if (pass)
115 		return tcu::TestStatus::pass(std::string("Supported depth/stencil formats: ") + supportedFormatsMsg.str());
116 	else
117 		return tcu::TestStatus::fail("All depth/stencil formats are unsupported");
118 }
119 
120 class DepthTest : public vkt::TestCase
121 {
122 public:
123 	enum
124 	{
125 		QUAD_COUNT = 4
126 	};
127 
128 	static const float					quadDepths[QUAD_COUNT];
129 	static const float					quadDepthsMinusOneToOne[QUAD_COUNT];
130 	static const float					quadWs[QUAD_COUNT];
131 
132 										DepthTest				(tcu::TestContext&					testContext,
133 																 const std::string&					name,
134 																 const PipelineConstructionType		pipelineConstructionType,
135 																 const VkFormat						depthFormat,
136 																 const VkCompareOp					depthCompareOps[QUAD_COUNT],
137 																 const bool							separateDepthStencilLayouts,
138 																 const VkPrimitiveTopology			primitiveTopology				= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
139 																 const bool							depthBoundsTestEnable			= false,
140 																 const float						depthBoundsMin					= 0.0f,
141 																 const float						depthBoundsMax					= 1.0f,
142 																 const bool							depthTestEnable					= true,
143 																 const bool							stencilTestEnable				= false,
144 																 const bool							colorAttachmentEnable			= true,
145 																 const bool							hostVisible						= false,
146 																 const tcu::UVec2					renderSize						= tcu::UVec2(32, 32),
147 																 const DepthClipControlCase			depthClipControl				= DepthClipControlCase::DISABLED);
148 	virtual								~DepthTest				(void);
149 	virtual void						initPrograms			(SourceCollections& programCollection) const;
150 	virtual void						checkSupport			(Context& context) const;
151 	virtual TestInstance*				createInstance			(Context& context) const;
152 
153 private:
154 	const PipelineConstructionType		m_pipelineConstructionType;
155 	const VkFormat						m_depthFormat;
156 	const bool							m_separateDepthStencilLayouts;
157 	VkPrimitiveTopology					m_primitiveTopology;
158 	const bool							m_depthBoundsTestEnable;
159 	const float							m_depthBoundsMin;
160 	const float							m_depthBoundsMax;
161 	const bool							m_depthTestEnable;
162 	const bool							m_stencilTestEnable;
163 	const bool							m_colorAttachmentEnable;
164 	const bool							m_hostVisible;
165 	const tcu::UVec2					m_renderSize;
166 	const DepthClipControlCase			m_depthClipControl;
167 	VkCompareOp							m_depthCompareOps[QUAD_COUNT];
168 };
169 
170 class DepthTestInstance : public vkt::TestInstance
171 {
172 public:
173 										DepthTestInstance		(Context&							context,
174 																 const PipelineConstructionType		pipelineConstructionType,
175 																 const VkFormat						depthFormat,
176 																 const VkCompareOp					depthCompareOps[DepthTest::QUAD_COUNT],
177 																 const bool							separateDepthStencilLayouts,
178 																 const VkPrimitiveTopology			primitiveTopology,
179 																 const bool							depthBoundsTestEnable,
180 																 const float						depthBoundsMin,
181 																 const float						depthBoundsMax,
182 																 const bool							depthTestEnable,
183 																 const bool							stencilTestEnable,
184 																 const bool							colorAttachmentEnable,
185 																 const bool							hostVisible,
186 																 const tcu::UVec2					renderSize,
187 																 const DepthClipControlCase			depthClipControl);
188 
189 	virtual								~DepthTestInstance		(void);
190 	virtual tcu::TestStatus				iterate					(void);
191 
192 private:
193 	tcu::TestStatus						verifyImage				(void);
194 
195 private:
196 	VkCompareOp							m_depthCompareOps[DepthTest::QUAD_COUNT];
197 	const tcu::UVec2					m_renderSize;
198 	const VkFormat						m_colorFormat;
199 	const VkFormat						m_depthFormat;
200 	const bool							m_separateDepthStencilLayouts;
201 	VkPrimitiveTopology					m_primitiveTopology;
202 	const bool							m_depthBoundsTestEnable;
203 	const float							m_depthBoundsMin;
204 	const float							m_depthBoundsMax;
205 	const bool							m_depthTestEnable;
206 	const bool							m_stencilTestEnable;
207 	const bool							m_colorAttachmentEnable;
208 	const bool							m_hostVisible;
209 	const DepthClipControlCase			m_depthClipControl;
210 	VkImageSubresourceRange				m_depthImageSubresourceRange;
211 
212 	Move<VkImage>						m_colorImage;
213 	de::MovePtr<Allocation>				m_colorImageAlloc;
214 	Move<VkImage>						m_depthImage;
215 	de::MovePtr<Allocation>				m_depthImageAlloc;
216 	Move<VkImageView>					m_colorAttachmentView;
217 	Move<VkImageView>					m_depthAttachmentView;
218 	RenderPassWrapper					m_renderPass;
219 	Move<VkFramebuffer>					m_framebuffer;
220 
221 	ShaderWrapper						m_vertexShaderModule;
222 	ShaderWrapper						m_fragmentShaderModule;
223 
224 	Move<VkBuffer>						m_vertexBuffer;
225 	std::vector<Vertex4RGBA>			m_vertices;
226 	de::MovePtr<Allocation>				m_vertexBufferAlloc;
227 
228 	Move<VkBuffer>						m_altVertexBuffer;
229 	std::vector<Vertex4RGBA>			m_altVertices;
230 	de::MovePtr<Allocation>				m_altVertexBufferAlloc;
231 
232 	PipelineLayoutWrapper				m_pipelineLayout;
233 	GraphicsPipelineWrapper				m_graphicsPipelines[DepthTest::QUAD_COUNT];
234 	GraphicsPipelineWrapper				m_altGraphicsPipelines[DepthTest::QUAD_COUNT];
235 
236 	Move<VkCommandPool>					m_cmdPool;
237 	Move<VkCommandBuffer>				m_cmdBuffer;
238 };
239 
240 const float DepthTest::quadDepths[QUAD_COUNT] =
241 {
242 	0.1f,
243 	0.0f,
244 	0.3f,
245 	0.2f
246 };
247 
248 // Depth values suitable for the depth range of -1..1.
249 const float DepthTest::quadDepthsMinusOneToOne[QUAD_COUNT] =
250 {
251 	-0.8f,
252 	-1.0f,
253 	 0.6f,
254 	 0.2f
255 };
256 
257 const float DepthTest::quadWs[QUAD_COUNT] =
258 {
259 	2.0f,
260 	1.25f,
261 	0.5f,
262 	0.25f
263 };
264 
DepthTest(tcu::TestContext & testContext,const std::string & name,const PipelineConstructionType pipelineConstructionType,const VkFormat depthFormat,const VkCompareOp depthCompareOps[QUAD_COUNT],const bool separateDepthStencilLayouts,const VkPrimitiveTopology primitiveTopology,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable,const bool hostVisible,const tcu::UVec2 renderSize,const DepthClipControlCase depthClipControl)265 DepthTest::DepthTest (tcu::TestContext&					testContext,
266 					  const std::string&				name,
267 					  const PipelineConstructionType	pipelineConstructionType,
268 					  const VkFormat					depthFormat,
269 					  const VkCompareOp					depthCompareOps[QUAD_COUNT],
270 					  const bool						separateDepthStencilLayouts,
271 					  const VkPrimitiveTopology			primitiveTopology,
272 					  const bool						depthBoundsTestEnable,
273 					  const float						depthBoundsMin,
274 					  const float						depthBoundsMax,
275 					  const bool						depthTestEnable,
276 					  const bool						stencilTestEnable,
277 					  const bool						colorAttachmentEnable,
278 					  const bool						hostVisible,
279 						const tcu::UVec2				renderSize,
280 					  const DepthClipControlCase		depthClipControl)
281 	: vkt::TestCase					(testContext, name)
282 	, m_pipelineConstructionType	(pipelineConstructionType)
283 	, m_depthFormat					(depthFormat)
284 	, m_separateDepthStencilLayouts	(separateDepthStencilLayouts)
285 	, m_primitiveTopology			(primitiveTopology)
286 	, m_depthBoundsTestEnable		(depthBoundsTestEnable)
287 	, m_depthBoundsMin				(depthBoundsMin)
288 	, m_depthBoundsMax				(depthBoundsMax)
289 	, m_depthTestEnable				(depthTestEnable)
290 	, m_stencilTestEnable			(stencilTestEnable)
291 	, m_colorAttachmentEnable		(colorAttachmentEnable)
292 	, m_hostVisible					(hostVisible)
293 	, m_renderSize					(renderSize)
294 	, m_depthClipControl			(depthClipControl)
295 {
296 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT);
297 }
298 
~DepthTest(void)299 DepthTest::~DepthTest (void)
300 {
301 }
302 
checkSupport(Context & context) const303 void DepthTest::checkSupport (Context& context) const
304 {
305 	if (m_depthBoundsTestEnable)
306 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
307 
308 	if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat))
309 		throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat));
310 
311 	if (m_separateDepthStencilLayouts && !context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
312 		TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
313 
314 	checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
315 
316 #ifndef CTS_USES_VULKANSC
317 	if (m_depthClipControl != DepthClipControlCase::DISABLED && !context.isDeviceFunctionalitySupported("VK_EXT_depth_clip_control"))
318 		TCU_THROW(NotSupportedError, "VK_EXT_depth_clip_control is not supported");
319 #endif // CTS_USES_VULKANSC
320 }
321 
createInstance(Context & context) const322 TestInstance* DepthTest::createInstance (Context& context) const
323 {
324 	return new DepthTestInstance(context, m_pipelineConstructionType, m_depthFormat, m_depthCompareOps, m_separateDepthStencilLayouts, m_primitiveTopology, m_depthBoundsTestEnable, m_depthBoundsMin, m_depthBoundsMax, m_depthTestEnable, m_stencilTestEnable, m_colorAttachmentEnable, m_hostVisible, m_renderSize, m_depthClipControl);
325 }
326 
initPrograms(SourceCollections & programCollection) const327 void DepthTest::initPrograms (SourceCollections& programCollection) const
328 {
329 	if (m_colorAttachmentEnable)
330 	{
331 		programCollection.glslSources.add("color_vert") << glu::VertexSource(
332 			"#version 310 es\n"
333 			"layout(location = 0) in vec4 position;\n"
334 			"layout(location = 1) in vec4 color;\n"
335 			"layout(location = 0) out highp vec4 vtxColor;\n"
336 			"void main (void)\n"
337 			"{\n"
338 			"	gl_Position = position;\n"
339 			"	gl_PointSize = 1.0f;\n"
340 			"	vtxColor = color;\n"
341 			"}\n");
342 
343 		programCollection.glslSources.add("color_frag") << glu::FragmentSource(
344 			"#version 310 es\n"
345 			"layout(location = 0) in highp vec4 vtxColor;\n"
346 			"layout(location = 0) out highp vec4 fragColor;\n"
347 			"void main (void)\n"
348 			"{\n"
349 			"	fragColor = vtxColor;\n"
350 			"}\n");
351 	}
352 	else
353 	{
354 		programCollection.glslSources.add("color_vert") << glu::VertexSource(
355 			"#version 310 es\n"
356 			"layout(location = 0) in vec4 position;\n"
357 			"layout(location = 1) in vec4 color;\n"
358 			"void main (void)\n"
359 			"{\n"
360 			"	gl_Position = position;\n"
361 			"	gl_PointSize = 1.0f;\n"
362 			"}\n");
363 	}
364 }
365 
DepthTestInstance(Context & context,const PipelineConstructionType pipelineConstructionType,const VkFormat depthFormat,const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],const bool separateDepthStencilLayouts,const VkPrimitiveTopology primitiveTopology,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable,const bool hostVisible,const tcu::UVec2 renderSize,const DepthClipControlCase depthClipControl)366 DepthTestInstance::DepthTestInstance (Context&							context,
367 									  const PipelineConstructionType	pipelineConstructionType,
368 									  const VkFormat					depthFormat,
369 									  const VkCompareOp					depthCompareOps[DepthTest::QUAD_COUNT],
370 									  const bool						separateDepthStencilLayouts,
371 									  const VkPrimitiveTopology			primitiveTopology,
372 									  const bool						depthBoundsTestEnable,
373 									  const float						depthBoundsMin,
374 									  const float						depthBoundsMax,
375 									  const bool						depthTestEnable,
376 									  const bool						stencilTestEnable,
377 									  const bool						colorAttachmentEnable,
378 									  const bool						hostVisible,
379 									  const tcu::UVec2					renderSize,
380 									  const DepthClipControlCase		depthClipControl)
381 	: vkt::TestInstance				(context)
382 	, m_renderSize					(renderSize)
383 	, m_colorFormat					(colorAttachmentEnable ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_UNDEFINED)
384 	, m_depthFormat					(depthFormat)
385 	, m_separateDepthStencilLayouts	(separateDepthStencilLayouts)
386 	, m_primitiveTopology			(primitiveTopology)
387 	, m_depthBoundsTestEnable		(depthBoundsTestEnable)
388 	, m_depthBoundsMin				(depthBoundsMin)
389 	, m_depthBoundsMax				(depthBoundsMax)
390 	, m_depthTestEnable				(depthTestEnable)
391 	, m_stencilTestEnable			(stencilTestEnable)
392 	, m_colorAttachmentEnable		(colorAttachmentEnable)
393 	, m_hostVisible					(hostVisible)
394 	, m_depthClipControl			(depthClipControl)
395 	, m_graphicsPipelines
396 	{
397 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType },
398 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType },
399 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType },
400 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType }
401 	}
402 	, m_altGraphicsPipelines
403 	{
404 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType },
405 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType },
406 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType },
407 		{ context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType }
408 	}
409 {
410 	const DeviceInterface&		vk						= context.getDeviceInterface();
411 	const VkDevice				vkDevice				= context.getDevice();
412 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
413 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
414 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
415 	const bool					hasDepthClipControl		= (m_depthClipControl != DepthClipControlCase::DISABLED);
416 	const bool					useAltGraphicsPipelines	= (m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS ||
417 														   m_depthClipControl == DepthClipControlCase::NORMAL_W);
418 	const bool					useAltVertices			= m_depthClipControl == DepthClipControlCase::NORMAL_W;
419 
420 	// Copy depth operators
421 	deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT);
422 
423 	// Create color image
424 	if (m_colorAttachmentEnable)
425 	{
426 		const VkImageCreateInfo colorImageParams =
427 		{
428 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
429 			DE_NULL,																	// const void*				pNext;
430 			0u,																			// VkImageCreateFlags		flags;
431 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
432 			m_colorFormat,																// VkFormat					format;
433 			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
434 			1u,																			// deUint32					mipLevels;
435 			1u,																			// deUint32					arrayLayers;
436 			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
437 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
438 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
439 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
440 			1u,																			// deUint32					queueFamilyIndexCount;
441 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
442 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
443 		};
444 
445 		m_colorImage			= createImage(vk, vkDevice, &colorImageParams);
446 
447 		// Allocate and bind color image memory
448 		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
449 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
450 	}
451 
452 	// Create depth image
453 	{
454 		const VkImageCreateInfo depthImageParams =
455 		{
456 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
457 			DE_NULL,										// const void*				pNext;
458 			0u,												// VkImageCreateFlags		flags;
459 			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
460 			m_depthFormat,									// VkFormat					format;
461 			{ m_renderSize.x(), m_renderSize.y(), 1u },		// VkExtent3D				extent;
462 			1u,												// deUint32					mipLevels;
463 			1u,												// deUint32					arrayLayers;
464 			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
465 			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
466 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
467 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT,				// VkImageUsageFlags		usage;
468 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
469 			1u,												// deUint32					queueFamilyIndexCount;
470 			&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
471 			VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
472 		};
473 
474 		m_depthImage = createImage(vk, vkDevice, &depthImageParams);
475 
476 		// Allocate and bind depth image memory
477 		auto memReqs = MemoryRequirement::Local | MemoryRequirement::HostVisible;
478 		m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), m_hostVisible ? memReqs : MemoryRequirement::Any);
479 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
480 
481 		const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
482 																									  : VK_IMAGE_ASPECT_DEPTH_BIT);
483 		m_depthImageSubresourceRange    = makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers);
484 	}
485 
486 	// Create color attachment view
487 	if (m_colorAttachmentEnable)
488 	{
489 		const VkImageViewCreateInfo colorAttachmentViewParams =
490 		{
491 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
492 			DE_NULL,										// const void*				pNext;
493 			0u,												// VkImageViewCreateFlags	flags;
494 			*m_colorImage,									// VkImage					image;
495 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
496 			m_colorFormat,									// VkFormat					format;
497 			componentMappingRGBA,							// VkComponentMapping		components;
498 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
499 		};
500 
501 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
502 	}
503 
504 	// Create depth attachment view
505 	{
506 		const VkImageViewCreateInfo depthAttachmentViewParams =
507 		{
508 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
509 			DE_NULL,										// const void*				pNext;
510 			0u,												// VkImageViewCreateFlags	flags;
511 			*m_depthImage,									// VkImage					image;
512 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
513 			m_depthFormat,									// VkFormat					format;
514 			componentMappingRGBA,							// VkComponentMapping		components;
515 			m_depthImageSubresourceRange,					// VkImageSubresourceRange	subresourceRange;
516 		};
517 
518 		m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
519 	}
520 
521 	// Create render pass
522 	m_renderPass = RenderPassWrapper(pipelineConstructionType, vk, vkDevice, m_colorFormat, m_depthFormat);
523 
524 	// Create framebuffer
525 	{
526 		std::vector<VkImage>			images;
527 		std::vector<VkImageView>		attachmentBindInfos;
528 
529 		if (m_colorAttachmentEnable)
530 		{
531 			images.push_back(*m_colorImage);
532 			attachmentBindInfos.push_back(*m_colorAttachmentView);
533 		}
534 
535 		images.push_back(*m_depthImage);
536 		attachmentBindInfos.push_back(*m_depthAttachmentView);
537 
538 		const VkFramebufferCreateInfo	framebufferParams	=
539 		{
540 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
541 			DE_NULL,											// const void*					pNext;
542 			0u,													// VkFramebufferCreateFlags		flags;
543 			*m_renderPass,										// VkRenderPass					renderPass;
544 			(deUint32)attachmentBindInfos.size(),				// deUint32						attachmentCount;
545 			attachmentBindInfos.data(),							// const VkImageView*			pAttachments;
546 			(deUint32)m_renderSize.x(),							// deUint32						width;
547 			(deUint32)m_renderSize.y(),							// deUint32						height;
548 			1u													// deUint32						layers;
549 		};
550 
551 		m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images);
552 	}
553 
554 	// Create pipeline layout
555 	{
556 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
557 		{
558 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
559 			DE_NULL,											// const void*						pNext;
560 			0u,													// VkPipelineLayoutCreateFlags		flags;
561 			0u,													// deUint32							setLayoutCount;
562 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
563 			0u,													// deUint32							pushConstantRangeCount;
564 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
565 		};
566 
567 		m_pipelineLayout = PipelineLayoutWrapper(pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
568 	}
569 
570 	// Shader modules
571 	m_vertexShaderModule		= ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
572 	if (m_colorAttachmentEnable)
573 		m_fragmentShaderModule	= ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
574 
575 	const std::vector<VkViewport>	viewports		{ makeViewport(m_renderSize) };
576 	const std::vector<VkViewport>	badViewports	{ makeViewport(0.0f, 0.0f, static_cast<float>(m_renderSize.x()) / 2.0f, static_cast<float>(m_renderSize.y()) / 2.0f, 1.0f, 0.0f) };
577 	const std::vector<VkRect2D>		scissors		{ makeRect2D(m_renderSize) };
578 	const bool						dynamicViewport	= (static_cast<int>(m_depthClipControl) > static_cast<int>(DepthClipControlCase::BEFORE_STATIC));
579 
580 	// Create pipeline
581 	{
582 		const VkVertexInputBindingDescription				vertexInputBindingDescription
583 		{
584 			0u,							// deUint32					binding;
585 			sizeof(Vertex4RGBA),		// deUint32					strideInBytes;
586 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	inputRate;
587 		};
588 
589 		const VkVertexInputAttributeDescription				vertexInputAttributeDescriptions[2]
590 		{
591 			{
592 				0u,									// deUint32	location;
593 				0u,									// deUint32	binding;
594 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
595 				0u									// deUint32	offset;
596 			},
597 			{
598 				1u,									// deUint32	location;
599 				0u,									// deUint32	binding;
600 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
601 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
602 			}
603 		};
604 
605 		const VkPipelineVertexInputStateCreateInfo			vertexInputStateParams
606 		{
607 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
608 			DE_NULL,														// const void*								pNext;
609 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
610 			1u,																// deUint32									vertexBindingDescriptionCount;
611 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
612 			2u,																// deUint32									vertexAttributeDescriptionCount;
613 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
614 		};
615 
616 		const VkPipelineInputAssemblyStateCreateInfo		inputAssemblyStateParams
617 		{
618 			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType								sType
619 			DE_NULL,														// const void*									pNext
620 			0u,																// VkPipelineInputAssemblyStateCreateFlags		flags
621 			m_primitiveTopology,											// VkPrimitiveTopology							topology
622 			VK_FALSE														// VkBool32										primitiveRestartEnable
623 		};
624 
625 		VkPipelineDepthStencilStateCreateInfo				depthStencilStateParams
626 		{
627 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
628 			DE_NULL,													// const void*								pNext;
629 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
630 			m_depthTestEnable,											// VkBool32									depthTestEnable;
631 			true,														// VkBool32									depthWriteEnable;
632 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
633 			m_depthBoundsTestEnable,									// VkBool32									depthBoundsTestEnable;
634 			m_stencilTestEnable,										// VkBool32									stencilTestEnable;
635 			// VkStencilOpState	front;
636 			{
637 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
638 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
639 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
640 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
641 				0u,						// deUint32		compareMask;
642 				0u,						// deUint32		writeMask;
643 				0u,						// deUint32		reference;
644 			},
645 			// VkStencilOpState	back;
646 			{
647 				VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
648 				VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
649 				VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
650 				VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
651 				0u,						// deUint32		compareMask;
652 				0u,						// deUint32		writeMask;
653 				0u,						// deUint32		reference;
654 			},
655 			m_depthBoundsMin,											// float									minDepthBounds;
656 			m_depthBoundsMax,											// float									maxDepthBounds;
657 		};
658 
659 		// Make sure rasterization is not disabled when the fragment shader is missing.
660 		const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateParams
661 		{
662 			vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
663 			nullptr,														//	const void*								pNext;
664 			0u,																//	VkPipelineRasterizationStateCreateFlags	flags;
665 			VK_FALSE,														//	VkBool32								depthClampEnable;
666 			VK_FALSE,														//	VkBool32								rasterizerDiscardEnable;
667 			vk::VK_POLYGON_MODE_FILL,										//	VkPolygonMode							polygonMode;
668 			vk::VK_CULL_MODE_NONE,											//	VkCullModeFlags							cullMode;
669 			vk::VK_FRONT_FACE_COUNTER_CLOCKWISE,							//	VkFrontFace								frontFace;
670 			VK_FALSE,														//	VkBool32								depthBiasEnable;
671 			0.0f,															//	float									depthBiasConstantFactor;
672 			0.0f,															//	float									depthBiasClamp;
673 			0.0f,															//	float									depthBiasSlopeFactor;
674 			1.0f,															//	float									lineWidth;
675 		};
676 
677 		PipelineViewportDepthClipControlCreateInfoWrapper depthClipControlWrapper;
678 		PipelineViewportDepthClipControlCreateInfoWrapper depthClipControl01Wrapper;
679 
680 #ifndef CTS_USES_VULKANSC
681 		VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlCreateInfo
682 		{
683 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,	// VkStructureType	sType;
684 			DE_NULL,																// const void*		pNext;
685 			VK_TRUE,																// VkBool32			negativeOneToOne;
686 		};
687 		if (hasDepthClipControl)
688 			depthClipControlWrapper.ptr = &depthClipControlCreateInfo;
689 
690 		// Using the range 0,1 in the structure.
691 		VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlCreateInfo01
692 		{
693 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,	// VkStructureType	sType;
694 			DE_NULL,																// const void*		pNext;
695 			VK_FALSE,																// VkBool32			negativeOneToOne;
696 		};
697 		depthClipControl01Wrapper.ptr = &depthClipControlCreateInfo01;
698 #endif // CTS_USES_VULKANSC
699 
700 		// Dynamic viewport if needed.
701 		std::vector<VkDynamicState> dynamicStates;
702 
703 		if (m_depthClipControl == DepthClipControlCase::BEFORE_DYNAMIC
704 			|| m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS
705 			|| m_depthClipControl == DepthClipControlCase::AFTER_DYNAMIC)
706 		{
707 			dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
708 		}
709 
710 		const VkPipelineDynamicStateCreateInfo					dynamicStateCreateInfo			=
711 		{
712 			VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	//	VkStructureType						sType;
713 			nullptr,												//	const void*							pNext;
714 			0u,														//	VkPipelineDynamicStateCreateFlags	flags;
715 			static_cast<uint32_t>(dynamicStates.size()),			//	uint32_t							dynamicStateCount;
716 			de::dataOrNull(dynamicStates),							//	const VkDynamicState*				pDynamicStates;
717 		};
718 
719 		const vk::VkPipelineColorBlendAttachmentState blendState
720 		{
721 			VK_FALSE,
722 			VK_BLEND_FACTOR_ONE,
723 			VK_BLEND_FACTOR_ONE,
724 			VK_BLEND_OP_ADD,
725 			VK_BLEND_FACTOR_ONE,
726 			VK_BLEND_FACTOR_ONE,
727 			VK_BLEND_OP_ADD,
728 			VK_COLOR_COMPONENT_R_BIT |
729 			VK_COLOR_COMPONENT_G_BIT |
730 			VK_COLOR_COMPONENT_B_BIT |
731 			VK_COLOR_COMPONENT_A_BIT,
732 		};
733 
734 		deUint32 colorAttachmentCount = (m_colorFormat != VK_FORMAT_UNDEFINED) ? 1u : 0u;
735 
736 		const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo
737 		{
738 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType
739 			DE_NULL,														// const void*									pNext
740 			0u,																// VkPipelineColorBlendStateCreateFlags			flags
741 			VK_FALSE,														// VkBool32										logicOpEnable
742 			VK_LOGIC_OP_CLEAR,												// VkLogicOp									logicOp
743 			colorAttachmentCount,											// deUint32										attachmentCount
744 			&blendState,													// const VkPipelineColorBlendAttachmentState*	pAttachments
745 			{ 0.0f, 0.0f, 0.0f, 0.0f }										// float										blendConstants[4]
746 		};
747 
748 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
749 		{
750 			depthStencilStateParams.depthCompareOp	= depthCompareOps[quadNdx];
751 
752 			m_graphicsPipelines[quadNdx].setDefaultMultisampleState()
753 										.setDefaultColorBlendState()
754 										.setViewportStatePnext(depthClipControlWrapper.ptr)
755 										.setDynamicState(&dynamicStateCreateInfo)
756 										.setupVertexInputState(&vertexInputStateParams, &inputAssemblyStateParams)
757 										.setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports),
758 																	scissors,
759 																	m_pipelineLayout,
760 																	*m_renderPass,
761 																	0u,
762 																	m_vertexShaderModule,
763 																	&rasterizationStateParams)
764 										.setupFragmentShaderState(m_pipelineLayout,
765 																	*m_renderPass,
766 																	0u,
767 																	m_fragmentShaderModule,
768 																	&depthStencilStateParams)
769 										.setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo)
770 										.setMonolithicPipelineLayout(m_pipelineLayout)
771 										.buildPipeline();
772 
773 			if (useAltGraphicsPipelines)
774 			{
775 				if (m_depthClipControl == DepthClipControlCase::NORMAL_W)
776 				{
777 					m_altGraphicsPipelines[quadNdx].setDefaultMultisampleState()
778 												   .setDefaultColorBlendState()
779 												   .setViewportStatePnext(depthClipControl01Wrapper.ptr)
780 												   .setDynamicState(&dynamicStateCreateInfo)
781 												   .setupVertexInputState(&vertexInputStateParams, &inputAssemblyStateParams)
782 												   .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports),
783 																				scissors,
784 																				m_pipelineLayout,
785 																				*m_renderPass,
786 																				0u,
787 																				m_vertexShaderModule,
788 																				&rasterizationStateParams)
789 												   .setupFragmentShaderState(m_pipelineLayout,
790 																		*m_renderPass,
791 																		0u,
792 																		m_fragmentShaderModule,
793 																		&depthStencilStateParams)
794 												   .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo)
795 												   .setMonolithicPipelineLayout(m_pipelineLayout)
796 												   .buildPipeline();
797 				}
798 				else
799 				{
800 					m_altGraphicsPipelines[quadNdx].setDefaultMultisampleState()
801 												   .setDefaultColorBlendState()
802 												   .setViewportStatePnext(depthClipControl01Wrapper.ptr)
803 												   .setDynamicState(&dynamicStateCreateInfo)
804 												   .setupVertexInputState(&vertexInputStateParams)
805 												   .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports),
806 																					scissors,
807 																					m_pipelineLayout,
808 																					*m_renderPass,
809 																					0u,
810 																					m_vertexShaderModule,
811 																					&rasterizationStateParams)
812 												   .setupFragmentShaderState(m_pipelineLayout,
813 																					*m_renderPass,
814 																					0u,
815 																					m_fragmentShaderModule,
816 																					&depthStencilStateParams)
817 												   .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo)
818 												   .setMonolithicPipelineLayout(m_pipelineLayout)
819 												   .buildPipeline();
820 				}
821 			}
822 		}
823 	}
824 
825 	// Create vertex buffer
826 	{
827 		const VkBufferCreateInfo vertexBufferParams =
828 		{
829 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
830 			DE_NULL,									// const void*			pNext;
831 			0u,											// VkBufferCreateFlags	flags;
832 			1024u,										// VkDeviceSize			size;
833 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
834 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
835 			1u,											// deUint32				queueFamilyIndexCount;
836 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
837 		};
838 
839 		m_vertices			= createOverlappingQuads();
840 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
841 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
842 
843 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
844 
845 		if (useAltVertices) {
846 			m_altVertices			= createOverlappingQuads();
847 			m_altVertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
848 			m_altVertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_altVertexBuffer), MemoryRequirement::HostVisible);
849 
850 			VK_CHECK(vk.bindBufferMemory(vkDevice, *m_altVertexBuffer, m_altVertexBufferAlloc->getMemory(), m_altVertexBufferAlloc->getOffset()));
851 		}
852 
853 		// Adjust depths
854 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
855 			for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
856 			{
857 				m_vertices[quadNdx * 6 + vertexNdx].position.z() = (hasDepthClipControl ? DepthTest::quadDepthsMinusOneToOne[quadNdx] : DepthTest::quadDepths[quadNdx]);
858 				if (m_depthClipControl == DepthClipControlCase::NORMAL_W)
859 				{
860 					const float w = DepthTest::quadWs[quadNdx];
861 					m_vertices[quadNdx * 6 + vertexNdx].position.x() *= w;
862 					m_vertices[quadNdx * 6 + vertexNdx].position.y() *= w;
863 					m_vertices[quadNdx * 6 + vertexNdx].position.z() *= w;
864 					m_vertices[quadNdx * 6 + vertexNdx].position.w() = w;
865 				}
866 				if (useAltVertices)
867 				{
868 					m_altVertices[quadNdx * 6 + vertexNdx].position = m_vertices[quadNdx * 6 + vertexNdx].position;
869 					float z = m_altVertices[quadNdx * 6 + vertexNdx].position.z();
870 					float w = m_altVertices[quadNdx * 6 + vertexNdx].position.w();
871 					if (depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_NOT_EQUAL ||
872 						depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_LESS ||
873 						depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_LESS_OR_EQUAL)
874 					{
875 						z += 0.01f;
876 					}
877 					else if (depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_GREATER ||
878 							 depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_GREATER_OR_EQUAL)
879 					{
880 						z -= 0.01f;
881 					}
882 					m_altVertices[quadNdx * 6 + vertexNdx].position.z() = (z + w) * 0.5f;
883 				}
884 			}
885 
886 		// Load vertices into vertex buffer
887 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
888 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
889 
890 		if (useAltVertices) {
891 			deMemcpy(m_altVertexBufferAlloc->getHostPtr(), m_altVertices.data(), m_altVertices.size() * sizeof(Vertex4RGBA));
892 			flushAlloc(vk, vkDevice, *m_altVertexBufferAlloc);
893 		}
894 	}
895 
896 	// Create command pool
897 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
898 
899 	// Create command buffer
900 	{
901 		std::vector<VkClearValue>			attachmentClearValues;
902 
903 		if (m_colorAttachmentEnable)
904 			attachmentClearValues.push_back(defaultClearValue(m_colorFormat));
905 
906 		attachmentClearValues.push_back(defaultClearValue(m_depthFormat));
907 
908 		const VkImageMemoryBarrier			colorBarrier					=
909 		{
910 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
911 			DE_NULL,																// const void*                pNext;
912 			(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
913 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags              dstAccessMask;
914 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
915 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,								// VkImageLayout              newLayout;
916 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
917 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
918 			*m_colorImage,															// VkImage                    image;
919 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange    subresourceRange;
920 		};
921 
922 		VkImageSubresourceRange				depthBarrierSubresourceRange	= m_depthImageSubresourceRange;
923 		VkImageLayout						newLayout						= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
924 		if (m_separateDepthStencilLayouts)
925 		{
926 			depthBarrierSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
927 			newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
928 		}
929 
930 		const VkImageMemoryBarrier			depthBarrier					=
931 		{
932 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
933 			DE_NULL,																// const void*                pNext;
934 			(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
935 			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,							// VkAccessFlags              dstAccessMask;
936 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
937 			newLayout										,						// VkImageLayout              newLayout;
938 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
939 			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
940 			*m_depthImage,															// VkImage                    image;
941 			depthBarrierSubresourceRange,											// VkImageSubresourceRange    subresourceRange;
942 		};
943 
944 		std::vector<VkImageMemoryBarrier>	imageLayoutBarriers;
945 
946 		if (m_colorAttachmentEnable)
947 			imageLayoutBarriers.push_back(colorBarrier);
948 
949 		imageLayoutBarriers.push_back(depthBarrier);
950 
951 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
952 
953 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
954 
955 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
956 			VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
957 			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), imageLayoutBarriers.data());
958 
959 		m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)attachmentClearValues.size(), attachmentClearValues.data());
960 
961 		const VkDeviceSize quadOffset = (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
962 
963 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
964 		{
965 			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
966 
967 			if (m_depthClipControl == DepthClipControlCase::NORMAL_W && depthCompareOps[quadNdx] != vk::VK_COMPARE_OP_NEVER)
968 			{
969 				m_altGraphicsPipelines[quadNdx].bind(*m_cmdBuffer);
970 				vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_altVertexBuffer.get(), &vertexBufferOffset);
971 				vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_altVertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
972 			}
973 
974 			if (m_depthClipControl == DepthClipControlCase::BEFORE_STATIC
975 				|| m_depthClipControl == DepthClipControlCase::BEFORE_DYNAMIC
976 				|| m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS)
977 			{
978 				if (vk::isConstructionTypeShaderObject(pipelineConstructionType))
979 				{
980 #ifndef CTS_USES_VULKANSC
981 					vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, viewports.data());
982 #else
983 					vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, viewports.data());
984 #endif
985 				}
986 				else
987 				{
988 					vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, viewports.data());
989 				}
990 			}
991 
992 			if (m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS)
993 				m_altGraphicsPipelines[quadNdx].bind(*m_cmdBuffer);
994 			m_graphicsPipelines[quadNdx].bind(*m_cmdBuffer);
995 
996 			if (m_depthClipControl == DepthClipControlCase::AFTER_DYNAMIC)
997 			{
998 				if (vk::isConstructionTypeShaderObject(pipelineConstructionType))
999 				{
1000 #ifndef CTS_USES_VULKANSC
1001 					vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, viewports.data());
1002 #else
1003 					vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, viewports.data());
1004 #endif
1005 				}
1006 				else
1007 				{
1008 					vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, viewports.data());
1009 				}
1010 			}
1011 
1012 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1013 			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
1014 		}
1015 
1016 		m_renderPass.end(vk, *m_cmdBuffer);
1017 		endCommandBuffer(vk, *m_cmdBuffer);
1018 	}
1019 }
1020 
~DepthTestInstance(void)1021 DepthTestInstance::~DepthTestInstance (void)
1022 {
1023 }
1024 
iterate(void)1025 tcu::TestStatus DepthTestInstance::iterate (void)
1026 {
1027 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1028 	const VkDevice				vkDevice	= m_context.getDevice();
1029 	const VkQueue				queue		= m_context.getUniversalQueue();
1030 
1031 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1032 
1033 	return verifyImage();
1034 }
1035 
verifyImage(void)1036 tcu::TestStatus DepthTestInstance::verifyImage (void)
1037 {
1038 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
1039 	const tcu::TextureFormat	tcuDepthFormat	= mapVkFormat(m_depthFormat);
1040 	const ColorVertexShader		vertexShader;
1041 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat, (m_depthClipControl != DepthClipControlCase::DISABLED));
1042 	const rr::Program			program			(&vertexShader, &fragmentShader);
1043 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1044 	bool						colorCompareOk	= false;
1045 	bool						depthCompareOk	= false;
1046 
1047 	// Render reference image
1048 	{
1049 		for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
1050 		{
1051 			// Set depth state
1052 			rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1053 			renderState.fragOps.depthTestEnabled = m_depthTestEnable;
1054 			renderState.fragOps.depthFunc = mapVkCompareOp(m_depthCompareOps[quadNdx]);
1055 			if (m_depthBoundsTestEnable)
1056 			{
1057 				renderState.fragOps.depthBoundsTestEnabled = true;
1058 				renderState.fragOps.minDepthBound = m_depthBoundsMin;
1059 				renderState.fragOps.maxDepthBound = m_depthBoundsMax;
1060 			}
1061 
1062 			refRenderer.draw(renderState,
1063 							 mapVkPrimitiveTopology(m_primitiveTopology),
1064 							 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
1065 													  m_vertices.begin() + (quadNdx + 1) * 6));
1066 		}
1067 	}
1068 
1069 	// Compare color result with reference image
1070 	if (m_colorAttachmentEnable)
1071 	{
1072 		const DeviceInterface&			vk					= m_context.getDeviceInterface();
1073 		const VkDevice					vkDevice			= m_context.getDevice();
1074 		const VkQueue					queue				= m_context.getUniversalQueue();
1075 		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
1076 		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1077 		de::MovePtr<tcu::TextureLevel>	result				= readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
1078 
1079 		colorCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1080 															  "IntImageCompare",
1081 															  "Image comparison",
1082 															  refRenderer.getAccess(),
1083 															  result->getAccess(),
1084 															  tcu::UVec4(2, 2, 2, 2),
1085 															  tcu::IVec3(1, 1, 0),
1086 															  true,
1087 															  tcu::COMPARE_LOG_RESULT);
1088 	}
1089 	else
1090 	{
1091 		colorCompareOk = true;
1092 	}
1093 
1094 	// Compare depth result with reference image
1095 	{
1096 		const DeviceInterface&			vk					= m_context.getDeviceInterface();
1097 		const VkDevice					vkDevice			= m_context.getDevice();
1098 		const VkQueue					queue				= m_context.getUniversalQueue();
1099 		const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
1100 		SimpleAllocator					allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1101 		de::MovePtr<tcu::TextureLevel>	result				= readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_depthFormat, m_renderSize);
1102 
1103 		{
1104 			de::MovePtr<tcu::TextureLevel>	convertedReferenceLevel;
1105 			tcu::Maybe<tcu::TextureFormat>	convertedFormat;
1106 
1107 			if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_24_8_REV)
1108 			{
1109 				convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT24);
1110 			}
1111 			else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_16_8_8)
1112 			{
1113 				convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
1114 			}
1115 			else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV)
1116 			{
1117 				convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
1118 			}
1119 
1120 			if (convertedFormat)
1121 			{
1122 				convertedReferenceLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(*convertedFormat, refRenderer.getDepthStencilAccess().getSize().x(), refRenderer.getDepthStencilAccess().getSize().y()));
1123 				tcu::copy(convertedReferenceLevel->getAccess(), refRenderer.getDepthStencilAccess());
1124 			}
1125 
1126 			float depthThreshold = 0.0f;
1127 
1128 			if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
1129 			{
1130 				const tcu::IVec4	formatBits = tcu::getTextureFormatBitDepth(result->getFormat());
1131 				depthThreshold = 1.0f / static_cast<float>((1 << formatBits[0]) - 1);
1132 			}
1133 			else if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1134 			{
1135 				depthThreshold = 0.0000001f;
1136 			}
1137 			else
1138 				TCU_FAIL("unrecognized format type class");
1139 
1140 			depthCompareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1141 														"DepthImageCompare",
1142 														"Depth image comparison",
1143 														convertedReferenceLevel ? convertedReferenceLevel->getAccess() : refRenderer.getDepthStencilAccess(),
1144 														result->getAccess(),
1145 														tcu::Vec4(depthThreshold, 0.0f, 0.0f, 0.0f),
1146 														tcu::COMPARE_LOG_RESULT);
1147 		}
1148 	}
1149 
1150 	if (colorCompareOk && depthCompareOk)
1151 		return tcu::TestStatus::pass("Result image matches reference");
1152 	else
1153 		return tcu::TestStatus::fail("Image mismatch");
1154 }
1155 
getFormatCaseName(const VkFormat format)1156 std::string getFormatCaseName (const VkFormat format)
1157 {
1158 	const std::string	fullName	= getFormatName(format);
1159 
1160 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
1161 
1162 	return de::toLower(fullName.substr(10));
1163 }
1164 
getTopologyName(const VkPrimitiveTopology topology)1165 std::string getTopologyName (const VkPrimitiveTopology topology) {
1166 	const std::string	fullName	= getPrimitiveTopologyName(topology);
1167 
1168 	DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_"));
1169 
1170 	return de::toLower(fullName.substr(22));
1171 }
1172 
getCompareOpsName(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])1173 std::string	getCompareOpsName (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
1174 {
1175 	std::ostringstream name;
1176 
1177 	for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
1178 	{
1179 		const std::string	fullOpName	= getCompareOpName(quadDepthOps[quadNdx]);
1180 
1181 		DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_"));
1182 
1183 		name << de::toLower(fullOpName.substr(14));
1184 
1185 		if (quadNdx < DepthTest::QUAD_COUNT - 1)
1186 			name << "_";
1187 	}
1188 
1189 	return name.str();
1190 }
1191 
1192 } // anonymous
1193 
createDepthTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)1194 tcu::TestCaseGroup* createDepthTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
1195 {
1196 	const VkFormat			depthFormats[]						=
1197 	{
1198 		VK_FORMAT_D16_UNORM,
1199 		VK_FORMAT_X8_D24_UNORM_PACK32,
1200 		VK_FORMAT_D32_SFLOAT,
1201 		VK_FORMAT_D16_UNORM_S8_UINT,
1202 		VK_FORMAT_D24_UNORM_S8_UINT,
1203 		VK_FORMAT_D32_SFLOAT_S8_UINT
1204 	};
1205 
1206 	// Each entry configures the depth compare operators of QUAD_COUNT quads.
1207 	// All entries cover pair-wise combinations of compare operators.
1208 	const VkCompareOp		depthOps[][DepthTest::QUAD_COUNT]	=
1209 	{
1210 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL },
1211 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER },
1212 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL },
1213 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
1214 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
1215 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS },
1216 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NEVER },
1217 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
1218 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS },
1219 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
1220 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
1221 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL },
1222 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL },
1223 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS },
1224 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
1225 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS },
1226 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS },
1227 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER },
1228 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL },
1229 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
1230 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER },
1231 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER },
1232 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL },
1233 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
1234 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_GREATER_OR_EQUAL },
1235 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL },
1236 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS },
1237 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
1238 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER },
1239 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
1240 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL },
1241 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
1242 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS },
1243 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER_OR_EQUAL },
1244 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER },
1245 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL },
1246 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS_OR_EQUAL },
1247 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NEVER },
1248 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL },
1249 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL },
1250 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
1251 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_ALWAYS },
1252 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS },
1253 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL },
1254 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
1255 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_NOT_EQUAL },
1256 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
1257 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER_OR_EQUAL },
1258 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
1259 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS },
1260 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_ALWAYS },
1261 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER },
1262 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_EQUAL },
1263 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NOT_EQUAL },
1264 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_LESS },
1265 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NEVER },
1266 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS,				VK_COMPARE_OP_NOT_EQUAL },
1267 		{ VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_EQUAL },
1268 		{ VK_COMPARE_OP_EQUAL,				VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL },
1269 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER },
1270 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER },
1271 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_GREATER },
1272 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_NOT_EQUAL },
1273 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_ALWAYS },
1274 		{ VK_COMPARE_OP_LESS_OR_EQUAL,		VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER },
1275 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER },
1276 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL },
1277 		{ VK_COMPARE_OP_ALWAYS,				VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_LESS_OR_EQUAL },
1278 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_LESS },
1279 		{ VK_COMPARE_OP_GREATER_OR_EQUAL,	VK_COMPARE_OP_NEVER,			VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_NEVER },
1280 		{ VK_COMPARE_OP_LESS,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_EQUAL,			VK_COMPARE_OP_EQUAL },
1281 		{ VK_COMPARE_OP_NEVER,				VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS,			VK_COMPARE_OP_GREATER_OR_EQUAL },
1282 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER,			VK_COMPARE_OP_ALWAYS },
1283 		{ VK_COMPARE_OP_NOT_EQUAL,			VK_COMPARE_OP_LESS_OR_EQUAL,	VK_COMPARE_OP_NOT_EQUAL,		VK_COMPARE_OP_GREATER }
1284 	};
1285 
1286 	const bool						colorAttachmentEnabled[]	= { true, false };
1287 
1288 	const VkPrimitiveTopology		primitiveTopologies[]		= { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST };
1289 
1290 	de::MovePtr<tcu::TestCaseGroup>	depthTests					(new tcu::TestCaseGroup(testCtx, "depth"));
1291 	de::MovePtr<tcu::TestCaseGroup>	noColorAttachmentTests		(new tcu::TestCaseGroup(testCtx, "nocolor"));
1292 
1293 	// Tests for format features
1294 	if (!isConstructionTypeLibrary(pipelineConstructionType))
1295 	{
1296 		de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests (new tcu::TestCaseGroup(testCtx, "format_features"));
1297 
1298 		// Formats that must be supported in all implementations
1299 		addFunctionCase(formatFeaturesTests.get(),
1300 				"support_d16_unorm",
1301 				testSupportsDepthStencilFormat,
1302 				VK_FORMAT_D16_UNORM);
1303 
1304 		// Sets where at least one of the formats must be supported
1305 		const VkFormat	depthOnlyFormats[]		= { VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT };
1306 		const VkFormat	depthStencilFormats[]	= { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
1307 
1308 		addFunctionCase(formatFeaturesTests.get(),
1309 				"support_d24_unorm_or_d32_sfloat",
1310 				testSupportsAtLeastOneDepthStencilFormat,
1311 				std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats)));
1312 
1313 		addFunctionCase(formatFeaturesTests.get(),
1314 				"support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint",
1315 				testSupportsAtLeastOneDepthStencilFormat,
1316 				std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats)));
1317 
1318 		depthTests->addChild(formatFeaturesTests.release());
1319 	}
1320 
1321 	for (deUint32 colorAttachmentEnabledIdx = 0; colorAttachmentEnabledIdx < DE_LENGTH_OF_ARRAY(colorAttachmentEnabled); colorAttachmentEnabledIdx++)
1322 	{
1323 		const bool colorEnabled = colorAttachmentEnabled[colorAttachmentEnabledIdx];
1324 
1325 		// Tests for format and compare operators
1326 		{
1327 			// Uses different depth formats
1328 			de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format"));
1329 
1330 			for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++)
1331 			{
1332 				const bool		hasDepth					= tcu::hasDepthComponent(mapVkFormat(depthFormats[formatNdx]).order);
1333 				const bool		hasStencil					= tcu::hasStencilComponent(mapVkFormat(depthFormats[formatNdx]).order);
1334 				const int		separateLayoutsLoopCount	= (hasDepth && hasStencil) ? 2 : 1;
1335 
1336 				for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1337 				{
1338 					const bool			useSeparateDepthStencilLayouts	= bool(separateDepthStencilLayouts);
1339 
1340 					de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
1341 								(getFormatCaseName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "")).c_str(),
1342 								(std::string("Uses format ") + getFormatName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? " with separate depth/stencil layouts" : "")).c_str()));
1343 					de::MovePtr<tcu::TestCaseGroup>	compareOpsTests	(new tcu::TestCaseGroup(testCtx, "compare_ops", "Combines depth compare operators"));
1344 
1345 					for (size_t topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveTopologies); topologyNdx++) {
1346 						const std::string topologyName = getTopologyName(primitiveTopologies[topologyNdx]) + "_";
1347 						for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++)
1348 						{
1349 							compareOpsTests->addChild(new DepthTest(testCtx,
1350 										topologyName + getCompareOpsName(depthOps[opsNdx]),
1351 										pipelineConstructionType,
1352 										depthFormats[formatNdx],
1353 										depthOps[opsNdx],
1354 										useSeparateDepthStencilLayouts,
1355 										primitiveTopologies[topologyNdx],
1356 										false,
1357 										0.0f,
1358 										1.0f));
1359 
1360 							compareOpsTests->addChild(new DepthTest(testCtx,
1361 										topologyName + getCompareOpsName(depthOps[opsNdx]) + "_depth_bounds_test",
1362 										pipelineConstructionType,
1363 										depthFormats[formatNdx],
1364 										depthOps[opsNdx],
1365 										useSeparateDepthStencilLayouts,
1366 										primitiveTopologies[topologyNdx],
1367 										true,
1368 										0.1f,
1369 										0.25f,
1370 										true,
1371 										false,
1372 										colorEnabled));
1373 						}
1374 					}
1375 					// Special VkPipelineDepthStencilStateCreateInfo known to have issues
1376 					{
1377 						const VkCompareOp depthOpsSpecial[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER };
1378 
1379 						compareOpsTests->addChild(new DepthTest(testCtx,
1380 									"never_zerodepthbounds_depthdisabled_stencilenabled",
1381 									pipelineConstructionType,
1382 									depthFormats[formatNdx],
1383 									depthOpsSpecial,
1384 									useSeparateDepthStencilLayouts,
1385 									VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1386 									true,
1387 									0.0f,
1388 									0.0f,
1389 									false,
1390 									true,
1391 									colorEnabled));
1392 					}
1393 					formatTest->addChild(compareOpsTests.release());
1394 
1395 					// Test case with depth test enabled, but depth write disabled
1396 					de::MovePtr<tcu::TestCaseGroup>	depthTestDisabled(new tcu::TestCaseGroup(testCtx, "depth_test_disabled"));
1397 					{
1398 						const VkCompareOp depthOpsDepthTestDisabled[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS };
1399 						depthTestDisabled->addChild(new DepthTest(testCtx,
1400 									"depth_write_enabled",
1401 									pipelineConstructionType,
1402 									depthFormats[formatNdx],
1403 									depthOpsDepthTestDisabled,
1404 									useSeparateDepthStencilLayouts,
1405 									VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1406 									false,			/* depthBoundsTestEnable */
1407 									0.0f,			/* depthBoundMin*/
1408 									1.0f,			/* depthBoundMax*/
1409 									false,			/* depthTestEnable */
1410 									false,			/* stencilTestEnable */
1411 									colorEnabled	/* colorAttachmentEnable */));
1412 					}
1413 					formatTest->addChild(depthTestDisabled.release());
1414 
1415 					// Test case with depth buffer placed in local memory
1416 					de::MovePtr<tcu::TestCaseGroup>	hostVisibleTests(new tcu::TestCaseGroup(testCtx, "host_visible", "Test for disabled depth test"));
1417 					{
1418 						const VkCompareOp hostVisibleOps[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS };
1419 
1420 						// Depth buffer placed in local memory
1421 						hostVisibleTests->addChild(new DepthTest(testCtx,
1422 									"local_memory_depth_buffer",
1423 									pipelineConstructionType,
1424 									depthFormats[formatNdx],
1425 									hostVisibleOps,
1426 									useSeparateDepthStencilLayouts,
1427 									VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1428 									false,					/* depthBoundsTestEnable */
1429 									0.0f,					/* depthBoundMin*/
1430 									1.0f,					/* depthBoundMax*/
1431 									true,					/* depthTestEnable */
1432 									false,					/* stencilTestEnable */
1433 									colorEnabled,			/* colorAttachmentEnable */
1434 									true,					/* hostVisible */
1435 									tcu::UVec2(256, 256)	/*renderSize*/));
1436 					}
1437 
1438 					formatTest->addChild(hostVisibleTests.release());
1439 					formatTests->addChild(formatTest.release());
1440 				}
1441 			}
1442 			if (colorEnabled)
1443 				depthTests->addChild(formatTests.release());
1444 			else
1445 				noColorAttachmentTests->addChild(formatTests.release());
1446 		}
1447 	}
1448 	depthTests->addChild(noColorAttachmentTests.release());
1449 
1450 #ifndef CTS_USES_VULKANSC
1451 	de::MovePtr<tcu::TestCaseGroup>	depthClipControlTests		(new tcu::TestCaseGroup(testCtx, "depth_clip_control", "Depth tests with depth clip control enabled"));
1452 	{
1453 		const VkCompareOp compareOps[] = { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS };
1454 
1455 		const struct
1456 		{
1457 			const DepthClipControlCase	viewportCase;
1458 			const std::string			suffix;
1459 		} kViewportCases[] =
1460 		{
1461 			{ DepthClipControlCase::NORMAL,					""								},
1462 			{ DepthClipControlCase::NORMAL_W,				"_different_w"					},
1463 			{ DepthClipControlCase::BEFORE_STATIC,			"_viewport_before_static"		},
1464 			{ DepthClipControlCase::BEFORE_DYNAMIC,			"_viewport_before_dynamic"		},
1465 			{ DepthClipControlCase::BEFORE_TWO_DYNAMICS,	"_viewport_before_two_dynamic"	},
1466 			{ DepthClipControlCase::AFTER_DYNAMIC,			"_viewport_after_dynamic"		},
1467 		};
1468 
1469 		for (const auto& viewportCase : kViewportCases)
1470 			for (const auto& format : depthFormats)
1471 				for (const auto& compareOp : compareOps)
1472 				{
1473 					std::string testName = getFormatCaseName(format) + "_" + de::toLower(std::string(getCompareOpName(compareOp)).substr(14)) + viewportCase.suffix;
1474 
1475 					const VkCompareOp ops[DepthTest::QUAD_COUNT] = { compareOp, compareOp, compareOp, compareOp };
1476 					depthClipControlTests->addChild(new DepthTest(testCtx, testName, pipelineConstructionType, format, ops,
1477 													false, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false, 0.0f, 1.0f, true, false, true, false, tcu::UVec2(32,32), viewportCase.viewportCase));
1478 				}
1479 	}
1480 	depthTests->addChild(depthClipControlTests.release());
1481 #endif // CTS_USES_VULKANSC
1482 
1483 	return depthTests.release();
1484 }
1485 
1486 } // pipeline
1487 } // vkt
1488