• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Valve Corporation.
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 VK_EXT_depth_range_unrestricted Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktPipelineDepthRangeUnrestrictedTests.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktPipelineClearUtil.hpp"
30 #include "vktPipelineImageUtil.hpp"
31 #include "vktPipelineReferenceRenderer.hpp"
32 #include "vktTestCase.hpp"
33 #include "vktTestCaseUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkBuilderUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkObjUtil.hpp"
42 
43 #include "tcuTestLog.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuCommandLine.hpp"
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 testDynamicStaticMode
62 {
63 	TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC	= 0,
64 	TEST_MODE_VIEWPORT_DYNAMIC				= 1,
65 	TEST_MODE_DEPTH_BOUNDS_DYNAMIC			= 2,
66 	TEST_MODE_VIEWPORT_DEPTH_BOUNDS_DYNAMIC	= 3,
67 };
68 
69 struct DepthRangeUnrestrictedParam
70 {
71 	PipelineConstructionType	pipelineConstructionType;
72 	VkFormat					depthFormat;
73 	VkBool32					testClearValueOnly;
74 	VkClearValue				depthBufferClearValue;
75 	VkBool32					depthClampEnable;
76 	float						wc;							// Component W of the vertices
77 	deUint32					viewportDepthBoundsMode;
78 	float						viewportMinDepth;
79 	float						viewportMaxDepth;
80 	VkBool32					depthBoundsTestEnable;
81 	float						minDepthBounds;
82 	float						maxDepthBounds;
83 	VkCompareOp					depthCompareOp;
84 };
85 
86 // helper functions
getFormatCaseName(vk::VkFormat format)87 std::string getFormatCaseName (vk::VkFormat format)
88 {
89 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
90 }
91 
getCompareOpStringName(VkCompareOp compare)92 std::string getCompareOpStringName (VkCompareOp compare)
93 {
94 	return de::toLower(de::toString(getCompareOpStr(compare)).substr(3));
95 }
96 
generateTestName(struct DepthRangeUnrestrictedParam param)97 const std::string generateTestName (struct DepthRangeUnrestrictedParam param)
98 {
99 	std::ostringstream result;
100 
101 	result << getFormatCaseName(param.depthFormat).c_str();
102 	result << "_" << getCompareOpStringName(param.depthCompareOp).c_str();
103 	result << "_clear_value_" << (int) param.depthBufferClearValue.depthStencil.depth;
104 
105 	if (param.depthClampEnable == VK_FALSE)
106 		result << "_wc_" << (int) param.wc;
107 
108 	if (param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC)
109 		result << "_dynamic";
110 	result << "_viewport_min_" << (int)param.viewportMinDepth << "_max_" << (int)param.viewportMaxDepth;
111 
112 	if (param.depthBoundsTestEnable)
113 	{
114 		if (param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
115 			result << "_dynamic";
116 		result << "_boundstest_min" << (int)param.minDepthBounds << "_max_" << (int)param.maxDepthBounds;
117 	}
118 
119 	return result.str();
120 }
121 
isSupportedDepthStencilFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)122 deBool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
123 {
124 	VkFormatProperties formatProps;
125 
126 	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
127 
128 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
129 }
130 
isFloatingPointDepthFormat(VkFormat format)131 deBool isFloatingPointDepthFormat (VkFormat format)
132 {
133 	switch (format)
134 	{
135 	case VK_FORMAT_D32_SFLOAT:
136 	case VK_FORMAT_D32_SFLOAT_S8_UINT:
137 		return DE_TRUE;
138 	case VK_FORMAT_D24_UNORM_S8_UINT:
139 	case VK_FORMAT_D16_UNORM_S8_UINT:
140 	case VK_FORMAT_D16_UNORM:
141 		return DE_FALSE;
142 	default:
143 		DE_FATAL("No depth format");
144 	}
145 	return DE_FALSE;
146 }
147 
depthFormatHasStencilComponent(VkFormat format)148 deBool depthFormatHasStencilComponent (VkFormat format)
149 {
150 	switch (format)
151 	{
152 	case VK_FORMAT_D32_SFLOAT_S8_UINT:
153 	case VK_FORMAT_D24_UNORM_S8_UINT:
154 	case VK_FORMAT_D16_UNORM_S8_UINT:
155 		return DE_TRUE;
156 	case VK_FORMAT_D32_SFLOAT:
157 	case VK_FORMAT_D16_UNORM:
158 		return DE_FALSE;
159 	default:
160 		DE_FATAL("No depth format");
161 	}
162 	return DE_FALSE;
163 }
164 
compareDepthResult(VkCompareOp compare,float depth,float clearValue)165 deBool compareDepthResult (VkCompareOp compare, float depth, float clearValue)
166 {
167 	deBool result = DE_FALSE;
168 
169 	DE_ASSERT(compare <= VK_COMPARE_OP_ALWAYS && compare >= VK_COMPARE_OP_NEVER);
170 
171 	switch (compare)
172 	{
173 	case VK_COMPARE_OP_ALWAYS:
174 		result = DE_TRUE;
175 		break;
176 	case VK_COMPARE_OP_NEVER:
177 		result = DE_FALSE;
178 		break;
179 	case VK_COMPARE_OP_EQUAL:
180 		result = depth == clearValue;
181 		break;
182 	case VK_COMPARE_OP_NOT_EQUAL:
183 		result = depth != clearValue;
184 		break;
185 	case VK_COMPARE_OP_GREATER:
186 		result = depth > clearValue;
187 		break;
188 	case VK_COMPARE_OP_GREATER_OR_EQUAL:
189 		result = depth >= clearValue;
190 		break;
191 	case VK_COMPARE_OP_LESS:
192 		result = depth < clearValue;
193 		break;
194 	case VK_COMPARE_OP_LESS_OR_EQUAL:
195 		result = depth <= clearValue;
196 		break;
197 	default:
198 		result = false;
199 		break;
200 	}
201 	return result;
202 }
203 
createPoints(float wc)204 static inline std::vector<Vertex4RGBA> createPoints (float wc)
205 {
206 	using tcu::Vec2;
207 	using tcu::Vec4;
208 
209 	std::vector<Vertex4RGBA> vertices;
210 
211 	// Vertices are in the following positions of the image:
212 	//
213 	// ----------------------------------
214 	// |                                |
215 	// |                                |
216 	// |      5                  6      |
217 	// |                                |
218 	// |          1         2           |
219 	// |                                |
220 	// |                                |
221 	// |          3         0           |
222 	// |                                |
223 	// |      7                  4      |
224 	// |                                |
225 	// |                                |
226 	// ----------------------------------
227 	//
228 	// Vertex    Depth    Color
229 	//   0        0.0     white
230 	//   1        0.25    magenta
231 	//   2       -2.0     yellow
232 	//   3        2.0     red
233 	//   4       -5.0     black
234 	//   5        5.0     cyan
235 	//   6       10.0     blue
236 	//   7      -10.0     green
237 	// Depth values are constant, they don't depend on wc.
238 	const Vertex4RGBA vertex0 =
239 	{
240 		Vec4(0.25f * wc, 0.25f * wc, 0.0f, wc),
241 		Vec4(1.0f, 1.0f, 1.0f, 1.0)
242 	};
243 	const Vertex4RGBA vertex1 =
244 	{
245 		Vec4(-0.25f * wc, -0.25f * wc, 0.25f, wc),
246 		Vec4(1.0f, 0.0f, 1.0f, 1.0)
247 	};
248 	const Vertex4RGBA vertex2 =
249 	{
250 		Vec4(0.25f * wc, -0.25f * wc, -2.0f, wc),
251 		Vec4(1.0f, 1.0f, 0.0f, 1.0)
252 	};
253 	const Vertex4RGBA vertex3 =
254 	{
255 		Vec4(-0.25f * wc, 0.25f * wc, 2.0f, wc),
256 		Vec4(1.0f, 0.0f, 0.0f, 1.0)
257 	};
258 	const Vertex4RGBA vertex4 =
259 	{
260 		Vec4(0.5f * wc, 0.5f * wc, -5.0f, wc),
261 		Vec4(0.0f, 0.0f, 0.0f, 1.0)
262 	};
263 	const Vertex4RGBA vertex5 =
264 	{
265 		Vec4(-0.5f * wc, -0.5f * wc, 5.0f, wc),
266 		Vec4(0.0f, 1.0f, 1.0f, 1.0)
267 	};
268 	const Vertex4RGBA vertex6 =
269 	{
270 		Vec4(0.5f * wc, -0.5f * wc, 10.0f, wc),
271 		Vec4(0.0f, 0.0f, 1.0f, 1.0)
272 	};
273 
274 	const Vertex4RGBA vertex7 =
275 	{
276 		Vec4(-0.5f * wc, 0.5f * wc, -10.0f, wc),
277 		Vec4(0.0f, 1.0f, 0.0f, 1.0)
278 	};
279 
280 	vertices.push_back(vertex0);
281 	vertices.push_back(vertex1);
282 	vertices.push_back(vertex2);
283 	vertices.push_back(vertex3);
284 	vertices.push_back(vertex4);
285 	vertices.push_back(vertex5);
286 	vertices.push_back(vertex6);
287 	vertices.push_back(vertex7);
288 
289 	return vertices;
290 }
291 
292 template <class Test>
newTestCase(tcu::TestContext & testContext,const DepthRangeUnrestrictedParam testParam)293 vkt::TestCase* newTestCase (tcu::TestContext&					testContext,
294 							const DepthRangeUnrestrictedParam	testParam)
295 {
296 	return new Test(testContext,
297 					generateTestName(testParam).c_str(),
298 					testParam);
299 }
300 
createBufferAndBindMemory(Context & context,VkDeviceSize size,VkBufferUsageFlags usage,de::MovePtr<Allocation> * pAlloc)301 Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
302 {
303 	const DeviceInterface&	vk				 = context.getDeviceInterface();
304 	const VkDevice			vkDevice		 = context.getDevice();
305 	const deUint32			queueFamilyIndex = context.getUniversalQueueFamilyIndex();
306 
307 	const VkBufferCreateInfo vertexBufferParams =
308 	{
309 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
310 		DE_NULL,									// const void*			pNext;
311 		0u,											// VkBufferCreateFlags	flags;
312 		size,										// VkDeviceSize			size;
313 		usage,										// VkBufferUsageFlags	usage;
314 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
315 		1u,											// deUint32				queueFamilyCount;
316 		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
317 	};
318 
319 	Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
320 
321 	*pAlloc = context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
322 	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
323 
324 	return vertexBuffer;
325 }
326 
createImage2DAndBindMemory(Context & context,VkFormat format,deUint32 width,deUint32 height,VkImageUsageFlags usage,VkSampleCountFlagBits sampleCount,de::details::MovePtr<Allocation> * pAlloc)327 Move<VkImage> createImage2DAndBindMemory (Context&							context,
328 										  VkFormat							format,
329 										  deUint32							width,
330 										  deUint32							height,
331 										  VkImageUsageFlags					usage,
332 										  VkSampleCountFlagBits				sampleCount,
333 										  de::details::MovePtr<Allocation>* pAlloc)
334 {
335 	const DeviceInterface&	vk				 = context.getDeviceInterface();
336 	const VkDevice			vkDevice		 = context.getDevice();
337 	const deUint32			queueFamilyIndex = context.getUniversalQueueFamilyIndex();
338 
339 	const VkImageCreateInfo colorImageParams =
340 	{
341 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType		sType;
342 		DE_NULL,																	// const void*			pNext;
343 		0u,																			// VkImageCreateFlags	flags;
344 		VK_IMAGE_TYPE_2D,															// VkImageType			imageType;
345 		format,																		// VkFormat				format;
346 		{ width, height, 1u },														// VkExtent3D			extent;
347 		1u,																			// deUint32				mipLevels;
348 		1u,																			// deUint32				arraySize;
349 		sampleCount,																// deUint32				samples;
350 		VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling		tiling;
351 		usage,																		// VkImageUsageFlags	usage;
352 		VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode		sharingMode;
353 		1u,																			// deUint32				queueFamilyCount;
354 		&queueFamilyIndex,															// const deUint32*		pQueueFamilyIndices;
355 		VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout		initialLayout;
356 	};
357 
358 	Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
359 
360 	*pAlloc = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
361 	VK_CHECK(vk.bindImageMemory(vkDevice, *image, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
362 
363 	return image;
364 }
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const PipelineConstructionType pipelineConstructionType,const VkFormat colorFormat,const VkFormat depthStencilFormat,const VkAttachmentLoadOp loadOperationColor,const VkAttachmentLoadOp loadOperationDepthStencil)365 RenderPassWrapper makeRenderPass (const DeviceInterface&				vk,
366 								   const VkDevice						device,
367 								   const PipelineConstructionType		pipelineConstructionType,
368 								   const VkFormat						colorFormat,
369 								   const VkFormat						depthStencilFormat,
370 								   const VkAttachmentLoadOp				loadOperationColor,
371 								   const VkAttachmentLoadOp				loadOperationDepthStencil)
372 {
373 	const bool								hasColor							= colorFormat != VK_FORMAT_UNDEFINED;
374 	const bool								hasDepthStencil						= depthStencilFormat != VK_FORMAT_UNDEFINED;
375 	const VkImageLayout						initialLayoutColor					= loadOperationColor == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
376 	const VkImageLayout						initialLayoutDepthStencil			= loadOperationDepthStencil == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
377 
378 	const VkAttachmentDescription			colorAttachmentDescription			=
379 	{
380 		(VkAttachmentDescriptionFlags)0,				// VkAttachmentDescriptionFlags    flags
381 		colorFormat,									// VkFormat                        format
382 		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits           samples
383 		loadOperationColor,								// VkAttachmentLoadOp              loadOp
384 		VK_ATTACHMENT_STORE_OP_STORE,					// VkAttachmentStoreOp             storeOp
385 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// VkAttachmentLoadOp              stencilLoadOp
386 		VK_ATTACHMENT_STORE_OP_DONT_CARE,				// VkAttachmentStoreOp             stencilStoreOp
387 		initialLayoutColor,								// VkImageLayout                   initialLayout
388 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		// VkImageLayout                   finalLayout
389 	};
390 
391 	const VkAttachmentDescription			depthStencilAttachmentDescription	=
392 	{
393 		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags    flags
394 		depthStencilFormat,									// VkFormat                        format
395 		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits           samples
396 		loadOperationDepthStencil,							// VkAttachmentLoadOp              loadOp
397 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp             storeOp
398 		loadOperationDepthStencil,							// VkAttachmentLoadOp              stencilLoadOp
399 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp             stencilStoreOp
400 		initialLayoutDepthStencil,							// VkImageLayout                   initialLayout
401 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout                   finalLayout
402 	};
403 
404 	std::vector<VkAttachmentDescription>	attachmentDescriptions;
405 
406 	if (hasColor)
407 		attachmentDescriptions.push_back(colorAttachmentDescription);
408 	if (hasDepthStencil)
409 		attachmentDescriptions.push_back(depthStencilAttachmentDescription);
410 
411 	const VkAttachmentReference				colorAttachmentRef					=
412 	{
413 		0u,											// deUint32         attachment
414 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout    layout
415 	};
416 
417 	const VkAttachmentReference				depthStencilAttachmentRef			=
418 	{
419 		hasColor ? 1u : 0u,									// deUint32         attachment
420 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout    layout
421 	};
422 
423 	const VkSubpassDescription				subpassDescription					=
424 	{
425 		(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags       flags
426 		VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint             pipelineBindPoint
427 		0u,														// deUint32                        inputAttachmentCount
428 		DE_NULL,												// const VkAttachmentReference*    pInputAttachments
429 		hasColor ? 1u : 0u,										// deUint32                        colorAttachmentCount
430 		hasColor ? &colorAttachmentRef : DE_NULL,				// const VkAttachmentReference*    pColorAttachments
431 		DE_NULL,												// const VkAttachmentReference*    pResolveAttachments
432 		hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL,	// const VkAttachmentReference*    pDepthStencilAttachment
433 		0u,														// deUint32                        preserveAttachmentCount
434 		DE_NULL													// const deUint32*                 pPreserveAttachments
435 	};
436 
437 	const VkRenderPassCreateInfo			renderPassInfo						=
438 	{
439 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,									// VkStructureType                   sType
440 		DE_NULL,																	// const void*                       pNext
441 		(VkRenderPassCreateFlags)0,													// VkRenderPassCreateFlags           flags
442 		(deUint32)attachmentDescriptions.size(),									// deUint32                          attachmentCount
443 		attachmentDescriptions.size() > 0 ? &attachmentDescriptions[0] : DE_NULL,	// const VkAttachmentDescription*    pAttachments
444 		1u,																			// deUint32                          subpassCount
445 		&subpassDescription,														// const VkSubpassDescription*       pSubpasses
446 		0u,																			// deUint32                          dependencyCount
447 		DE_NULL																		// const VkSubpassDependency*        pDependencies
448 	};
449 
450 	return RenderPassWrapper(pipelineConstructionType, vk, device, &renderPassInfo);
451 }
452 
453 // Test Classes
454 class DepthRangeUnrestrictedTestInstance : public vkt::TestInstance
455 {
456 public:
457 								DepthRangeUnrestrictedTestInstance		(Context&				context,
458 																		 const DepthRangeUnrestrictedParam	param);
459 	virtual						~DepthRangeUnrestrictedTestInstance		(void);
460 	virtual tcu::TestStatus		iterate									(void);
461 protected:
462 			void				prepareRenderPass						(RenderPassWrapper& renderPass, GraphicsPipelineWrapper& pipeline);
463 			void				prepareCommandBuffer					(void);
464 			void				preparePipelineWrapper					(GraphicsPipelineWrapper& gpw, VkRenderPass renderpass);
465 			tcu::TestStatus		verifyTestResult						(void);
466 protected:
467 	const DepthRangeUnrestrictedParam	m_param;
468 	deBool								m_extensions;
469 	const tcu::UVec2					m_renderSize;
470 	const VkFormat						m_colorFormat;
471 	PipelineLayoutWrapper				m_pipelineLayout;
472 
473 	Move<VkImage>						m_depthImage;
474 	de::MovePtr<Allocation>				m_depthImageAlloc;
475 	de::MovePtr<Allocation>				m_colorImageAlloc;
476 	Move<VkImageView>					m_depthAttachmentView;
477 	VkImageMemoryBarrier				m_imageLayoutBarriers[2];
478 
479 	Move<VkBuffer>						m_vertexBuffer;
480 	de::MovePtr<Allocation>				m_vertexBufferMemory;
481 	std::vector<Vertex4RGBA>			m_vertices;
482 
483 	RenderPassWrapper					m_renderPass;
484 	Move<VkCommandPool>					m_cmdPool;
485 	Move<VkCommandBuffer>				m_cmdBuffer;
486 	Move<VkImage>						m_colorImage;
487 	Move<VkImageView>					m_colorAttachmentView;
488 	GraphicsPipelineWrapper				m_pipeline;
489 
490 	ShaderWrapper						m_vertModule;
491 	ShaderWrapper						m_fragModule;
492 };
493 
preparePipelineWrapper(GraphicsPipelineWrapper & gpw,VkRenderPass renderpass)494 void DepthRangeUnrestrictedTestInstance::preparePipelineWrapper (GraphicsPipelineWrapper& gpw, VkRenderPass renderpass)
495 {
496 	// Create pipeline
497 	const VkVertexInputBindingDescription vertexInputBindingDescription
498 	{
499 		0u,									// deUint32				binding;
500 		sizeof(Vertex4RGBA),				// deUint32				strideInBytes;
501 		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
502 	};
503 
504 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2]
505 	{
506 		{
507 			0u,									// deUint32 location;
508 			0u,									// deUint32 binding;
509 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
510 			0u									// deUint32 offsetInBytes;
511 		},
512 		{
513 			1u,									// deUint32 location;
514 			0u,									// deUint32 binding;
515 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
516 			DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32 offsetInBytes;
517 		}
518 	};
519 
520 	const VkPipelineVertexInputStateCreateInfo vertexInputStateParams
521 	{
522 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
523 		DE_NULL,														// const void*								pNext;
524 		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
525 		1u,																// deUint32									vertexBindingDescriptionCount;
526 		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
527 		2u,																// deUint32									vertexAttributeDescriptionCount;
528 		vertexInputAttributeDescriptions,								// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
529 	};
530 
531 	const std::vector<VkRect2D>		scissor		{ makeRect2D(m_renderSize) };
532 	std::vector<VkViewport>			viewport	{ makeViewport(m_renderSize) };
533 
534 	if (!(m_param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC))
535 	{
536 		viewport[0].minDepth				= m_param.viewportMinDepth;
537 		viewport[0].maxDepth				= m_param.viewportMaxDepth;
538 	}
539 
540 	const VkPipelineRasterizationStateCreateInfo rasterStateParams
541 	{
542 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
543 		DE_NULL,														// const void*								pNext;
544 		0u,																// VkPipelineRasterizationStateCreateFlags	flags;
545 		m_param.depthClampEnable,										// VkBool32									depthClampEnable;
546 		VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
547 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
548 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
549 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
550 		VK_FALSE,														// VkBool32									depthBiasEnable;
551 		0.0f,															// float									depthBiasConstantFactor;
552 		0.0f,															// float									depthBiasClamp;
553 		0.0f,															// float									depthBiasSlopeFactor;
554 		1.0f,															// float									lineWidth;
555 	};
556 
557 	const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
558 	{
559 		VK_FALSE,														// VkBool32									blendEnable;
560 		VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcColorBlendFactor;
561 		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor							dstColorBlendFactor;
562 		VK_BLEND_OP_ADD,												// VkBlendOp								colorBlendOp;
563 		VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcAlphaBlendFactor;
564 		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor							dstAlphaBlendFactor;
565 		VK_BLEND_OP_ADD,												// VkBlendOp								alphaBlendOp;
566 		VK_COLOR_COMPONENT_R_BIT |
567 		VK_COLOR_COMPONENT_G_BIT |
568 		VK_COLOR_COMPONENT_B_BIT |
569 		VK_COLOR_COMPONENT_A_BIT										// VkColorComponentFlags					colorWriteMask;
570 	};
571 
572 	const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
573 	{
574 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
575 		DE_NULL,													// const void*									pNext;
576 		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
577 		VK_FALSE,													// VkBool32										logicOpEnable;
578 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
579 		1u,															// deUint32										attachmentCount;
580 		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
581 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
582 	};
583 
584 	float minDepthBounds = m_param.minDepthBounds;
585 	float maxDepthBounds = m_param.maxDepthBounds;
586 
587 	if (m_param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
588 	{
589 		minDepthBounds = 0.0f;
590 		maxDepthBounds = 1.0f;
591 	}
592 
593 	VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
594 	{
595 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType								sType;
596 		DE_NULL,													// const void*									pNext;
597 		0u,															// VkPipelineDepthStencilStateCreateFlags		flags;
598 		VK_TRUE,													// VkBool32										depthTestEnable;
599 		VK_TRUE,													// VkBool32										depthWriteEnable;
600 		m_param.depthCompareOp,										// VkCompareOp									depthCompareOp;
601 		m_param.depthBoundsTestEnable,								// VkBool32										depthBoundsTestEnable;
602 		VK_FALSE,													// VkBool32										stencilTestEnable;
603 		// VkStencilOpState front;
604 		{
605 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
606 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
607 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
608 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
609 			0u,						// deUint32		compareMask;
610 			0u,						// deUint32		writeMask;
611 			0u,						// deUint32		reference;
612 		},
613 		// VkStencilOpState back;
614 		{
615 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
616 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
617 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
618 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
619 			0u,						// deUint32		compareMask;
620 			0u,						// deUint32		writeMask;
621 			0u,						// deUint32		reference;
622 		},
623 		minDepthBounds,												// float										minDepthBounds;
624 		maxDepthBounds,												// float										maxDepthBounds;
625 	};
626 
627 	std::vector<VkDynamicState> dynamicStates;
628 	if (m_param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC)
629 		dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
630 	if (m_param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
631 		dynamicStates.push_back(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
632 
633 	const VkPipelineDynamicStateCreateInfo			dynamicStateParams			=
634 	{
635 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,		// VkStructureType								sType;
636 		DE_NULL,													// const void*									pNext;
637 		(VkPipelineDynamicStateCreateFlags)0u,						// VkPipelineDynamicStateCreateFlags			flags;
638 		(deUint32)dynamicStates.size(),								// deUint32										dynamicStateCount;
639 		(const VkDynamicState*)dynamicStates.data()					// const VkDynamicState*						pDynamicStates;
640 	};
641 
642 	gpw.setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
643 	   .setDefaultMultisampleState()
644 	   .setDynamicState(&dynamicStateParams)
645 	   .setupVertexInputState(&vertexInputStateParams)
646 	   .setupPreRasterizationShaderState(viewport,
647 			scissor,
648 			m_pipelineLayout,
649 		   renderpass,
650 			0u,
651 			m_vertModule,
652 			&rasterStateParams)
653 	   .setupFragmentShaderState(m_pipelineLayout, renderpass, 0u, m_fragModule, &depthStencilStateParams)
654 	   .setupFragmentOutputState(renderpass, 0u, &colorBlendStateParams)
655 	   .setMonolithicPipelineLayout(m_pipelineLayout)
656 	   .buildPipeline();
657 }
658 
prepareRenderPass(RenderPassWrapper & renderPass,GraphicsPipelineWrapper & pipeline)659 void DepthRangeUnrestrictedTestInstance::prepareRenderPass (RenderPassWrapper& renderPass, GraphicsPipelineWrapper& pipeline)
660 {
661 	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
662 
663 	const VkClearValue attachmentClearValues[2] =
664 	{
665 		defaultClearValue(m_colorFormat),
666 		m_param.depthBufferClearValue,
667 	};
668 
669 	renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
670 
671 	pipeline.bind(*m_cmdBuffer);
672 	VkDeviceSize offsets = 0u;
673 	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
674 
675 	if (m_param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC)
676 	{
677 		VkViewport	viewport	= makeViewport(m_renderSize);
678 		viewport.minDepth		= m_param.viewportMinDepth;
679 		viewport.maxDepth		= m_param.viewportMaxDepth;
680 		if (vk::isConstructionTypeShaderObject(m_param.pipelineConstructionType))
681 		{
682 #ifndef CTS_USES_VULKANSC
683 			vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, &viewport);
684 #else
685 			vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, &viewport);
686 #endif
687 		}
688 		else
689 		{
690 			vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, &viewport);
691 		}
692 	}
693 
694 	if (m_param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
695 		vk.cmdSetDepthBounds(*m_cmdBuffer, m_param.minDepthBounds, m_param.maxDepthBounds);
696 
697 	if (!m_vertices.empty() && !m_param.testClearValueOnly)
698 		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
699 
700 	renderPass.end(vk, *m_cmdBuffer);
701 }
702 
prepareCommandBuffer(void)703 void DepthRangeUnrestrictedTestInstance::prepareCommandBuffer (void)
704 {
705 	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
706 
707 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
708 
709 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
710 		0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
711 
712 	prepareRenderPass(m_renderPass, m_pipeline);
713 
714 	endCommandBuffer(vk, *m_cmdBuffer);
715 }
716 
DepthRangeUnrestrictedTestInstance(Context & context,const DepthRangeUnrestrictedParam param)717 DepthRangeUnrestrictedTestInstance::DepthRangeUnrestrictedTestInstance	(Context&							context,
718 																		 const DepthRangeUnrestrictedParam	param)
719 	: TestInstance			(context)
720 	, m_param				(param)
721 	, m_extensions			(m_context.requireDeviceFunctionality("VK_EXT_depth_range_unrestricted"))
722 	, m_renderSize			(tcu::UVec2(32,32))
723 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
724 	, m_pipeline			(m_context.getInstanceInterface(), m_context.getDeviceInterface(), m_context.getPhysicalDevice(), m_context.getDevice(), m_context.getDeviceExtensions(), param.pipelineConstructionType)
725 {
726 	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
727 	const VkDevice			vkDevice		 = m_context.getDevice();
728 	const deUint32			queueFamilyIndex = context.getUniversalQueueFamilyIndex();
729 
730 	if (!isSupportedDepthStencilFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), param.depthFormat))
731 	{
732 		throw tcu::NotSupportedError("Unsupported depth format");
733 	}
734 
735 	VkPhysicalDeviceFeatures  features = m_context.getDeviceFeatures();
736 	if (param.depthClampEnable && features.depthClamp == DE_FALSE)
737 	{
738 		throw tcu::NotSupportedError("Unsupported feature: depthClamp");
739 	}
740 
741 	if (param.depthBoundsTestEnable && features.depthBounds == DE_FALSE)
742 	{
743 		throw tcu::NotSupportedError("Unsupported feature: depthBounds");
744 	}
745 
746 	// Create vertex buffer
747 	{
748 		m_vertexBuffer	= createBufferAndBindMemory(m_context, 1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
749 		m_vertices		= createPoints(m_param.wc);
750 		// Load vertices into vertex buffer
751 		deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
752 		flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
753 	}
754 
755 	// Create render pass
756 	m_renderPass = makeRenderPass(vk, vkDevice, m_param.pipelineConstructionType, m_colorFormat, m_param.depthFormat, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
757 
758 	const VkComponentMapping	ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
759 	// Create color image
760 	{
761 		m_colorImage = createImage2DAndBindMemory(m_context,
762 												  m_colorFormat,
763 												  m_renderSize.x(),
764 												  m_renderSize.y(),
765 												  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
766 												  VK_SAMPLE_COUNT_1_BIT,
767 												  &m_colorImageAlloc);
768 	}
769 
770 	// Create depth image
771 	{
772 		m_depthImage = createImage2DAndBindMemory(m_context,
773 												  m_param.depthFormat,
774 												  m_renderSize.x(),
775 												  m_renderSize.y(),
776 												  VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
777 												  VK_SAMPLE_COUNT_1_BIT,
778 												  &m_depthImageAlloc);
779 	}
780 
781 	deUint32 depthAspectBits = VK_IMAGE_ASPECT_DEPTH_BIT;
782 	if (depthFormatHasStencilComponent(param.depthFormat))
783 		depthAspectBits |= VK_IMAGE_ASPECT_STENCIL_BIT;
784 
785 	// Set up image layout transition barriers
786 	{
787 		VkImageMemoryBarrier colorImageBarrier =
788 		{
789 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
790 			DE_NULL,											// const void*				pNext;
791 			0u,													// VkAccessFlags			srcAccessMask;
792 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
793 			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
794 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout			newLayout;
795 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
796 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
797 			*m_colorImage,										// VkImage					image;
798 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },		// VkImageSubresourceRange	subresourceRange;
799 		};
800 
801 		m_imageLayoutBarriers[0] = colorImageBarrier;
802 
803 		VkImageMemoryBarrier depthImageBarrier =
804 		{
805 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
806 			DE_NULL,											// const void*				pNext;
807 			0u,													// VkAccessFlags			srcAccessMask;
808 			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
809 			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
810 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
811 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
812 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
813 			*m_depthImage,										// VkImage					image;
814 			{ depthAspectBits, 0u, 1u, 0u, 1u },				// VkImageSubresourceRange	subresourceRange;
815 		};
816 
817 		m_imageLayoutBarriers[1] = depthImageBarrier;
818 	}
819 	// Create color attachment view
820 	{
821 		VkImageViewCreateInfo colorAttachmentViewParams =
822 		{
823 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
824 			DE_NULL,										// const void*				pNext;
825 			0u,												// VkImageViewCreateFlags	flags;
826 			*m_colorImage,									// VkImage					image;
827 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
828 			m_colorFormat,									// VkFormat					format;
829 			ComponentMappingRGBA,							// VkComponentMapping		components;
830 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
831 		};
832 
833 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
834 	}
835 
836 	// Create depth attachment view
837 	{
838 		const VkImageViewCreateInfo depthAttachmentViewParams =
839 		{
840 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
841 			DE_NULL,										// const void*				pNext;
842 			0u,												// VkImageViewCreateFlags	flags;
843 			*m_depthImage,									// VkImage					image;
844 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
845 			m_param.depthFormat,							// VkFormat					format;
846 			ComponentMappingRGBA,							// VkComponentMapping		components;
847 			{ depthAspectBits, 0u, 1u, 0u, 1u },			// VkImageSubresourceRange	subresourceRange;
848 		};
849 
850 		m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
851 	}
852 
853 	// Create framebuffer
854 	{
855 		std::vector<VkImage> images = {
856 			*m_colorImage,
857 			*m_depthImage,
858 		};
859 		VkImageView attachmentBindInfos[2] =
860 		{
861 			*m_colorAttachmentView,
862 			*m_depthAttachmentView,
863 		};
864 
865 		const VkFramebufferCreateInfo framebufferParams =
866 		{
867 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
868 			DE_NULL,											// const void*					pNext;
869 			0u,													// VkFramebufferCreateFlags		flags;
870 			*m_renderPass,										// VkRenderPass					renderPass;
871 			2u,													// deUint32						attachmentCount;
872 			attachmentBindInfos,								// const VkImageView*			pAttachments;
873 			(deUint32)m_renderSize.x(),							// deUint32						width;
874 			(deUint32)m_renderSize.y(),							// deUint32						height;
875 			1u,													// deUint32						layers;
876 		};
877 
878 		m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images);
879 	}
880 
881 	// Create shader modules
882 	m_vertModule = ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("vert"), 0);
883 	m_fragModule = ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("frag"), 0);
884 
885 	// Create pipeline layout
886 	{
887 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
888 		{
889 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
890 			DE_NULL,											// const void*						pNext;
891 			0u,													// VkPipelineLayoutCreateFlags		flags;
892 			0u,													// deUint32							setLayoutCount;
893 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
894 			0u,													// deUint32							pushConstantRangeCount;
895 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
896 		};
897 
898 		m_pipelineLayout = PipelineLayoutWrapper(m_param.pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
899 	}
900 
901 	// Create pipeline
902 	preparePipelineWrapper(m_pipeline, *m_renderPass);
903 
904 	// Create command pool
905 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
906 
907 	// Create command buffer
908 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
909 }
910 
~DepthRangeUnrestrictedTestInstance(void)911 DepthRangeUnrestrictedTestInstance::~DepthRangeUnrestrictedTestInstance (void)
912 {
913 }
914 
iterate(void)915 tcu::TestStatus DepthRangeUnrestrictedTestInstance::iterate (void)
916 {
917 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
918 	const VkDevice			vkDevice			= m_context.getDevice();
919 	const VkQueue			queue				= m_context.getUniversalQueue();
920 
921 	prepareCommandBuffer();
922 
923 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
924 	return verifyTestResult();
925 }
926 
verifyTestResult(void)927 tcu::TestStatus DepthRangeUnrestrictedTestInstance::verifyTestResult (void)
928 {
929 	deBool					compareOk			= DE_TRUE;
930 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
931 	const VkDevice			vkDevice			= m_context.getDevice();
932 	const VkQueue			queue				= m_context.getUniversalQueue();
933 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
934 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
935 	Allocator&				allocator			= m_context.getDefaultAllocator();
936 	tcu::TextureLevel		refImage			(vk::mapVkFormat(m_colorFormat), 32, 32);
937 	float					clearValue			= m_param.depthBufferClearValue.depthStencil.depth;
938 	double					epsilon				= 1e-5;
939 
940 	// For non-float depth formats, the value in the depth buffer is already clampled to the range [0, 1], which
941 	// includes the clear depth value.
942 	if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
943 		clearValue = de::min(de::max(clearValue, 0.0f), 1.0f);
944 
945 	// Generate reference image
946 	{
947 		VkClearValue			clearColor		= defaultClearValue(m_colorFormat);
948 		tcu::Vec4				clearColorVec4  (clearColor.color.float32[0], clearColor.color.float32[1],
949 												 clearColor.color.float32[2], clearColor.color.float32[3]);
950 
951 		tcu::clear(refImage.getAccess(), clearColorVec4);
952 		for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
953 		{
954 			if (m_param.depthClampEnable == VK_FALSE && (vertex->position.z() < 0.0f || vertex->position.z() > vertex->position.w()))
955 				continue;
956 
957 			if (m_param.testClearValueOnly)
958 				continue;
959 
960 			// Depth Clamp is enabled, then we clamp point depth to viewport's maxDepth and minDepth values, or [0.0f, 1.0f] is depth format is fixed-point.
961 			float scaling = ((vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth)) + m_param.viewportMinDepth;
962 			float depth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
963 
964 			// For non-float depth formats, depth value is clampled to the range [0, 1].
965 			if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
966 				depth = de::min(de::max(depth, 0.0f), 1.0f);
967 
968 			if (compareDepthResult(m_param.depthCompareOp, depth, clearValue))
969 			{
970 				deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
971 				deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
972 				refImage.getAccess().setPixel(vertex->color, x, y);
973 			}
974 		}
975 	}
976 
977 	// Check the rendered image
978 	{
979 		de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
980 
981 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
982 															  "IntImageCompare",
983 															  "Image comparison",
984 															  refImage.getAccess(),
985 															  result->getAccess(),
986 															  tcu::UVec4(2, 2, 2, 2),
987 															  tcu::IVec3(1, 1, 0),
988 															  true,
989 															  tcu::COMPARE_LOG_RESULT);
990 #ifdef CTS_USES_VULKANSC
991 		if (m_context.getTestContext().getCommandLine().isSubProcess())
992 #endif // CTS_USES_VULKANSC
993 		{
994 			if (!compareOk)
995 				return tcu::TestStatus::fail("Image mismatch");
996 		}
997 	}
998 
999 	// Check depth buffer contents
1000 	{
1001 		de::MovePtr<tcu::TextureLevel>	depthResult		= readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_param.depthFormat, m_renderSize);
1002 
1003 		if (m_param.testClearValueOnly) {
1004 			compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1005 												   "DepthImagecompare",
1006 												   "Depth image comparison",
1007 												   tcu::Vec4(clearValue, 0.0f, 0.0f, 1.0f),
1008 												   depthResult->getAccess(),
1009 												   tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
1010 												   tcu::COMPARE_LOG_RESULT);
1011 			if (!compareOk)
1012 				return tcu::TestStatus::fail("Depth buffer mismatch");
1013 			else
1014 				return tcu::TestStatus::pass("Result images matches references");
1015 		}
1016 
1017 		log << tcu::TestLog::Message;
1018 		for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
1019 		{
1020 			deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
1021 			deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
1022 			tcu::Vec4 depth	= depthResult->getAccess().getPixel(x, y);
1023 
1024 			// Check depth values are valid
1025 			if (depth.y() != 0.0f || depth.z() != 0.0f || depth.w() != 1.0f)
1026 			{
1027 				log << tcu::TestLog::Message << "Invalid depth buffer values for pixel (" << x << ", " << y << ") = ("
1028 					<< depth.x() << ", " << depth.y() << ", " << depth.z() << ", " << depth.w() << "." << tcu::TestLog::EndMessage;
1029 				compareOk = DE_FALSE;
1030 			}
1031 
1032 			// Check the case where depth clamping is disabled.
1033 			if (m_param.depthClampEnable == VK_FALSE)
1034 			{
1035 				if ((vertex->position.z() < 0.0f || vertex->position.z() > vertex->position.w()) &&
1036 					fabs(clearValue - depth.x()) > epsilon)
1037 				{
1038 					log << tcu::TestLog::Message << "Error pixel (" << x << ", " << y << "). Depth value = " << depth
1039 						<< ", expected " << clearValue << "." << tcu::TestLog::EndMessage;
1040 					compareOk = DE_FALSE;
1041 				}
1042 
1043 				float expectedDepth = clearValue;
1044 
1045 				if (vertex->position.z() <= vertex->position.w() && vertex->position.z() >= 0.0f)
1046 				{
1047 					// Assert we have a symmetric range around zero.
1048 					DE_ASSERT(m_param.viewportMinDepth == (-m_param.viewportMaxDepth));
1049 
1050 					// Calculate the expected depth value: first translate the value to from [0.0f, 1.0f] to [-1.0f, 1.0f].
1051 					expectedDepth = 2 * (vertex->position.z() / vertex->position.w()) - 1.0f;
1052 					// Now multiply by m_param.viewportMaxDepth to get the expected value.
1053 					expectedDepth *= m_param.viewportMaxDepth;
1054 				}
1055 
1056 				// For non-float depth formats, depth value is clampled to the range [0, 1].
1057 				if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1058 					expectedDepth = de::min(de::max(expectedDepth, 0.0f), 1.0f);
1059 
1060 				expectedDepth = compareDepthResult(m_param.depthCompareOp, expectedDepth, clearValue) ? expectedDepth : clearValue;
1061 
1062 				if (fabs(expectedDepth - depth.x()) > epsilon)
1063 				{
1064 					log << tcu::TestLog::Message << "Error pixel (" << x << ", " << y
1065 						<< "). Depth value " << depth.x() << ", expected " << expectedDepth << ", error " << fabs(expectedDepth - depth.x()) << tcu::TestLog::EndMessage;
1066 					compareOk = DE_FALSE;
1067 				}
1068 
1069 				continue;
1070 			}
1071 
1072 			// Depth Clamp is enabled, then we clamp point depth to viewport's maxDepth and minDepth values, or 0.0f and 1.0f is format is not float.
1073 			float scaling = (vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth) + m_param.viewportMinDepth;
1074 			float expectedDepth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
1075 
1076 			// For non-float depth formats, depth value is clampled to the range [0, 1].
1077 			if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1078 				expectedDepth = de::min(de::max(expectedDepth, 0.0f), 1.0f);
1079 
1080 			expectedDepth = compareDepthResult(m_param.depthCompareOp, expectedDepth, clearValue) ? expectedDepth : clearValue;
1081 
1082 			if (fabs(expectedDepth - depth.x()) > epsilon)
1083 			{
1084 				log << tcu::TestLog::Message << "Error pixel (" << x << ", " << y
1085 					<< "). Depth value " << depth.x() << ", expected " << expectedDepth << ", error " << fabs(expectedDepth - depth.x()) << tcu::TestLog::EndMessage;
1086 				compareOk = DE_FALSE;
1087 			}
1088 		}
1089 		if (!compareOk)
1090 			return tcu::TestStatus::fail("Depth buffer mismatch");
1091 	}
1092 
1093 	return tcu::TestStatus::pass("Result images matches references");
1094 }
1095 
1096 // Test Classes
1097 class DepthBoundsRangeUnrestrictedTestInstance : public DepthRangeUnrestrictedTestInstance
1098 {
1099 public:
1100 								DepthBoundsRangeUnrestrictedTestInstance		(Context&				context,
1101 																				 const DepthRangeUnrestrictedParam	param);
1102 	virtual						~DepthBoundsRangeUnrestrictedTestInstance		(void);
1103 	virtual tcu::TestStatus		iterate											(void);
1104 
1105 protected:
1106 			tcu::TestStatus		verifyTestResult								(bool firstDraw);
1107 			void				prepareCommandBuffer							(bool firstDraw);
1108 
1109 protected:
1110 			RenderPassWrapper					m_renderPassSecondDraw;
1111 			GraphicsPipelineWrapper				m_pipelineSecondDraw;
1112 			std::vector<bool>					m_vertexWasRendered;
1113 
1114 };
1115 
DepthBoundsRangeUnrestrictedTestInstance(Context & context,const DepthRangeUnrestrictedParam param)1116 DepthBoundsRangeUnrestrictedTestInstance::DepthBoundsRangeUnrestrictedTestInstance	(Context&							context,
1117 																					 const DepthRangeUnrestrictedParam	param)
1118 	: DepthRangeUnrestrictedTestInstance(context, param)
1119 	, m_pipelineSecondDraw				(m_context.getInstanceInterface(), m_context.getDeviceInterface(), m_context.getPhysicalDevice(), m_context.getDevice(), m_context.getDeviceExtensions(), param.pipelineConstructionType)
1120 {
1121 	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
1122 	const VkDevice			vkDevice		 = m_context.getDevice();
1123 
1124 	// Create render pass for second draw, we keep the first draw's contents of the depth buffer.
1125 	m_renderPassSecondDraw = makeRenderPass(vk, vkDevice, param.pipelineConstructionType, m_colorFormat, m_param.depthFormat, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_LOAD);
1126 
1127 	// Create framebuffer for second draw.
1128 	{
1129 		std::vector<VkImage> images = {
1130 			*m_colorImage,
1131 			*m_depthImage,
1132 		};
1133 		VkImageView attachmentBindInfos[2] =
1134 		{
1135 			*m_colorAttachmentView,
1136 			*m_depthAttachmentView,
1137 		};
1138 
1139 		const VkFramebufferCreateInfo framebufferParams =
1140 		{
1141 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
1142 			DE_NULL,											// const void*					pNext;
1143 			0u,													// VkFramebufferCreateFlags		flags;
1144 			*m_renderPassSecondDraw,							// VkRenderPass					renderPass;
1145 			2u,													// deUint32						attachmentCount;
1146 			attachmentBindInfos,								// const VkImageView*			pAttachments;
1147 			(deUint32)m_renderSize.x(),							// deUint32						width;
1148 			(deUint32)m_renderSize.y(),							// deUint32						height;
1149 			1u,													// deUint32						layers;
1150 		};
1151 
1152 		m_renderPassSecondDraw.createFramebuffer(vk, vkDevice, &framebufferParams, images);
1153 	}
1154 
1155 	// Create pipeline
1156 	preparePipelineWrapper(m_pipelineSecondDraw, *m_renderPassSecondDraw);
1157 }
1158 
~DepthBoundsRangeUnrestrictedTestInstance(void)1159 DepthBoundsRangeUnrestrictedTestInstance::~DepthBoundsRangeUnrestrictedTestInstance (void)
1160 {
1161 }
1162 
iterate(void)1163 tcu::TestStatus DepthBoundsRangeUnrestrictedTestInstance::iterate (void)
1164 {
1165 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
1166 	const VkDevice			vkDevice			= m_context.getDevice();
1167 	const VkQueue			queue				= m_context.getUniversalQueue();
1168 
1169 	// This test will draw the same scene two times.
1170 	// First one will render the points depending on if the pass the depth test and if clear depth value passes the
1171 	// depthBounds test.
1172 	//
1173 	// The second one, will render the same scene but the the point positions will have depth buffer values from
1174 	// the first draw. If they pass the depth test, the depthBounds test will check the content of the depth buffer,
1175 	// which is most cases, will make that the second result differs from the first one, hence the need to split
1176 	// the verification in two steps.
1177 	prepareCommandBuffer(true);
1178 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1179 	tcu::TestStatus status = verifyTestResult(true);
1180 
1181 #ifdef CTS_USES_VULKANSC
1182 	if (m_context.getTestContext().getCommandLine().isSubProcess())
1183 #endif // CTS_USES_VULKANSC
1184 	{
1185 		if (status.getCode() != QP_TEST_RESULT_PASS)
1186 			return status;
1187 	}
1188 
1189 	prepareCommandBuffer(false);
1190 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1191 	return verifyTestResult(false);
1192 }
1193 
prepareCommandBuffer(bool firstDraw)1194 void DepthBoundsRangeUnrestrictedTestInstance::prepareCommandBuffer (bool firstDraw)
1195 {
1196 	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
1197 
1198 	if (!firstDraw)
1199 	{
1200 		VK_CHECK(vk.resetCommandBuffer(*m_cmdBuffer, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT));
1201 		// Color image layout changed after verifying the first draw call, restore it.
1202 		m_imageLayoutBarriers[0].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1203 		m_imageLayoutBarriers[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1204 		// Depth image layout changed after verifying the first draw call, restore it.
1205 		m_imageLayoutBarriers[1].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1206 		m_imageLayoutBarriers[1].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1207 	}
1208 
1209 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1210 
1211 	vk.cmdPipelineBarrier(*m_cmdBuffer, (firstDraw ? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT : VK_PIPELINE_STAGE_TRANSFER_BIT), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1212 		0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
1213 
1214 	prepareRenderPass((firstDraw ? m_renderPass : m_renderPassSecondDraw),
1215 					  (firstDraw ? m_pipeline : m_pipelineSecondDraw));
1216 
1217 	endCommandBuffer(vk, *m_cmdBuffer);
1218 }
1219 
verifyTestResult(bool firstDraw)1220 tcu::TestStatus DepthBoundsRangeUnrestrictedTestInstance::verifyTestResult (bool firstDraw)
1221 {
1222 	deBool					compareOk			= DE_TRUE;
1223 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
1224 	const VkDevice			vkDevice			= m_context.getDevice();
1225 	const VkQueue			queue				= m_context.getUniversalQueue();
1226 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
1227 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
1228 	Allocator&				allocator			= m_context.getDefaultAllocator();
1229 	tcu::TextureLevel		refImage			(vk::mapVkFormat(m_colorFormat), 32, 32);
1230 	float					clearValue			= m_param.depthBufferClearValue.depthStencil.depth;
1231 	double					epsilon				= 1e-5;
1232 
1233 	// For non-float depth formats, depth value is clampled to the range [0, 1].
1234 	if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1235 		clearValue = de::min(de::max(clearValue, 0.0f), 1.0f);
1236 
1237 	// Generate reference image
1238 	{
1239 		VkClearValue			clearColor		= defaultClearValue(m_colorFormat);
1240 		tcu::Vec4				clearColorVec4  (clearColor.color.float32[0], clearColor.color.float32[1],
1241 												 clearColor.color.float32[2], clearColor.color.float32[3]);
1242 		tcu::clear(refImage.getAccess(), clearColorVec4);
1243 		for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
1244 		{
1245 			// Depth Clamp is enabled, then we clamp point depth to viewport's maxDepth and minDepth values and later check if it is inside depthBounds volume.
1246 			float scaling = ((vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth)) + m_param.viewportMinDepth;
1247 			float depth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
1248 			if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1249 				depth = de::min(de::max(depth, 0.0f), 1.0f);
1250 
1251 			auto i = vertex - m_vertices.begin();
1252 
1253 			// Depending if the first draw call succeed, we need to know if the second draw call will render the points because the depth buffer content
1254 			// will determine if it passes the depth test and the depth bounds test.
1255 			bool firstDrawHasPassedDepthBoundsTest = !firstDraw && m_vertexWasRendered[i];
1256 			float depthBufferValue = firstDrawHasPassedDepthBoundsTest ? depth : clearValue;
1257 
1258 			// For non-float depth formats, depth value is clampled to the range [0, 1].
1259 			if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1260 				depthBufferValue = de::min(de::max(depthBufferValue, 0.0f), 1.0f);
1261 
1262 			// Check that the point passes the depth test and the depth bounds test.
1263 			if (compareDepthResult(m_param.depthCompareOp, depth, depthBufferValue) &&
1264 				depthBufferValue >= m_param.minDepthBounds && depthBufferValue <= m_param.maxDepthBounds)
1265 			{
1266 				deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
1267 				deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
1268 				refImage.getAccess().setPixel(vertex->color, x, y);
1269 				if (firstDraw)
1270 					m_vertexWasRendered.push_back(true);
1271 				continue;
1272 			}
1273 
1274 			if (firstDraw)
1275 				m_vertexWasRendered.push_back(false);
1276 		}
1277 	}
1278 
1279 	// Check the rendered image
1280 	{
1281 		de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
1282 		std::string description = "Image comparison draw ";
1283 		description += (firstDraw ? "1" : "2");
1284 
1285 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1286 															  "IntImageCompare",
1287 															  description.c_str(),
1288 															  refImage.getAccess(),
1289 															  result->getAccess(),
1290 															  tcu::UVec4(2, 2, 2, 2),
1291 															  tcu::IVec3(1, 1, 0),
1292 															  true,
1293 															  tcu::COMPARE_LOG_RESULT);
1294 #ifdef CTS_USES_VULKANSC
1295 		if (m_context.getTestContext().getCommandLine().isSubProcess())
1296 #endif // CTS_USES_VULKANSC
1297 		{
1298 			if (!compareOk)
1299 				return tcu::TestStatus::fail("Image mismatch");
1300 		}
1301 	}
1302 
1303 	// Check depth buffer contents
1304 	{
1305 		de::MovePtr<tcu::TextureLevel>	depthResult		= readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_param.depthFormat, m_renderSize);
1306 
1307 		log << tcu::TestLog::Message;
1308 		for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
1309 		{
1310 			deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
1311 			deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
1312 			tcu::Vec4 depth	= depthResult->getAccess().getPixel(x, y);
1313 
1314 			// Check depth values are valid
1315 			if (depth.y() != 0.0f || depth.z() != 0.0f || depth.w() != 1.0f)
1316 			{
1317 				log << tcu::TestLog::Message << "Draw " << (firstDraw ? "1" : "2") << ": Invalid depth buffer values for pixel (" << x << ", " << y << ") = ("
1318 					<< depth.x() << ", " << depth.y() << ", " << depth.z() << ", " << depth.w() << "." << tcu::TestLog::EndMessage;
1319 				compareOk = DE_FALSE;
1320 			}
1321 
1322 			// Depth Clamp is enabled, so we clamp point depth to viewport's maxDepth and minDepth values, or 0.0f and 1.0f is format is not float.
1323 			float scaling = (vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth) + m_param.viewportMinDepth;
1324 			float expectedDepth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
1325 
1326 			auto i = vertex - m_vertices.begin();
1327 
1328 			// Depending if the first draw call succeed, we need to know if the second draw call will render the points because the depth buffer content
1329 			// will determine if it passes the depth test and the depth bounds test.
1330 			bool firstDrawHasPassedDepthBoundsTest = !firstDraw && m_vertexWasRendered[i];
1331 
1332 			// If we are in the first draw call, the depth buffer content is clearValue. If we are in the second draw call, it is going to be depth.x() if the first
1333 			// succeeded.
1334 			float depthBufferValue = firstDrawHasPassedDepthBoundsTest ? depth.x() : clearValue;
1335 
1336 			// For non-float depth formats, depth value is clampled to the range [0, 1].
1337 			if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1338 				depthBufferValue = de::min(de::max(depthBufferValue, 0.0f), 1.0f);
1339 
1340 			// Calculate the expectd depth depending on the depth test and the depth bounds test results.
1341 			expectedDepth =
1342 				(compareDepthResult(m_param.depthCompareOp, expectedDepth, depthBufferValue) && depthBufferValue <= m_param.maxDepthBounds && depthBufferValue >= m_param.minDepthBounds)
1343 				? expectedDepth : depthBufferValue;
1344 
1345 			// For non-float depth formats, depth value is clampled to the range [0, 1].
1346 			if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1347 				expectedDepth = de::min(de::max(expectedDepth, 0.0f), 1.0f);
1348 
1349 			if (fabs(expectedDepth - depth.x()) > epsilon)
1350 			{
1351 				log << tcu::TestLog::Message << "Draw " << (firstDraw ? "1" : "2") << ": Error pixel (" << x << ", " << y
1352 					<< "). Depth value " << depth.x() << ", expected " << expectedDepth << ", error " << fabs(expectedDepth - depth.x()) << tcu::TestLog::EndMessage;
1353 				compareOk = DE_FALSE;
1354 			}
1355 		}
1356 
1357 		if (!compareOk)
1358 			return tcu::TestStatus::fail("Depth buffer mismatch");
1359 	}
1360 
1361 	return tcu::TestStatus::pass("Result images matches references");
1362 }
1363 
1364 class DepthRangeUnrestrictedTest : public vkt::TestCase
1365 {
1366 public:
DepthRangeUnrestrictedTest(tcu::TestContext & testContext,const std::string & name,const DepthRangeUnrestrictedParam param)1367 							DepthRangeUnrestrictedTest			(tcu::TestContext&					testContext,
1368 																 const std::string&					name,
1369 																 const DepthRangeUnrestrictedParam	param)
1370 								: vkt::TestCase (testContext, name)
1371 								, m_param		(param)
1372 								{ }
~DepthRangeUnrestrictedTest(void)1373 	virtual					~DepthRangeUnrestrictedTest	(void) { }
1374 	virtual void			initPrograms		(SourceCollections&	programCollection) const;
1375 	virtual TestInstance*	createInstance		(Context&				context) const;
1376 	void					checkSupport		(Context& context) const;
1377 
1378 protected:
1379 		const DepthRangeUnrestrictedParam       m_param;
1380 };
1381 
initPrograms(SourceCollections & programCollection) const1382 void DepthRangeUnrestrictedTest::initPrograms (SourceCollections& programCollection) const
1383 {
1384 	programCollection.glslSources.add("vert") << glu::VertexSource(
1385 				"#version 310 es\n"
1386 				"layout(location = 0) in vec4 position;\n"
1387 				"layout(location = 1) in vec4 color;\n"
1388 				"layout(location = 0) out highp vec4 vtxColor;\n"
1389 				"void main (void)\n"
1390 				"{\n"
1391 				"  gl_Position = position;\n"
1392 				"  gl_PointSize = 1.0f;\n"
1393 				"  vtxColor = color;\n"
1394 
1395 				"}\n");
1396 
1397 
1398 	programCollection.glslSources.add("frag") << glu::FragmentSource(
1399 				"#version 310 es\n"
1400 				"layout(location = 0) in highp vec4 vtxColor;\n"
1401 				"layout(location = 0) out highp vec4 fragColor;\n"
1402 				"void main (void)\n"
1403 				"{\n"
1404 				"  fragColor = vtxColor;\n"
1405 				"}\n");
1406 
1407 }
1408 
createInstance(Context & context) const1409 TestInstance* DepthRangeUnrestrictedTest::createInstance (Context& context) const
1410 {
1411 	if (m_param.depthBoundsTestEnable)
1412 		return new DepthBoundsRangeUnrestrictedTestInstance(context, m_param);
1413 	return new DepthRangeUnrestrictedTestInstance(context, m_param);
1414 }
1415 
checkSupport(Context & context) const1416 void DepthRangeUnrestrictedTest::checkSupport(Context& context) const
1417 {
1418 	checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_param.pipelineConstructionType);
1419 }
1420 } // anonymous
1421 
createDepthRangeUnrestrictedTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)1422 tcu::TestCaseGroup* createDepthRangeUnrestrictedTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
1423 {
1424 	de::MovePtr<tcu::TestCaseGroup> depthTests (new tcu::TestCaseGroup(testCtx, "depth_range_unrestricted"));
1425 	const VkFormat depthFormats[]	=
1426 	{
1427 		VK_FORMAT_D32_SFLOAT,
1428 		VK_FORMAT_D24_UNORM_S8_UINT,
1429 		VK_FORMAT_D16_UNORM,
1430 	};
1431 
1432 	const VkCompareOp compareOps[]	=
1433 	{
1434 		VK_COMPARE_OP_GREATER,
1435 		VK_COMPARE_OP_GREATER_OR_EQUAL,
1436 		VK_COMPARE_OP_LESS,
1437 		VK_COMPARE_OP_LESS_OR_EQUAL,
1438 	};
1439 
1440 	float viewportValues[]			= {2.0f, 6.0f, 12.0f};
1441 	float depthBoundsValues[]		= {2.0f, 4.0f, 8.0f};
1442 	float wcValues[]				= {2.0f, 6.0f, 12.0f};
1443 	float clearValues[]				= {2.0f, -3.0f, 6.0f, -7.0f};
1444 
1445 	// Depth clear values outside range [0.0f, 1.0f].
1446 	{
1447 		de::MovePtr<tcu::TestCaseGroup> depthClearValueTests (new tcu::TestCaseGroup(testCtx, "clear_value"));
1448 		DepthRangeUnrestrictedParam testParams;
1449 		testParams.pipelineConstructionType		= pipelineConstructionType;
1450 		testParams.testClearValueOnly			= VK_TRUE;
1451 		testParams.depthClampEnable				= VK_FALSE;
1452 		testParams.wc							= 1.0f;
1453 		testParams.viewportMinDepth				= 0.0f;
1454 		testParams.viewportMaxDepth				= 1.0f;
1455 		testParams.minDepthBounds				= 0.0f;
1456 		testParams.maxDepthBounds				= 1.0f;
1457 		testParams.depthBoundsTestEnable		= VK_FALSE;
1458 		testParams.depthCompareOp				= VK_COMPARE_OP_LESS_OR_EQUAL;
1459 		testParams.viewportDepthBoundsMode		= TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1460 
1461 		for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1462 		{
1463 			testParams.depthFormat				= depthFormats[format];
1464 			testParams.depthBufferClearValue	= defaultClearValue(depthFormats[format]);
1465 			for (int val = 0; val < DE_LENGTH_OF_ARRAY(clearValues); val++)
1466 			{
1467 				testParams.depthBufferClearValue.depthStencil.depth	= clearValues[val];
1468 				depthClearValueTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1469 			}
1470 		}
1471 		depthTests->addChild(depthClearValueTests.release());
1472 	}
1473 
1474 	// Viewport's depth unrestricted range
1475 	{
1476 		de::MovePtr<tcu::TestCaseGroup> viewportTests (new tcu::TestCaseGroup(testCtx, "viewport"));
1477 		DepthRangeUnrestrictedParam testParams;
1478 		testParams.pipelineConstructionType	= pipelineConstructionType;
1479 		testParams.testClearValueOnly		= VK_FALSE;
1480 		testParams.wc						= 1.0f;
1481 		testParams.depthClampEnable			= VK_TRUE;
1482 		testParams.minDepthBounds			= 0.0f;
1483 		testParams.maxDepthBounds			= 1.0f;
1484 		testParams.depthBoundsTestEnable	= VK_FALSE;
1485 
1486 		for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1487 		{
1488 			testParams.depthFormat				= depthFormats[format];
1489 			testParams.depthBufferClearValue	= defaultClearValue(testParams.depthFormat);
1490 			for (int compareOp = 0; compareOp < DE_LENGTH_OF_ARRAY(compareOps); compareOp++)
1491 			{
1492 				testParams.depthCompareOp		= compareOps[compareOp];
1493 				for (int clearValue = 0; clearValue < DE_LENGTH_OF_ARRAY(clearValues); clearValue++)
1494 				{
1495 					testParams.depthBufferClearValue.depthStencil.depth		= clearValues[clearValue];
1496 					for (int viewportValue = 0; viewportValue < DE_LENGTH_OF_ARRAY(viewportValues); viewportValue++)
1497 					{
1498 						testParams.viewportMinDepth			= -viewportValues[viewportValue];
1499 						testParams.viewportMaxDepth			= viewportValues[viewportValue];
1500 						testParams.viewportDepthBoundsMode	= TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1501 						viewportTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1502 						testParams.viewportDepthBoundsMode	= TEST_MODE_VIEWPORT_DYNAMIC;
1503 						viewportTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1504 					}
1505 				}
1506 			}
1507 		}
1508 
1509 		depthTests->addChild(viewportTests.release());
1510 	}
1511 
1512 	// DepthBounds's depth unrestricted range
1513 	{
1514 		de::MovePtr<tcu::TestCaseGroup> depthBoundsTests (new tcu::TestCaseGroup(testCtx, "depthbounds"));
1515 		DepthRangeUnrestrictedParam testParams;
1516 		testParams.pipelineConstructionType						= pipelineConstructionType;
1517 		testParams.testClearValueOnly							= VK_FALSE;
1518 		testParams.wc											= 1.0f;
1519 		testParams.depthClampEnable								= VK_TRUE;
1520 		testParams.depthBoundsTestEnable						= VK_TRUE;
1521 
1522 		for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1523 		{
1524 			testParams.depthFormat				= depthFormats[format];
1525 			testParams.depthBufferClearValue	= defaultClearValue(testParams.depthFormat);
1526 			for (int compareOp = 0; compareOp < DE_LENGTH_OF_ARRAY(compareOps); compareOp++)
1527 			{
1528 				testParams.depthCompareOp		= compareOps[compareOp];
1529 				for (int clearValue = 0; clearValue < DE_LENGTH_OF_ARRAY(clearValues); clearValue++)
1530 				{
1531 					testParams.depthBufferClearValue.depthStencil.depth		= clearValues[clearValue];
1532 					for (int viewportValue = 0; viewportValue < DE_LENGTH_OF_ARRAY(viewportValues); viewportValue++)
1533 					{
1534 						testParams.viewportMinDepth				= -viewportValues[viewportValue];
1535 						testParams.viewportMaxDepth				= viewportValues[viewportValue];
1536 						for (int depthValue = 0; depthValue < DE_LENGTH_OF_ARRAY(depthBoundsValues); depthValue++)
1537 						{
1538 							testParams.minDepthBounds			= -depthBoundsValues[depthValue];
1539 							testParams.maxDepthBounds			= depthBoundsValues[depthValue];
1540 
1541 							testParams.viewportDepthBoundsMode	= TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1542 							depthBoundsTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1543 							testParams.viewportDepthBoundsMode	= TEST_MODE_DEPTH_BOUNDS_DYNAMIC;
1544 							depthBoundsTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1545 							testParams.viewportDepthBoundsMode  = TEST_MODE_VIEWPORT_DEPTH_BOUNDS_DYNAMIC;
1546 							depthBoundsTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1547 						}
1548 					}
1549 				}
1550 			}
1551 		}
1552 
1553 		depthTests->addChild(depthBoundsTests.release());
1554 	}
1555 
1556 	// Depth clamping disabled
1557 	{
1558 		de::MovePtr<tcu::TestCaseGroup> noDepthClampingTests (new tcu::TestCaseGroup(testCtx, "depthclampingdisabled"));
1559 		DepthRangeUnrestrictedParam testParams;
1560 		testParams.pipelineConstructionType		= pipelineConstructionType;
1561 		testParams.testClearValueOnly			= VK_FALSE;
1562 		testParams.depthClampEnable				= VK_FALSE;
1563 		testParams.minDepthBounds				= 0.0f;
1564 		testParams.maxDepthBounds				= 1.0f;
1565 		testParams.depthBoundsTestEnable		= VK_FALSE;
1566 		testParams.viewportDepthBoundsMode		= TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1567 
1568 		for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1569 		{
1570 			testParams.depthFormat					= depthFormats[format];
1571 			testParams.depthBufferClearValue		= defaultClearValue(testParams.depthFormat);
1572 			for (int compareOp = 0; compareOp < DE_LENGTH_OF_ARRAY(compareOps); compareOp++)
1573 			{
1574 				testParams.depthCompareOp			= compareOps[compareOp];
1575 				for (int clearValue = 0; clearValue < DE_LENGTH_OF_ARRAY(clearValues); clearValue++)
1576 				{
1577 					testParams.depthBufferClearValue.depthStencil.depth	= clearValues[clearValue];
1578 					for (int viewportValue = 0; viewportValue < DE_LENGTH_OF_ARRAY(viewportValues); viewportValue++)
1579 					{
1580 						testParams.viewportMinDepth	= -viewportValues[viewportValue];
1581 						testParams.viewportMaxDepth	= viewportValues[viewportValue];
1582 						for (int wc = 0; wc < DE_LENGTH_OF_ARRAY(wcValues); wc++)
1583 						{
1584 							testParams.wc	= wcValues[wc];
1585 							noDepthClampingTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1586 						}
1587 					}
1588 				}
1589 			}
1590 		}
1591 
1592 		depthTests->addChild(noDepthClampingTests.release());
1593 	}
1594 
1595 	return depthTests.release();
1596 }
1597 
1598 } // pipeline
1599 
1600 } // vkt
1601