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