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