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