• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 ARM Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Timestamp Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktPipelineTimestampTests.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktPipelineReferenceRenderer.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "deUniquePtr.hpp"
44 #include "deStringUtil.hpp"
45 #include "deMemory.h"
46 
47 #include <sstream>
48 #include <vector>
49 #include <set>
50 #include <cctype>
51 #include <locale>
52 #include <limits>
53 #include <thread>
54 #include <chrono>
55 #include <time.h>
56 #include <algorithm>
57 
58 #if (DE_OS == DE_OS_WIN32)
59 #	define VC_EXTRALEAN
60 #	define WIN32_LEAN_AND_MEAN
61 #	define NOMINMAX
62 #	include <windows.h>
63 #endif
64 
65 namespace vkt
66 {
67 namespace pipeline
68 {
69 
70 using namespace vk;
71 
72 namespace
73 {
74 typedef std::vector<VkPipelineStageFlagBits> StageFlagVector;
75 
76 // helper functions
77 #define GEN_DESC_STRING(name,postfix)                                      \
78 		do {                                                               \
79 		   for (std::string::size_type ndx = 0; ndx<strlen(#name); ++ndx)  \
80 			 if(isDescription && #name[ndx] == '_')                        \
81 			   desc << " ";                                                \
82 			 else                                                          \
83 			   desc << std::tolower(#name[ndx],loc);                       \
84 		   if (isDescription)                                              \
85 			 desc << " " << #postfix;                                      \
86 		   else                                                            \
87 			 desc << "_" << #postfix;                                      \
88 		} while (deGetFalse())
89 
getPipelineStageFlagStr(const VkPipelineStageFlagBits stage,bool isDescription)90 std::string getPipelineStageFlagStr (const VkPipelineStageFlagBits stage,
91 									 bool                          isDescription)
92 {
93 	std::ostringstream desc;
94 	std::locale loc;
95 	switch(stage)
96 	{
97 #define STAGE_CASE(p)                              \
98 		case VK_PIPELINE_STAGE_##p##_BIT:          \
99 		{                                          \
100 			GEN_DESC_STRING(p, stage);             \
101 			break;                                 \
102 		}
103 		STAGE_CASE(TOP_OF_PIPE);
104 		STAGE_CASE(DRAW_INDIRECT);
105 		STAGE_CASE(VERTEX_INPUT);
106 		STAGE_CASE(VERTEX_SHADER);
107 		STAGE_CASE(TESSELLATION_CONTROL_SHADER);
108 		STAGE_CASE(TESSELLATION_EVALUATION_SHADER);
109 		STAGE_CASE(GEOMETRY_SHADER);
110 		STAGE_CASE(FRAGMENT_SHADER);
111 		STAGE_CASE(EARLY_FRAGMENT_TESTS);
112 		STAGE_CASE(LATE_FRAGMENT_TESTS);
113 		STAGE_CASE(COLOR_ATTACHMENT_OUTPUT);
114 		STAGE_CASE(COMPUTE_SHADER);
115 		STAGE_CASE(TRANSFER);
116 		STAGE_CASE(HOST);
117 		STAGE_CASE(ALL_GRAPHICS);
118 		STAGE_CASE(ALL_COMMANDS);
119 #undef STAGE_CASE
120 	  default:
121 		desc << "unknown stage!";
122 		DE_FATAL("Unknown Stage!");
123 		break;
124 	};
125 
126 	return desc.str();
127 }
128 
129 enum TransferMethod
130 {
131 	TRANSFER_METHOD_COPY_BUFFER = 0,
132 	TRANSFER_METHOD_COPY_IMAGE,
133 	TRANSFER_METHOD_BLIT_IMAGE,
134 	TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE,
135 	TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER,
136 	TRANSFER_METHOD_UPDATE_BUFFER,
137 	TRANSFER_METHOD_FILL_BUFFER,
138 	TRANSFER_METHOD_CLEAR_COLOR_IMAGE,
139 	TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE,
140 	TRANSFER_METHOD_RESOLVE_IMAGE,
141 	TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS,
142 	TRANSFER_METHOD_LAST
143 };
144 
getTransferMethodStr(const TransferMethod method,bool isDescription)145 std::string getTransferMethodStr (const TransferMethod	method,
146 								  bool					isDescription)
147 {
148 	std::ostringstream	desc;
149 	std::locale			loc;
150 
151 	switch(method)
152 	{
153 #define METHOD_CASE(p)                             \
154 		case TRANSFER_METHOD_##p:                  \
155 		{                                          \
156 			GEN_DESC_STRING(p, method);            \
157 			break;                                 \
158 		}
159 	  METHOD_CASE(COPY_BUFFER)
160 	  METHOD_CASE(COPY_IMAGE)
161 	  METHOD_CASE(BLIT_IMAGE)
162 	  METHOD_CASE(COPY_BUFFER_TO_IMAGE)
163 	  METHOD_CASE(COPY_IMAGE_TO_BUFFER)
164 	  METHOD_CASE(UPDATE_BUFFER)
165 	  METHOD_CASE(FILL_BUFFER)
166 	  METHOD_CASE(CLEAR_COLOR_IMAGE)
167 	  METHOD_CASE(CLEAR_DEPTH_STENCIL_IMAGE)
168 	  METHOD_CASE(RESOLVE_IMAGE)
169 	  METHOD_CASE(COPY_QUERY_POOL_RESULTS)
170 #undef METHOD_CASE
171 	  default:
172 		desc << "unknown method!";
173 		DE_FATAL("Unknown method!");
174 		break;
175 	};
176 
177 	return desc.str();
178 }
179 
180 constexpr deUint32 MIN_TIMESTAMP_VALID_BITS = 36;
181 constexpr deUint32 MAX_TIMESTAMP_VALID_BITS = 64;
182 
183 // Checks the number of valid bits for the given queue meets the spec requirements.
checkValidBits(deUint32 validBits,deUint32 queueFamilyIndex)184 void checkValidBits (deUint32 validBits, deUint32 queueFamilyIndex)
185 {
186 	if (validBits < MIN_TIMESTAMP_VALID_BITS || validBits > MAX_TIMESTAMP_VALID_BITS)
187 	{
188 		std::ostringstream msg;
189 		msg << "Invalid value for timestampValidBits (" << validBits << ") in queue index " << queueFamilyIndex;
190 		TCU_FAIL(msg.str());
191 	}
192 }
193 
194 // Returns the timestamp mask given the number of valid timestamp bits.
timestampMaskFromValidBits(deUint32 validBits)195 deUint64 timestampMaskFromValidBits (deUint32 validBits)
196 {
197 	return ((validBits == MAX_TIMESTAMP_VALID_BITS) ? std::numeric_limits<deUint64>::max() : ((1ULL << validBits) - 1));
198 }
199 
200 // Checks support for timestamps and returns the timestamp mask.
checkTimestampsSupported(Context & context)201 deUint64 checkTimestampsSupported (Context& context)
202 {
203 	const InstanceInterface&					vki					= context.getInstanceInterface();
204 	const VkPhysicalDevice						physDevice			= context.getPhysicalDevice();
205 	const deUint32								queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
206 	const std::vector<VkQueueFamilyProperties>	queueProperties		= vk::getPhysicalDeviceQueueFamilyProperties(vki, physDevice);
207 	DE_ASSERT(queueFamilyIndex < queueProperties.size());
208 	const deUint32&								validBits			= queueProperties[queueFamilyIndex].timestampValidBits;
209 
210 	if (validBits == 0)
211 		throw tcu::NotSupportedError("Universal queue does not support timestamps");
212 
213 	checkValidBits(validBits, queueFamilyIndex);
214 	return timestampMaskFromValidBits(validBits);
215 }
216 
checkTimestampBits(deUint64 timestamp,deUint64 mask)217 void checkTimestampBits (deUint64 timestamp, deUint64 mask)
218 {
219 	// The spec says:
220 	// timestampValidBits is the unsigned integer count of meaningful bits in
221 	// the timestamps written via vkCmdWriteTimestamp. The valid range for the
222 	// count is 36..64 bits, or a value of 0, indicating no support for
223 	// timestamps. Bits outside the valid range are guaranteed to be zeros.
224 	if (timestamp > mask)
225 	{
226 		std::ostringstream msg;
227 		msg << std::hex << "Invalid device timestamp value 0x" << timestamp << " according to device timestamp mask 0x" << mask;
228 		TCU_FAIL(msg.str());
229 	}
230 }
231 
232 // helper classes
233 class TimestampTestParam
234 {
235 public:
236 								TimestampTestParam		(const VkPipelineStageFlagBits*	stages,
237 														 const deUint32					stageCount,
238 														 const bool						inRenderPass,
239 														 const bool						hostQueryReset);
240 								~TimestampTestParam		(void);
241 	virtual const std::string	generateTestName		(void) const;
242 	virtual const std::string	generateTestDescription	(void) const;
getStageVector(void) const243 	StageFlagVector				getStageVector			(void) const	{ return m_stageVec; }
getInRenderPass(void) const244 	bool						getInRenderPass			(void) const	{ return m_inRenderPass; }
getHostQueryReset(void) const245 	bool						getHostQueryReset		(void) const	{ return m_hostQueryReset; }
toggleInRenderPass(void)246 	void						toggleInRenderPass		(void)			{ m_inRenderPass = !m_inRenderPass; }
toggleHostQueryReset(void)247 	void						toggleHostQueryReset	(void)			{ m_hostQueryReset = !m_hostQueryReset; }
248 protected:
249 	StageFlagVector				m_stageVec;
250 	bool						m_inRenderPass;
251 	bool						m_hostQueryReset;
252 };
253 
TimestampTestParam(const VkPipelineStageFlagBits * stages,const deUint32 stageCount,const bool inRenderPass,const bool hostQueryReset)254 TimestampTestParam::TimestampTestParam (const VkPipelineStageFlagBits*	stages,
255 									    const deUint32					stageCount,
256 									    const bool						inRenderPass,
257 									    const bool						hostQueryReset)
258 	: m_inRenderPass(inRenderPass)
259 	, m_hostQueryReset(hostQueryReset)
260 {
261 	for (deUint32 ndx = 0; ndx < stageCount; ndx++)
262 	{
263 		m_stageVec.push_back(stages[ndx]);
264 	}
265 }
266 
~TimestampTestParam(void)267 TimestampTestParam::~TimestampTestParam (void)
268 {
269 }
270 
generateTestName(void) const271 const std::string TimestampTestParam::generateTestName (void) const
272 {
273 	std::string result("");
274 
275 	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
276 	{
277 		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
278 		{
279 			result += getPipelineStageFlagStr(*it, false) + '_';
280 		}
281 	}
282 	if(m_inRenderPass)
283 		result += "in_render_pass";
284 	else
285 		result += "out_of_render_pass";
286 
287 	if(m_hostQueryReset)
288 		result += "_host_query_reset";
289 
290 	return result;
291 }
292 
generateTestDescription(void) const293 const std::string TimestampTestParam::generateTestDescription (void) const
294 {
295 	std::string result("Record timestamp after ");
296 
297 	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
298 	{
299 		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
300 		{
301 			result += getPipelineStageFlagStr(*it, true) + ' ';
302 		}
303 	}
304 	if(m_inRenderPass)
305 		result += " in the renderpass";
306 	else
307 		result += " out of the render pass";
308 
309 	if(m_hostQueryReset)
310 		result += "and the host resets query pool";
311 
312 	return result;
313 }
314 
315 class TransferTimestampTestParam : public TimestampTestParam
316 {
317 public:
318 						TransferTimestampTestParam	(const VkPipelineStageFlagBits*	stages,
319 													 const deUint32					stageCount,
320 													 const bool						inRenderPass,
321 													 const bool						hostQueryReset,
322 													 const deUint32					methodNdx);
~TransferTimestampTestParam(void)323 						~TransferTimestampTestParam	(void) { }
324 	const std::string	generateTestName			(void) const;
325 	const std::string	generateTestDescription		(void) const;
getMethod(void) const326 	TransferMethod		getMethod					(void) const { return m_method; }
327 protected:
328 	TransferMethod		m_method;
329 };
330 
TransferTimestampTestParam(const VkPipelineStageFlagBits * stages,const deUint32 stageCount,const bool inRenderPass,const bool hostQueryReset,const deUint32 methodNdx)331 TransferTimestampTestParam::TransferTimestampTestParam (const VkPipelineStageFlagBits*	stages,
332 													    const deUint32					stageCount,
333 													    const bool						inRenderPass,
334 													    const bool						hostQueryReset,
335 													    const deUint32					methodNdx)
336 	: TimestampTestParam(stages, stageCount, inRenderPass, hostQueryReset)
337 {
338 	DE_ASSERT(methodNdx < (deUint32)TRANSFER_METHOD_LAST);
339 
340 	m_method = (TransferMethod)methodNdx;
341 }
342 
generateTestName(void) const343 const std::string TransferTimestampTestParam::generateTestName (void) const
344 {
345 	std::string result("");
346 
347 	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
348 	{
349 		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
350 		{
351 			result += getPipelineStageFlagStr(*it, false) + '_';
352 		}
353 	}
354 
355 	result += "with_" + getTransferMethodStr(m_method, false);
356 
357 	if(m_hostQueryReset)
358 		result += "_host_query_reset";
359 
360 	return result;
361 }
362 
generateTestDescription(void) const363 const std::string TransferTimestampTestParam::generateTestDescription (void) const
364 {
365 	std::string result("");
366 
367 	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
368 	{
369 		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
370 		{
371 			result += getPipelineStageFlagStr(*it, true) + ' ';
372 		}
373 	}
374 
375 	result += "with " + getTransferMethodStr(m_method, true);
376 
377 	if(m_hostQueryReset)
378 		result += "and the host resets query pool";
379 
380 	return result;
381 }
382 
383 class TwoCmdBuffersTestParam : public TimestampTestParam
384 {
385 public:
386 							TwoCmdBuffersTestParam	(const VkPipelineStageFlagBits*	stages,
387 													 const deUint32					stageCount,
388 													 const bool						inRenderPass,
389 													 const bool						hostQueryReset,
390 													 const VkCommandBufferLevel		cmdBufferLevel);
~TwoCmdBuffersTestParam(void)391 							~TwoCmdBuffersTestParam	(void) { }
getCmdBufferLevel(void) const392 	VkCommandBufferLevel	getCmdBufferLevel		(void) const { return m_cmdBufferLevel; }
393 protected:
394 	VkCommandBufferLevel	m_cmdBufferLevel;
395 };
396 
TwoCmdBuffersTestParam(const VkPipelineStageFlagBits * stages,const deUint32 stageCount,const bool inRenderPass,const bool hostQueryReset,const VkCommandBufferLevel cmdBufferLevel)397 TwoCmdBuffersTestParam::TwoCmdBuffersTestParam	(const VkPipelineStageFlagBits*	stages,
398 												 const deUint32					stageCount,
399 												 const bool						inRenderPass,
400 												 const bool						hostQueryReset,
401 												 const VkCommandBufferLevel		cmdBufferLevel)
402 : TimestampTestParam(stages, stageCount, inRenderPass, hostQueryReset), m_cmdBufferLevel(cmdBufferLevel)
403 {
404 }
405 
406 class SimpleGraphicsPipelineBuilder
407 {
408 public:
409 						 SimpleGraphicsPipelineBuilder  (Context& context);
~SimpleGraphicsPipelineBuilder(void)410 						 ~SimpleGraphicsPipelineBuilder (void) { }
411 
412 	void				bindShaderStage					(VkShaderStageFlagBits	stage,
413 														 const char*			source_name);
414 
415 	void				enableTessellationStage			(deUint32              patchControlPoints);
416 
417 	Move<VkPipeline>	buildPipeline					(tcu::UVec2            renderSize,
418 														 VkRenderPass          renderPass);
419 protected:
420 	enum
421 	{
422 		VK_MAX_SHADER_STAGES = 6,
423 	};
424 
425 	Context&				m_context;
426 
427 	Move<VkShaderModule>	m_shaderModules[VK_MAX_SHADER_STAGES];
428 	deUint32				m_shaderStageCount;
429 	VkShaderStageFlagBits	m_shaderStages[VK_MAX_SHADER_STAGES];
430 
431 	deUint32				m_patchControlPoints;
432 
433 	Move<VkPipelineLayout>	m_pipelineLayout;
434 	Move<VkPipeline>		m_graphicsPipelines;
435 
436 };
437 
SimpleGraphicsPipelineBuilder(Context & context)438 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder(Context& context)
439 	: m_context(context)
440 {
441 	m_patchControlPoints = 0;
442 	m_shaderStageCount   = 0;
443 }
444 
bindShaderStage(VkShaderStageFlagBits stage,const char * source_name)445 void SimpleGraphicsPipelineBuilder::bindShaderStage (VkShaderStageFlagBits	stage,
446 													 const char*			source_name)
447 {
448 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
449 	const VkDevice			vkDevice	= m_context.getDevice();
450 
451 	// Create shader module
452 	deUint32*				pCode		= (deUint32*)m_context.getBinaryCollection().get(source_name).getBinary();
453 	deUint32				codeSize	= (deUint32)m_context.getBinaryCollection().get(source_name).getSize();
454 
455 	const VkShaderModuleCreateInfo moduleCreateInfo =
456 	{
457 		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,	// VkStructureType             sType;
458 		DE_NULL,										// const void*                 pNext;
459 		0u,												// VkShaderModuleCreateFlags   flags;
460 		codeSize,										// deUintptr                   codeSize;
461 		pCode,											// const deUint32*             pCode;
462 	};
463 
464 	m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
465 	m_shaderStages[m_shaderStageCount] = stage;
466 
467 	m_shaderStageCount++;
468 }
469 
buildPipeline(tcu::UVec2 renderSize,VkRenderPass renderPass)470 Move<VkPipeline> SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass)
471 {
472 	const DeviceInterface&	vk						= m_context.getDeviceInterface();
473 	const VkDevice			vkDevice				= m_context.getDevice();
474 	VkShaderModule			vertShaderModule		= DE_NULL;
475 	VkShaderModule			tessControlShaderModule	= DE_NULL;
476 	VkShaderModule			tessEvalShaderModule	= DE_NULL;
477 	VkShaderModule			geomShaderModule		= DE_NULL;
478 	VkShaderModule			fragShaderModule		= DE_NULL;
479 
480 	for (deUint32 i = 0; i < m_shaderStageCount; i++)
481 	{
482 		if (m_shaderStages[i] == VK_SHADER_STAGE_VERTEX_BIT)
483 			vertShaderModule = *m_shaderModules[i];
484 		else if (m_shaderStages[i] == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
485 			tessControlShaderModule = *m_shaderModules[i];
486 		else if (m_shaderStages[i] == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
487 			tessEvalShaderModule = *m_shaderModules[i];
488 		else if (m_shaderStages[i] == VK_SHADER_STAGE_GEOMETRY_BIT)
489 			geomShaderModule = *m_shaderModules[i];
490 		else if (m_shaderStages[i] == VK_SHADER_STAGE_FRAGMENT_BIT)
491 			fragShaderModule = *m_shaderModules[i];
492 	}
493 
494 	// Create pipeline layout
495 	{
496 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
497 		{
498 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType                  sType;
499 			DE_NULL,										// const void*                      pNext;
500 			0u,												// VkPipelineLayoutCreateFlags      flags;
501 			0u,												// deUint32                         setLayoutCount;
502 			DE_NULL,										// const VkDescriptorSetLayout*     pSetLayouts;
503 			0u,												// deUint32                         pushConstantRangeCount;
504 			DE_NULL											// const VkPushConstantRange*       pPushConstantRanges;
505 		};
506 
507 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
508 	}
509 
510 	// Create pipeline
511 	const VkVertexInputBindingDescription vertexInputBindingDescription =
512 	{
513 		0u,								// deUint32                 binding;
514 		sizeof(Vertex4RGBA),			// deUint32                 strideInBytes;
515 		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate        inputRate;
516 	};
517 
518 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
519 	{
520 		{
521 			0u,									// deUint32 location;
522 			0u,									// deUint32 binding;
523 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
524 			0u									// deUint32 offsetInBytes;
525 		},
526 		{
527 			1u,									// deUint32 location;
528 			0u,									// deUint32 binding;
529 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
530 			DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32 offsetInBytes;
531 		}
532 	};
533 
534 	const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
535 	{
536 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                          sType;
537 		DE_NULL,													// const void*                              pNext;
538 		0u,															// VkPipelineVertexInputStateCreateFlags    flags;
539 		1u,															// deUint32                                 vertexBindingDescriptionCount;
540 		&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*   pVertexBindingDescriptions;
541 		2u,															// deUint32                                 vertexAttributeDescriptionCount;
542 		vertexInputAttributeDescriptions,							// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
543 	};
544 
545 	VkPrimitiveTopology primitiveTopology = (m_patchControlPoints > 0) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
546 
547 	const std::vector<VkViewport>	viewports	(1, makeViewport(renderSize));
548 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(renderSize));
549 
550 	VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
551 	{
552 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType                          sType;
553 		DE_NULL,													// const void*                              pNext;
554 		0u,															// VkPipelineDepthStencilStateCreateFlags   flags;
555 		VK_TRUE,													// VkBool32                                 depthTestEnable;
556 		VK_TRUE,													// VkBool32                                 depthWriteEnable;
557 		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp                              depthCompareOp;
558 		VK_FALSE,													// VkBool32                                 depthBoundsTestEnable;
559 		VK_FALSE,													// VkBool32                                 stencilTestEnable;
560 		// VkStencilOpState front;
561 		{
562 			VK_STENCIL_OP_KEEP,		// VkStencilOp  failOp;
563 			VK_STENCIL_OP_KEEP,		// VkStencilOp  passOp;
564 			VK_STENCIL_OP_KEEP,		// VkStencilOp  depthFailOp;
565 			VK_COMPARE_OP_NEVER,	// VkCompareOp  compareOp;
566 			0u,						// deUint32     compareMask;
567 			0u,						// deUint32     writeMask;
568 			0u,						// deUint32     reference;
569 		},
570 		// VkStencilOpState back;
571 		{
572 			VK_STENCIL_OP_KEEP,		// VkStencilOp  failOp;
573 			VK_STENCIL_OP_KEEP,		// VkStencilOp  passOp;
574 			VK_STENCIL_OP_KEEP,		// VkStencilOp  depthFailOp;
575 			VK_COMPARE_OP_NEVER,	// VkCompareOp  compareOp;
576 			0u,						// deUint32     compareMask;
577 			0u,						// deUint32     writeMask;
578 			0u,						// deUint32     reference;
579 		},
580 		0.0f,														// float                                    minDepthBounds;
581 		1.0f,														// float                                    maxDepthBounds;
582 	};
583 
584 	return makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
585 								vkDevice,					// const VkDevice                                device
586 								*m_pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
587 								vertShaderModule,			// const VkShaderModule                          vertexShaderModule
588 								tessControlShaderModule,	// const VkShaderModule                          tessellationControlModule
589 								tessEvalShaderModule,		// const VkShaderModule                          tessellationEvalModule
590 								geomShaderModule,			// const VkShaderModule                          geometryShaderModule
591 								fragShaderModule,			// const VkShaderModule                          fragmentShaderModule
592 								renderPass,					// const VkRenderPass                            renderPass
593 								viewports,					// const std::vector<VkViewport>&                viewports
594 								scissors,					// const std::vector<VkRect2D>&                  scissors
595 								primitiveTopology,			// const VkPrimitiveTopology                     topology
596 								0u,							// const deUint32                                subpass
597 								m_patchControlPoints,		// const deUint32                                patchControlPoints
598 								&vertexInputStateParams,	// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
599 								DE_NULL,					// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
600 								DE_NULL,					// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
601 								&depthStencilStateParams);	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
602 }
603 
enableTessellationStage(deUint32 patchControlPoints)604 void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
605 {
606 	m_patchControlPoints = patchControlPoints;
607 }
608 
609 template <class Test>
newTestCase(tcu::TestContext & testContext,TimestampTestParam * testParam)610 vkt::TestCase* newTestCase	(tcu::TestContext&		testContext,
611 							 TimestampTestParam*	testParam)
612 {
613 	return new Test(testContext,
614 					testParam->generateTestName().c_str(),
615 					testParam->generateTestDescription().c_str(),
616 					testParam);
617 }
618 
619 // Test Classes
620 class TimestampTest : public vkt::TestCase
621 {
622 public:
623 	enum
624 	{
625 		ENTRY_COUNT = 8
626 	};
627 
TimestampTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)628 							TimestampTest	(tcu::TestContext&			testContext,
629 											 const std::string&			name,
630 											 const std::string&			description,
631 											 const TimestampTestParam*	param)
632 											 : vkt::TestCase	(testContext, name, description)
633 											 , m_stages			(param->getStageVector())
634 											 , m_inRenderPass	(param->getInRenderPass())
635 											 , m_hostQueryReset	(param->getHostQueryReset())
636 											 { }
~TimestampTest(void)637 	virtual					~TimestampTest	(void) { }
638 	virtual void			initPrograms	(SourceCollections& programCollection) const;
639 	virtual TestInstance*	createInstance	(Context& context) const;
640 	virtual void			checkSupport	(Context& context) const;
641 protected:
642 	const StageFlagVector	m_stages;
643 	const bool				m_inRenderPass;
644 	const bool				m_hostQueryReset;
645 };
646 
647 class TimestampTestInstance : public vkt::TestInstance
648 {
649 public:
650 							TimestampTestInstance		(Context&				context,
651 														 const StageFlagVector&	stages,
652 														 const bool				inRenderPass,
653 														 const bool				hostQueryReset);
654 
655 	virtual					~TimestampTestInstance		(void);
656 	virtual tcu::TestStatus	iterate						(void);
657 
658 protected:
659 	virtual tcu::TestStatus	verifyTimestamp				(void);
660 	virtual void            configCommandBuffer			(void);
661 
662 	Move<VkBuffer>			createBufferAndBindMemory	(VkDeviceSize				size,
663 														 VkBufferUsageFlags			usage,
664 														 de::MovePtr<Allocation>*	pAlloc);
665 
666 	Move<VkImage>			createImage2DAndBindMemory	(VkFormat					format,
667 														 deUint32					width,
668 														 deUint32					height,
669 														 VkImageUsageFlags			usage,
670 														 VkSampleCountFlagBits		sampleCount,
671 														 de::MovePtr<Allocation>*	pAlloc);
672 
673 protected:
674 	const StageFlagVector	m_stages;
675 	bool					m_inRenderPass;
676 	bool					m_hostQueryReset;
677 
678 	Move<VkCommandPool>		m_cmdPool;
679 	Move<VkCommandBuffer>	m_cmdBuffer;
680 	Move<VkQueryPool>		m_queryPool;
681 	deUint64*				m_timestampValues;
682 	deUint64*				m_timestampValuesHostQueryReset;
683 	deUint64				m_timestampMask;
684 };
685 
initPrograms(SourceCollections & programCollection) const686 void TimestampTest::initPrograms (SourceCollections& programCollection) const
687 {
688 	vkt::TestCase::initPrograms(programCollection);
689 }
690 
checkSupport(Context & context) const691 void TimestampTest::checkSupport (Context& context) const
692 {
693 	// Check support for timestamp queries
694 	{
695 		const deUint32								queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
696 		const std::vector<VkQueueFamilyProperties>	queueProperties		= vk::getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
697 
698 		DE_ASSERT(queueFamilyIndex < (deUint32)queueProperties.size());
699 
700 		if (!queueProperties[queueFamilyIndex].timestampValidBits)
701 			throw tcu::NotSupportedError("Universal queue does not support timestamps");
702 	}
703 
704 	if (m_hostQueryReset)
705 	{
706 		// Check VK_EXT_host_query_reset is supported
707 		context.requireDeviceFunctionality("VK_EXT_host_query_reset");
708 
709 		if(context.getHostQueryResetFeatures().hostQueryReset == VK_FALSE)
710 			throw tcu::NotSupportedError("Implementation doesn't support resetting queries from the host");
711 	}
712 }
713 
createInstance(Context & context) const714 TestInstance* TimestampTest::createInstance (Context& context) const
715 {
716 	return new TimestampTestInstance(context,m_stages,m_inRenderPass,m_hostQueryReset);
717 }
718 
TimestampTestInstance(Context & context,const StageFlagVector & stages,const bool inRenderPass,const bool hostQueryReset)719 TimestampTestInstance::TimestampTestInstance (Context&					context,
720 											  const StageFlagVector&	stages,
721 											  const bool				inRenderPass,
722 											  const bool				hostQueryReset)
723 	: TestInstance		(context)
724 	, m_stages			(stages)
725 	, m_inRenderPass	(inRenderPass)
726 	, m_hostQueryReset	(hostQueryReset)
727 {
728 	const DeviceInterface&	vk					= context.getDeviceInterface();
729 	const VkDevice			vkDevice			= context.getDevice();
730 	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
731 
732 	m_timestampMask = checkTimestampsSupported(context);
733 
734 	// Create Query Pool
735 	{
736 		const VkQueryPoolCreateInfo queryPoolParams =
737 		{
738 		   VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
739 		   DE_NULL,										// const void*                   pNext;
740 		   0u,											// VkQueryPoolCreateFlags        flags;
741 		   VK_QUERY_TYPE_TIMESTAMP,						// VkQueryType                   queryType;
742 		   TimestampTest::ENTRY_COUNT,					// deUint32                      entryCount;
743 		   0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
744 		};
745 
746 		m_queryPool = createQueryPool(vk, vkDevice, &queryPoolParams);
747 	}
748 
749 	// Create command pool
750 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
751 
752 	// Create command buffer
753 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
754 
755 	// alloc timestamp values
756 	m_timestampValues = new deUint64[m_stages.size()];
757 
758 	if (m_hostQueryReset)
759 		m_timestampValuesHostQueryReset = new deUint64[m_stages.size() * 2];
760 	else
761 		m_timestampValuesHostQueryReset = DE_NULL;
762 }
763 
~TimestampTestInstance(void)764 TimestampTestInstance::~TimestampTestInstance (void)
765 {
766 	delete[] m_timestampValues;
767 	m_timestampValues = NULL;
768 
769 	delete[] m_timestampValuesHostQueryReset;
770 	m_timestampValuesHostQueryReset = NULL;
771 }
772 
configCommandBuffer(void)773 void TimestampTestInstance::configCommandBuffer (void)
774 {
775 	const DeviceInterface& vk = m_context.getDeviceInterface();
776 
777 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
778 
779 	if (!m_hostQueryReset)
780 		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
781 
782 	deUint32 timestampEntry = 0;
783 	for (const auto& stage : m_stages)
784 	{
785 		vk.cmdWriteTimestamp(*m_cmdBuffer, stage, *m_queryPool, timestampEntry++);
786 	}
787 
788 	endCommandBuffer(vk, *m_cmdBuffer);
789 }
790 
iterate(void)791 tcu::TestStatus TimestampTestInstance::iterate (void)
792 {
793 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
794 	const VkDevice			vkDevice			= m_context.getDevice();
795 	const VkQueue			queue				= m_context.getUniversalQueue();
796 	const deUint32			stageSize			= (deUint32)m_stages.size();
797 
798 	configCommandBuffer();
799 	if (m_hostQueryReset)
800 	{
801 		vk.resetQueryPool(vkDevice, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
802 	}
803 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
804 
805 	// Get timestamp value from query pool
806 	vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, stageSize, sizeof(deUint64) * stageSize, (void*)m_timestampValues, sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
807 
808 	for (deUint32 ndx = 0; ndx < stageSize; ndx++)
809 	{
810 		m_timestampValues[ndx] &= m_timestampMask;
811 	}
812 
813 	if(m_hostQueryReset)
814 	{
815 		// Initialize timestampValuesHostQueryReset values
816 		deMemset(m_timestampValuesHostQueryReset, 0, sizeof(deUint64) * stageSize * 2);
817 
818 		for (deUint32 ndx = 0; ndx < stageSize; ndx++)
819 		{
820 			m_timestampValuesHostQueryReset[2 * ndx] = m_timestampValues[ndx];
821 		}
822 
823 		// Host resets the query pool
824 		vk.resetQueryPool(vkDevice, *m_queryPool, 0u, stageSize);
825 		// Get timestamp value from query pool
826 		vk::VkResult res = vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, stageSize, sizeof(deUint64) * stageSize * 2, (void*)m_timestampValuesHostQueryReset, sizeof(deUint64) * 2, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
827 
828 		/* From Vulkan spec:
829 		 *
830 		 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
831 		 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
832 		 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
833 		 */
834 		if (res != vk::VK_NOT_READY)
835 			return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
836 
837 		for (deUint32 ndx = 0; ndx < stageSize; ndx++)
838 		{
839 			if ((m_timestampValuesHostQueryReset[2 * ndx] & m_timestampMask) != m_timestampValues[ndx])
840 				return tcu::TestStatus::fail("QueryPoolResults returned value was modified");
841 			if (m_timestampValuesHostQueryReset[2 * ndx + 1] != 0u)
842 				return tcu::TestStatus::fail("QueryPoolResults availability status is not zero");
843 		}
844 	}
845 
846 	return verifyTimestamp();
847 }
848 
verifyTimestamp(void)849 tcu::TestStatus TimestampTestInstance::verifyTimestamp (void)
850 {
851 	for (deUint32 first = 0; first < m_stages.size(); first++)
852 	{
853 		for (deUint32 second = 0; second < first; second++)
854 		{
855 			if(m_timestampValues[first] < m_timestampValues[second])
856 			{
857 				return tcu::TestStatus::fail("Latter stage timestamp is smaller than the former stage timestamp.");
858 			}
859 		}
860 	}
861 
862 	return tcu::TestStatus::pass("Timestamp increases steadily.");
863 }
864 
createBufferAndBindMemory(VkDeviceSize size,VkBufferUsageFlags usage,de::MovePtr<Allocation> * pAlloc)865 Move<VkBuffer> TimestampTestInstance::createBufferAndBindMemory (VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
866 {
867 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
868 	const VkDevice				vkDevice			= m_context.getDevice();
869 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
870 	SimpleAllocator				memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
871 
872 	const VkBufferCreateInfo	vertexBufferParams	=
873 	{
874 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType      sType;
875 		DE_NULL,								// const void*          pNext;
876 		0u,										// VkBufferCreateFlags  flags;
877 		size,									// VkDeviceSize         size;
878 		usage,									// VkBufferUsageFlags   usage;
879 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode        sharingMode;
880 		1u,										// deUint32             queueFamilyCount;
881 		&queueFamilyIndex						// const deUint32*      pQueueFamilyIndices;
882 	};
883 
884 	Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
885 	de::MovePtr<Allocation> vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
886 
887 	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
888 
889 	DE_ASSERT(pAlloc);
890 	*pAlloc = vertexBufferAlloc;
891 
892 	return vertexBuffer;
893 }
894 
createImage2DAndBindMemory(VkFormat format,deUint32 width,deUint32 height,VkImageUsageFlags usage,VkSampleCountFlagBits sampleCount,de::details::MovePtr<Allocation> * pAlloc)895 Move<VkImage> TimestampTestInstance::createImage2DAndBindMemory (VkFormat							format,
896 																 deUint32							width,
897 																 deUint32							height,
898 																 VkImageUsageFlags					usage,
899 																 VkSampleCountFlagBits				sampleCount,
900 																 de::details::MovePtr<Allocation>*	pAlloc)
901 {
902 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
903 	const VkDevice			vkDevice			= m_context.getDevice();
904 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
905 	SimpleAllocator			memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
906 
907 	// Optimal tiling feature check
908 	VkFormatProperties		formatProperty;
909 
910 	m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), format, &formatProperty);
911 
912 	if((usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(formatProperty.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
913 	{
914 		// Remove color attachment usage if the optimal tiling feature does not support it
915 		usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
916 	}
917 	if((usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(formatProperty.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
918 	{
919 		// Remove storage usage if the optimal tiling feature does not support it
920 		usage &= ~VK_IMAGE_USAGE_STORAGE_BIT;
921 	}
922 
923 	const VkImageCreateInfo colorImageParams =
924 	{
925 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType      sType;
926 		DE_NULL,								// const void*          pNext;
927 		0u,										// VkImageCreateFlags   flags;
928 		VK_IMAGE_TYPE_2D,						// VkImageType          imageType;
929 		format,									// VkFormat             format;
930 		{ width, height, 1u },					// VkExtent3D           extent;
931 		1u,										// deUint32             mipLevels;
932 		1u,										// deUint32             arraySize;
933 		sampleCount,							// deUint32             samples;
934 		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling        tiling;
935 		usage,									// VkImageUsageFlags    usage;
936 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode        sharingMode;
937 		1u,										// deUint32             queueFamilyCount;
938 		&queueFamilyIndex,						// const deUint32*      pQueueFamilyIndices;
939 		VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout        initialLayout;
940 	};
941 
942 	Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
943 
944 	// Allocate and bind image memory
945 	de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
946 	VK_CHECK(vk.bindImageMemory(vkDevice, *image, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
947 
948 	DE_ASSERT(pAlloc);
949 	*pAlloc = colorImageAlloc;
950 
951 	return image;
952 }
953 
954 template <class T>
955 class CalibratedTimestampTest : public vkt::TestCase
956 {
957 public:
CalibratedTimestampTest(tcu::TestContext & testContext,const std::string & name,const std::string & description)958 								CalibratedTimestampTest		(tcu::TestContext&		testContext,
959 															 const std::string&		name,
960 															 const std::string&		description)
961 									: vkt::TestCase{testContext, name, description}
962 									{ }
963 
~CalibratedTimestampTest(void)964 	virtual						~CalibratedTimestampTest	(void) override { }
965 	virtual void				initPrograms				(SourceCollections&		programCollection) const override;
966 	virtual void				checkSupport				(Context&				context) const override;
967 	virtual vkt::TestInstance*	createInstance				(Context&				context) const override;
968 };
969 
970 class CalibratedTimestampTestInstance : public vkt::TestInstance
971 {
972 public:
973 							CalibratedTimestampTestInstance		(Context& context);
~CalibratedTimestampTestInstance(void)974 	virtual                 ~CalibratedTimestampTestInstance	(void) override { }
975 	virtual tcu::TestStatus iterate								(void) override;
976 	virtual tcu::TestStatus runTest								(void) = 0;
977 protected:
978 	struct CalibratedTimestamp
979 	{
CalibratedTimestampvkt::pipeline::__anon39456d5d0111::CalibratedTimestampTestInstance::CalibratedTimestamp980 		CalibratedTimestamp(deUint64 timestamp_, deUint64 deviation_) : timestamp{timestamp_}, deviation(deviation_) { }
CalibratedTimestampvkt::pipeline::__anon39456d5d0111::CalibratedTimestampTestInstance::CalibratedTimestamp981 		CalibratedTimestamp() : timestamp{}, deviation{} { }
982 		deUint64 timestamp;
983 		deUint64 deviation;
984 	};
985 
986 	std::vector<VkTimeDomainEXT>		getDomainSubset(const std::vector<VkTimeDomainEXT>& available, const std::vector<VkTimeDomainEXT>& interesting) const;
987 	std::string							domainName(VkTimeDomainEXT domain) const;
988 	deUint64							getHostNativeTimestamp(VkTimeDomainEXT hostDomain) const;
989 	deUint64							getHostNanoseconds(deUint64 hostTimestamp) const;
990 	deUint64							getDeviceNanoseconds(deUint64 devTicksDelta) const;
991 	std::vector<CalibratedTimestamp>	getCalibratedTimestamps(const std::vector<VkTimeDomainEXT>& domains);
992 	CalibratedTimestamp					getCalibratedTimestamp(VkTimeDomainEXT domain);
993 	void								appendQualityMessage(const std::string& message);
994 
995 	void								verifyDevTimestampMask(deUint64 value) const;
996 	deUint64							absDiffWithOverflow(deUint64 a, deUint64 b, deUint64 mask = std::numeric_limits<deUint64>::max()) const;
997 	deUint64							positiveDiffWithOverflow(deUint64 before, deUint64 after, deUint64 mask = std::numeric_limits<deUint64>::max()) const;
998 	bool								outOfRange(deUint64 begin, deUint64 middle, deUint64 end) const;
999 
1000 	static constexpr deUint64		kBatchTimeLimitNanos		= 1000000000u;	// 1 sec.
1001 	static constexpr deUint64		kDeviationErrorLimitNanos	=  100000000u;	// 100 ms.
1002 	static constexpr deUint64		kDeviationWarningLimitNanos =   50000000u;	// 50 ms.
1003 	static constexpr deUint64		kDefaultToleranceNanos		=  100000000u;	// 100 ms.
1004 
1005 #if (DE_OS == DE_OS_WIN32)
1006     // Preprocessor used to avoid warning about unused variable.
1007 	static constexpr deUint64		kNanosecondsPerSecond		= 1000000000u;
1008 #endif
1009 	static constexpr deUint64		kNanosecondsPerMillisecond	=    1000000u;
1010 
1011 	std::string						m_qualityMessage;
1012 	float							m_timestampPeriod;
1013 	std::vector<VkTimeDomainEXT>	m_devDomains;
1014 	std::vector<VkTimeDomainEXT>	m_hostDomains;
1015 #if (DE_OS == DE_OS_WIN32)
1016 	deUint64						m_frequency;
1017 #endif
1018 
1019 	Move<VkCommandPool>				m_cmdPool;
1020 	Move<VkCommandBuffer>			m_cmdBuffer;
1021 	Move<VkQueryPool>				m_queryPool;
1022 	deUint64						m_devTimestampMask;
1023 };
1024 
1025 class CalibratedTimestampDevDomainTestInstance : public CalibratedTimestampTestInstance
1026 {
1027 public:
CalibratedTimestampDevDomainTestInstance(Context & context)1028 							CalibratedTimestampDevDomainTestInstance	(Context& context)
1029 								: CalibratedTimestampTestInstance{context}
1030 								{ }
1031 
~CalibratedTimestampDevDomainTestInstance(void)1032 	virtual                 ~CalibratedTimestampDevDomainTestInstance	(void) { }
1033 	virtual tcu::TestStatus runTest										(void) override;
1034 };
1035 
1036 class CalibratedTimestampHostDomainTestInstance : public CalibratedTimestampTestInstance
1037 {
1038 public:
CalibratedTimestampHostDomainTestInstance(Context & context)1039 							CalibratedTimestampHostDomainTestInstance	(Context& context)
1040 								: CalibratedTimestampTestInstance{context}
1041 								{ }
1042 
~CalibratedTimestampHostDomainTestInstance(void)1043 	virtual                 ~CalibratedTimestampHostDomainTestInstance	(void) { }
1044 	virtual tcu::TestStatus runTest										(void) override;
1045 };
1046 
1047 class CalibratedTimestampCalibrationTestInstance : public CalibratedTimestampTestInstance
1048 {
1049 public:
CalibratedTimestampCalibrationTestInstance(Context & context)1050 							CalibratedTimestampCalibrationTestInstance	(Context& context)
1051 								: CalibratedTimestampTestInstance{context}
1052 								{ }
1053 
~CalibratedTimestampCalibrationTestInstance(void)1054 	virtual                 ~CalibratedTimestampCalibrationTestInstance	(void) { }
1055 	virtual tcu::TestStatus runTest										(void) override;
1056 };
1057 
1058 template <class T>
initPrograms(SourceCollections & programCollection) const1059 void CalibratedTimestampTest<T>::initPrograms (SourceCollections& programCollection) const
1060 {
1061 	vkt::TestCase::initPrograms(programCollection);
1062 }
1063 
1064 template <class T>
createInstance(Context & context) const1065 vkt::TestInstance* CalibratedTimestampTest<T>::createInstance (Context& context) const
1066 {
1067 	return new T{context};
1068 }
1069 
1070 template <class T>
checkSupport(Context & context) const1071 void CalibratedTimestampTest<T>::checkSupport (Context& context) const
1072 {
1073 	context.requireDeviceFunctionality("VK_EXT_calibrated_timestamps");
1074 }
1075 
CalibratedTimestampTestInstance(Context & context)1076 CalibratedTimestampTestInstance::CalibratedTimestampTestInstance (Context& context)
1077 	: TestInstance{context}
1078 {
1079 #if (DE_OS == DE_OS_WIN32)
1080 	LARGE_INTEGER freq;
1081 	if (!QueryPerformanceFrequency(&freq))
1082 	{
1083 		throw tcu::ResourceError("Unable to get clock frequency with QueryPerformanceFrequency");
1084 	}
1085 	if (freq.QuadPart <= 0)
1086 	{
1087 		throw tcu::ResourceError("QueryPerformanceFrequency did not return a positive number");
1088 	}
1089 	m_frequency = static_cast<deUint64>(freq.QuadPart);
1090 #endif
1091 
1092 	const InstanceInterface&	vki					= context.getInstanceInterface();
1093 	const VkPhysicalDevice		physDevice			= context.getPhysicalDevice();
1094 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1095 
1096 	// Get timestamp mask.
1097 	m_devTimestampMask = checkTimestampsSupported(context);
1098 
1099 	// Get calibreatable time domains.
1100 	m_timestampPeriod = getPhysicalDeviceProperties(vki, physDevice).limits.timestampPeriod;
1101 
1102 	deUint32 domainCount;
1103 	VK_CHECK(vki.getPhysicalDeviceCalibrateableTimeDomainsEXT(physDevice, &domainCount, DE_NULL));
1104 	if (domainCount == 0)
1105 	{
1106 		throw tcu::NotSupportedError("No calibrateable time domains found");
1107 	}
1108 
1109 	std::vector<VkTimeDomainEXT> domains;
1110 	domains.resize(domainCount);
1111 	VK_CHECK(vki.getPhysicalDeviceCalibrateableTimeDomainsEXT(physDevice, &domainCount, domains.data()));
1112 
1113 	// Find the dev domain.
1114 	std::vector<VkTimeDomainEXT> preferredDevDomains;
1115 	preferredDevDomains.push_back(VK_TIME_DOMAIN_DEVICE_EXT);
1116 	m_devDomains = getDomainSubset(domains, preferredDevDomains);
1117 
1118 	// Find the host domain.
1119 	std::vector<VkTimeDomainEXT> preferredHostDomains;
1120 #if (DE_OS == DE_OS_WIN32)
1121 	preferredHostDomains.push_back(VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT);
1122 #else
1123 	preferredHostDomains.push_back(VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT);
1124 	preferredHostDomains.push_back(VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT);
1125 #endif
1126 	m_hostDomains = getDomainSubset(domains, preferredHostDomains);
1127 
1128 	// Initialize command buffers and queries.
1129 	const DeviceInterface&		vk				= context.getDeviceInterface();
1130 	const VkDevice				vkDevice		= context.getDevice();
1131 
1132 	const VkQueryPoolCreateInfo	queryPoolParams	=
1133 	{
1134 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
1135 		DE_NULL,									// const void*                   pNext;
1136 		0u,											// VkQueryPoolCreateFlags        flags;
1137 		VK_QUERY_TYPE_TIMESTAMP,					// VkQueryType                   queryType;
1138 		1u,											// deUint32                      entryCount;
1139 		0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
1140 	};
1141 
1142 	m_queryPool	= createQueryPool(vk, vkDevice, &queryPoolParams);
1143 	m_cmdPool	= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1144 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1145 
1146 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1147 	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
1148 	vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
1149 	endCommandBuffer(vk, *m_cmdBuffer);
1150 }
1151 
getDomainSubset(const std::vector<VkTimeDomainEXT> & available,const std::vector<VkTimeDomainEXT> & interesting) const1152 std::vector<VkTimeDomainEXT> CalibratedTimestampTestInstance::getDomainSubset (const std::vector<VkTimeDomainEXT>& available, const std::vector<VkTimeDomainEXT>& interesting) const
1153 {
1154 	const std::set<VkTimeDomainEXT> availableSet	(begin(available),		end(available));
1155 	const std::set<VkTimeDomainEXT> interestingSet	(begin(interesting),	end(interesting));
1156 
1157 	std::vector<VkTimeDomainEXT> subset;
1158 	std::set_intersection(begin(availableSet), end(availableSet), begin(interestingSet), end(interestingSet), std::back_inserter(subset));
1159 	return subset;
1160 }
1161 
domainName(VkTimeDomainEXT domain) const1162 std::string CalibratedTimestampTestInstance::domainName(VkTimeDomainEXT domain) const
1163 {
1164 	switch (domain)
1165 	{
1166 	case VK_TIME_DOMAIN_DEVICE_EXT:						return "Device Domain";
1167 	case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:			return "Monotonic Clock";
1168 	case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:		return "Raw Monotonic Clock";
1169 	case VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT:	return "Query Performance Counter";
1170 	default:											DE_ASSERT(DE_FALSE); return "Unknown Time Domain";
1171 	}
1172 }
1173 
getHostNativeTimestamp(VkTimeDomainEXT hostDomain) const1174 deUint64 CalibratedTimestampTestInstance::getHostNativeTimestamp (VkTimeDomainEXT hostDomain) const
1175 {
1176 #if (DE_OS == DE_OS_WIN32)
1177 	DE_ASSERT(hostDomain == VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT);
1178 	LARGE_INTEGER result;
1179 	if (!QueryPerformanceCounter(&result))
1180 	{
1181 		throw tcu::ResourceError("Unable to obtain host native timestamp for Win32");
1182 	}
1183 	if (result.QuadPart < 0)
1184 	{
1185 		throw tcu::ResourceError("Host-native timestamp for Win32 less than zero");
1186 	}
1187 	return static_cast<deUint64>(result.QuadPart);
1188 #else
1189 	DE_ASSERT(hostDomain == VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT ||
1190 			  hostDomain == VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT);
1191 
1192 #if defined(CLOCK_MONOTONIC_RAW)
1193 	clockid_t id = ((hostDomain == VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT) ? CLOCK_MONOTONIC : CLOCK_MONOTONIC_RAW);
1194 #else
1195 	clockid_t id = CLOCK_MONOTONIC;
1196 #endif
1197 	struct timespec ts;
1198 	if (clock_gettime(id, &ts) != 0)
1199 	{
1200 		throw tcu::ResourceError("Unable to obtain host native timestamp for POSIX");
1201 	}
1202 	return (static_cast<deUint64>(ts.tv_sec) * 1000000000ULL + ts.tv_nsec);
1203 #endif
1204 }
1205 
getHostNanoseconds(deUint64 hostTimestamp) const1206 deUint64 CalibratedTimestampTestInstance::getHostNanoseconds (deUint64 hostTimestamp) const
1207 {
1208 #if (DE_OS == DE_OS_WIN32)
1209 	deUint64	secs	= hostTimestamp / m_frequency;
1210 	deUint64	nanos	= ((hostTimestamp % m_frequency) * kNanosecondsPerSecond) / m_frequency;
1211 
1212 	return ((secs * kNanosecondsPerSecond) + nanos);
1213 #else
1214 	return hostTimestamp;
1215 #endif
1216 }
1217 
1218 // This method will be used when devTicksDelta is (supposedly) a small amount of ticks between two events. We will check
1219 // devTicksDelta is reasonably small for the calculation below to succeed without losing precision.
getDeviceNanoseconds(deUint64 devTicksDelta) const1220 deUint64 CalibratedTimestampTestInstance::getDeviceNanoseconds (deUint64 devTicksDelta) const
1221 {
1222 	if (devTicksDelta > static_cast<deUint64>(std::numeric_limits<deUint32>::max()))
1223 	{
1224 		std::ostringstream msg;
1225 		msg << "Number of device ticks too big for conversion to nanoseconds: " << devTicksDelta;
1226 		throw tcu::InternalError(msg.str());
1227 	}
1228 	return static_cast<deUint64>(static_cast<double>(devTicksDelta) * m_timestampPeriod);
1229 }
1230 
iterate(void)1231 tcu::TestStatus CalibratedTimestampTestInstance::iterate (void)
1232 {
1233 	// Notes:
1234 	//	1) Clocks may overflow.
1235 	//	2) Because m_timestampPeriod is a floating point value, there may be less than one nano per tick.
1236 
1237 	const tcu::TestStatus result = runTest();
1238 	if (result.getCode() != QP_TEST_RESULT_PASS)
1239 		return result;
1240 
1241 	if (!m_qualityMessage.empty())
1242 	{
1243 		const std::string msg = "Warnings found: " + m_qualityMessage;
1244 		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, msg);
1245 	}
1246 	return tcu::TestStatus::pass("Pass");
1247 }
1248 
1249 // Verify all invalid timestamp bits are zero.
verifyDevTimestampMask(deUint64 value) const1250 void CalibratedTimestampTestInstance::verifyDevTimestampMask (deUint64 value) const
1251 {
1252 	checkTimestampBits(value, m_devTimestampMask);
1253 }
1254 
1255 // Absolute difference between two timestamps A and B taking overflow into account. Pick the smallest difference between the two
1256 // possibilities. We don't know beforehand if B > A or vice versa. Take the valid bit mask into account.
absDiffWithOverflow(deUint64 a,deUint64 b,deUint64 mask) const1257 deUint64 CalibratedTimestampTestInstance::absDiffWithOverflow (deUint64 a, deUint64 b, deUint64 mask) const
1258 {
1259 	//	<---------+ range +-------->
1260 	//
1261 	//	+--------------------------+
1262 	//	|         deUint64         |
1263 	//	+------^-----------^-------+
1264 	//	       +           +
1265 	//	       a           b
1266 	//	       +----------->
1267 	//	       ccccccccccccc
1268 	//	------>             +-------
1269 	//	ddddddd             dddddddd
1270 
1271 	DE_ASSERT(a <= mask);
1272 	DE_ASSERT(b <= mask);
1273 
1274 	const deUint64 c = ((a >= b) ? (a - b) : (b - a));
1275 
1276 	if (c == 0u)
1277 		return c;
1278 
1279 	const deUint64 d = (mask - c) + 1;
1280 
1281 	return ((c < d) ? c : d);
1282 }
1283 
1284 // Positive difference between both marks, advancing from before to after, taking overflow and the valid bit mask into account.
positiveDiffWithOverflow(deUint64 before,deUint64 after,deUint64 mask) const1285 deUint64 CalibratedTimestampTestInstance::positiveDiffWithOverflow (deUint64 before, deUint64 after, deUint64 mask) const
1286 {
1287 	DE_ASSERT(before <= mask);
1288 	DE_ASSERT(after  <= mask);
1289 
1290 	return ((before <= after) ? (after - before) : ((mask - (before - after)) + 1));
1291 }
1292 
1293 // Return true if middle is not between begin and end, taking overflow into account.
outOfRange(deUint64 begin,deUint64 middle,deUint64 end) const1294 bool CalibratedTimestampTestInstance::outOfRange (deUint64 begin, deUint64 middle, deUint64 end) const
1295 {
1296 	return (((begin <= end) && (middle < begin || middle > end	)) ||
1297 			((begin >  end) && (middle > end   && middle < begin)));
1298 }
1299 
getCalibratedTimestamps(const std::vector<VkTimeDomainEXT> & domains)1300 std::vector<CalibratedTimestampTestInstance::CalibratedTimestamp> CalibratedTimestampTestInstance::getCalibratedTimestamps (const std::vector<VkTimeDomainEXT>& domains)
1301 {
1302 	std::vector<VkCalibratedTimestampInfoEXT> infos;
1303 
1304 	for (auto domain : domains)
1305 	{
1306 		VkCalibratedTimestampInfoEXT info;
1307 		info.sType = getStructureType<VkCalibratedTimestampInfoEXT>();
1308 		info.pNext = DE_NULL;
1309 		info.timeDomain = domain;
1310 		infos.push_back(info);
1311 	}
1312 
1313 	std::vector<deUint64> timestamps(domains.size());
1314 	deUint64			  deviation;
1315 
1316 	const DeviceInterface&      vk          = m_context.getDeviceInterface();
1317 	const VkDevice              vkDevice    = m_context.getDevice();
1318 
1319 	VK_CHECK(vk.getCalibratedTimestampsEXT(vkDevice, static_cast<deUint32>(domains.size()), infos.data(), timestamps.data(), &deviation));
1320 
1321 	if (deviation > kDeviationErrorLimitNanos)
1322 	{
1323 		throw tcu::InternalError("Calibrated maximum deviation too big");
1324 	}
1325 	else if (deviation > kDeviationWarningLimitNanos)
1326 	{
1327 		appendQualityMessage("Calibrated maximum deviation beyond desirable limits");
1328 	}
1329 	else if (deviation == 0 && domains.size() > 1)
1330 	{
1331 		appendQualityMessage("Calibrated maximum deviation reported as zero");
1332 	}
1333 
1334 	// Pack results.
1335 	std::vector<CalibratedTimestamp> results;
1336 
1337 	for (size_t i = 0; i < domains.size(); ++i)
1338 	{
1339 		if (domains[i] == VK_TIME_DOMAIN_DEVICE_EXT)
1340 			verifyDevTimestampMask(timestamps[i]);
1341 		results.emplace_back(timestamps[i], deviation);
1342 	}
1343 
1344 	return results;
1345 }
1346 
getCalibratedTimestamp(VkTimeDomainEXT domain)1347 CalibratedTimestampTestInstance::CalibratedTimestamp CalibratedTimestampTestInstance::getCalibratedTimestamp (VkTimeDomainEXT domain)
1348 {
1349 	// Single domain, single result.
1350 	return getCalibratedTimestamps(std::vector<VkTimeDomainEXT>(1, domain))[0];
1351 }
1352 
appendQualityMessage(const std::string & message)1353 void CalibratedTimestampTestInstance::appendQualityMessage (const std::string& message)
1354 {
1355 	if (!m_qualityMessage.empty())
1356 		m_qualityMessage += "; ";
1357 
1358 	m_qualityMessage += message;
1359 }
1360 
1361 // Test device domain makes sense and is consistent with vkCmdWriteTimestamp().
runTest(void)1362 tcu::TestStatus CalibratedTimestampDevDomainTestInstance::runTest (void)
1363 {
1364 	if (m_devDomains.empty())
1365 		throw tcu::NotSupportedError("No suitable device time domains found");
1366 
1367 	const DeviceInterface&      vk          = m_context.getDeviceInterface();
1368 	const VkDevice              vkDevice    = m_context.getDevice();
1369 	const VkQueue               queue       = m_context.getUniversalQueue();
1370 
1371 	for (const auto devDomain : m_devDomains)
1372 	{
1373 		const CalibratedTimestamp	before		= getCalibratedTimestamp(devDomain);
1374 		submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1375 		const CalibratedTimestamp	after		= getCalibratedTimestamp(devDomain);
1376 		const deUint64				diffNanos	= getDeviceNanoseconds(positiveDiffWithOverflow(before.timestamp, after.timestamp, m_devTimestampMask));
1377 		deUint64					written;
1378 		VK_CHECK(vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, 1u, sizeof(written), &written, sizeof(written), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)));
1379 		verifyDevTimestampMask(written);
1380 
1381 		if (diffNanos > kBatchTimeLimitNanos)
1382 		{
1383 			return tcu::TestStatus::fail(domainName(devDomain) + ": Batch of work took too long to execute");
1384 		}
1385 
1386 		if (outOfRange(before.timestamp, written, after.timestamp))
1387 		{
1388 			return tcu::TestStatus::fail(domainName(devDomain) + ": vkCmdWriteTimestamp() inconsistent with vkGetCalibratedTimestampsEXT()");
1389 		}
1390 	}
1391 
1392 	return tcu::TestStatus::pass("Pass");
1393 }
1394 
1395 // Test host domain makes sense and is consistent with native host values.
runTest(void)1396 tcu::TestStatus CalibratedTimestampHostDomainTestInstance::runTest (void)
1397 {
1398 	if (m_hostDomains.empty())
1399 		throw tcu::NotSupportedError("No suitable host time domains found");
1400 
1401 	for (const auto hostDomain : m_hostDomains)
1402 	{
1403 		const deUint64				before		= getHostNativeTimestamp(hostDomain);
1404 		const CalibratedTimestamp	vkTS		= getCalibratedTimestamp(hostDomain);
1405 		const deUint64				after		= getHostNativeTimestamp(hostDomain);
1406 		const deUint64				diffNanos	= getHostNanoseconds(positiveDiffWithOverflow(before, after));
1407 
1408 		if (diffNanos > kBatchTimeLimitNanos)
1409 		{
1410 			return tcu::TestStatus::fail(domainName(hostDomain) + ": Querying host domain took too long to execute");
1411 		}
1412 
1413 		if (outOfRange(before, vkTS.timestamp, after))
1414 		{
1415 			return tcu::TestStatus::fail(domainName(hostDomain) + ": vkGetCalibratedTimestampsEXT() inconsistent with native host API");
1416 		}
1417 	}
1418 
1419 	return tcu::TestStatus::pass("Pass");
1420 }
1421 
1422 // Verify predictable timestamps and calibration possible.
runTest(void)1423 tcu::TestStatus CalibratedTimestampCalibrationTestInstance::runTest (void)
1424 {
1425 	if (m_devDomains.empty())
1426 		throw tcu::NotSupportedError("No suitable device time domains found");
1427 	if (m_hostDomains.empty())
1428 		throw tcu::NotSupportedError("No suitable host time domains found");
1429 
1430 	// Sleep time.
1431 	constexpr deUint32	kSleepMilliseconds	= 200;
1432 	constexpr deUint32	kSleepNanoseconds	= kSleepMilliseconds * kNanosecondsPerMillisecond;
1433 
1434 	for (const auto devDomain	: m_devDomains)
1435 	for (const auto hostDomain	: m_hostDomains)
1436 	{
1437 		std::vector<VkTimeDomainEXT>	domains;
1438 		domains.push_back(devDomain);	// Device results at index 0.
1439 		domains.push_back(hostDomain);	// Host results at index 1.
1440 
1441 		// Measure time.
1442 		const std::vector<CalibratedTimestamp> before	= getCalibratedTimestamps(domains);
1443 		std::this_thread::sleep_for(std::chrono::nanoseconds(kSleepNanoseconds));
1444 		const std::vector<CalibratedTimestamp> after	= getCalibratedTimestamps(domains);
1445 
1446 		// Check device timestamp is as expected.
1447 		const deUint64 devBeforeTicks	= before[0].timestamp;
1448 		const deUint64 devAfterTicks	= after[0].timestamp;
1449 		const deUint64 devExpectedTicks	= ((devBeforeTicks + static_cast<deUint64>(static_cast<double>(kSleepNanoseconds) / m_timestampPeriod)) & m_devTimestampMask);
1450 		const deUint64 devDiffNanos		= getDeviceNanoseconds(absDiffWithOverflow(devAfterTicks, devExpectedTicks, m_devTimestampMask));
1451 		const deUint64 maxDevDiffNanos	= std::max({ kDefaultToleranceNanos, before[0].deviation + after[0].deviation });
1452 
1453 		if (devDiffNanos > maxDevDiffNanos)
1454 		{
1455 			std::ostringstream msg;
1456 			msg << "[" << domainName(devDomain) << "] Device expected timestamp differs " << devDiffNanos << " nanoseconds (expect value <= " << maxDevDiffNanos << ")";
1457 			return tcu::TestStatus::fail(msg.str());
1458 		}
1459 
1460 		// Check host timestamp is as expected.
1461 		const deUint64 hostBefore		= getHostNanoseconds(before[1].timestamp);
1462 		const deUint64 hostAfter		= getHostNanoseconds(after[1].timestamp);
1463 		const deUint64 hostExpected		= hostBefore + kSleepNanoseconds;
1464 		const deUint64 hostDiff			= absDiffWithOverflow(hostAfter, hostExpected);
1465 		const deUint64 maxHostDiff		= std::max({ kDefaultToleranceNanos, before[1].deviation + after[1].deviation });
1466 
1467 		if (hostDiff > maxHostDiff)
1468 		{
1469 			std::ostringstream msg;
1470 			msg << "[" << domainName(hostDomain) << "] Host expected timestamp differs " << hostDiff << " nanoseconds (expected value <= " << maxHostDiff << ")";
1471 			return tcu::TestStatus::fail(msg.str());
1472 		}
1473 	}
1474 
1475 	return tcu::TestStatus::pass("Pass");
1476 }
1477 
1478 class BasicGraphicsTest : public TimestampTest
1479 {
1480 public:
BasicGraphicsTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)1481 							BasicGraphicsTest	(tcu::TestContext&			testContext,
1482 												 const std::string&			name,
1483 												 const std::string&			description,
1484 												 const TimestampTestParam*	param)
1485 							: TimestampTest (testContext, name, description, param)
1486 { }
~BasicGraphicsTest(void)1487 	virtual					~BasicGraphicsTest	(void) { }
1488 	virtual void			initPrograms		(SourceCollections& programCollection) const;
1489 	virtual TestInstance*	createInstance		(Context& context) const;
1490 };
1491 
1492 class BasicGraphicsTestInstance : public TimestampTestInstance
1493 {
1494 public:
1495 	enum
1496 	{
1497 		VK_MAX_SHADER_STAGES = 6,
1498 	};
1499 					BasicGraphicsTestInstance	(Context&				context,
1500 												 const StageFlagVector	stages,
1501 												 const bool				inRenderPass,
1502 												 const bool				hostQueryReset);
1503 
1504 	virtual			~BasicGraphicsTestInstance	(void);
1505 protected:
1506 	virtual void	configCommandBuffer			(void);
1507 	virtual void	buildVertexBuffer			(void);
1508 	virtual void	buildRenderPass				(VkFormat	colorFormat,
1509 												 VkFormat	depthFormat);
1510 
1511 	virtual void	buildFrameBuffer			(tcu::UVec2	renderSize,
1512 												 VkFormat	colorFormat,
1513 												 VkFormat	depthFormat);
1514 
1515 protected:
1516 	const tcu::UVec2				m_renderSize;
1517 	const VkFormat					m_colorFormat;
1518 	const VkFormat					m_depthFormat;
1519 
1520 	Move<VkImage>					m_colorImage;
1521 	de::MovePtr<Allocation>			m_colorImageAlloc;
1522 	Move<VkImage>					m_depthImage;
1523 	de::MovePtr<Allocation>			m_depthImageAlloc;
1524 	Move<VkImageView>				m_colorAttachmentView;
1525 	Move<VkImageView>				m_depthAttachmentView;
1526 	Move<VkRenderPass>				m_renderPass;
1527 	Move<VkFramebuffer>				m_framebuffer;
1528 	VkImageMemoryBarrier			m_imageLayoutBarriers[2];
1529 
1530 	de::MovePtr<Allocation>			m_vertexBufferAlloc;
1531 	Move<VkBuffer>					m_vertexBuffer;
1532 	std::vector<Vertex4RGBA>		m_vertices;
1533 
1534 	SimpleGraphicsPipelineBuilder	m_pipelineBuilder;
1535 	Move<VkPipeline>				m_graphicsPipelines;
1536 };
1537 
initPrograms(SourceCollections & programCollection) const1538 void BasicGraphicsTest::initPrograms (SourceCollections& programCollection) const
1539 {
1540 	programCollection.glslSources.add("color_vert") << glu::VertexSource(
1541 		"#version 310 es\n"
1542 		"layout(location = 0) in vec4 position;\n"
1543 		"layout(location = 1) in vec4 color;\n"
1544 		"layout(location = 0) out highp vec4 vtxColor;\n"
1545 		"void main (void)\n"
1546 		"{\n"
1547 		"  gl_Position = position;\n"
1548 		"  vtxColor = color;\n"
1549 		"}\n");
1550 
1551 	programCollection.glslSources.add("color_frag") << glu::FragmentSource(
1552 		"#version 310 es\n"
1553 		"layout(location = 0) in highp vec4 vtxColor;\n"
1554 		"layout(location = 0) out highp vec4 fragColor;\n"
1555 		"void main (void)\n"
1556 		"{\n"
1557 		"  fragColor = vtxColor;\n"
1558 		"}\n");
1559 }
1560 
createInstance(Context & context) const1561 TestInstance* BasicGraphicsTest::createInstance (Context& context) const
1562 {
1563 	return new BasicGraphicsTestInstance(context,m_stages,m_inRenderPass,m_hostQueryReset);
1564 }
1565 
buildVertexBuffer(void)1566 void BasicGraphicsTestInstance::buildVertexBuffer (void)
1567 {
1568 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
1569 	const VkDevice			vkDevice	= m_context.getDevice();
1570 
1571 	// Create vertex buffer
1572 	{
1573 		m_vertexBuffer	= createBufferAndBindMemory(1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferAlloc);
1574 		m_vertices		= createOverlappingQuads();
1575 
1576 		// Load vertices into vertex buffer
1577 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1578 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1579 	}
1580 }
1581 
buildRenderPass(VkFormat colorFormat,VkFormat depthFormat)1582 void BasicGraphicsTestInstance::buildRenderPass (VkFormat colorFormat, VkFormat depthFormat)
1583 {
1584 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
1585 	const VkDevice			vkDevice	= m_context.getDevice();
1586 
1587 	// Create render pass
1588 	m_renderPass = makeRenderPass(vk, vkDevice, colorFormat, depthFormat);
1589 }
1590 
buildFrameBuffer(tcu::UVec2 renderSize,VkFormat colorFormat,VkFormat depthFormat)1591 void BasicGraphicsTestInstance::buildFrameBuffer (tcu::UVec2 renderSize, VkFormat colorFormat, VkFormat depthFormat)
1592 {
1593 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
1594 	const VkDevice				vkDevice				= m_context.getDevice();
1595 	const VkComponentMapping	ComponentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
1596 
1597 	// Create color image
1598 	{
1599 		m_colorImage = createImage2DAndBindMemory(colorFormat,
1600 												  renderSize.x(),
1601 												  renderSize.y(),
1602 												  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1603 												  VK_SAMPLE_COUNT_1_BIT,
1604 												  &m_colorImageAlloc);
1605 	}
1606 
1607 	// Create depth image
1608 	{
1609 		m_depthImage = createImage2DAndBindMemory(depthFormat,
1610 												  renderSize.x(),
1611 												  renderSize.y(),
1612 												  VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1613 												  VK_SAMPLE_COUNT_1_BIT,
1614 												  &m_depthImageAlloc);
1615 	}
1616 
1617 	// Set up image layout transition barriers
1618 	{
1619 		const VkImageMemoryBarrier colorImageBarrier =
1620 		{
1621 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
1622 			DE_NULL,											// const void*				pNext;
1623 			0u,													// VkAccessFlags			srcAccessMask;
1624 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1625 			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
1626 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout			newLayout;
1627 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
1628 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
1629 			*m_colorImage,										// VkImage					image;
1630 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },		// VkImageSubresourceRange	subresourceRange;
1631 		};
1632 		const VkImageMemoryBarrier depthImageBarrier =
1633 		{
1634 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
1635 			DE_NULL,											// const void*				pNext;
1636 			0u,													// VkAccessFlags			srcAccessMask;
1637 			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
1638 			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
1639 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
1640 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
1641 			VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
1642 			*m_depthImage,										// VkImage					image;
1643 			{ VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u },		// VkImageSubresourceRange	subresourceRange;
1644 		};
1645 
1646 		m_imageLayoutBarriers[0] = colorImageBarrier;
1647 		m_imageLayoutBarriers[1] = depthImageBarrier;
1648 	}
1649 
1650 	// Create color attachment view
1651 	{
1652 		const VkImageViewCreateInfo colorAttachmentViewParams =
1653 		{
1654 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType          sType;
1655 			DE_NULL,										// const void*              pNext;
1656 			0u,												// VkImageViewCreateFlags   flags;
1657 			*m_colorImage,									// VkImage                  image;
1658 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType          viewType;
1659 			colorFormat,									// VkFormat                 format;
1660 			ComponentMappingRGBA,							// VkComponentMapping       components;
1661 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange  subresourceRange;
1662 		};
1663 
1664 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
1665 	}
1666 
1667 	// Create depth attachment view
1668 	{
1669 		const VkImageViewCreateInfo depthAttachmentViewParams =
1670 		{
1671 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType          sType;
1672 			DE_NULL,										// const void*              pNext;
1673 			0u,												// VkImageViewCreateFlags   flags;
1674 			*m_depthImage,									// VkImage                  image;
1675 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType          viewType;
1676 			depthFormat,									// VkFormat                 format;
1677 			ComponentMappingRGBA,							// VkComponentMapping       components;
1678 			{ VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange  subresourceRange;
1679 		};
1680 
1681 		m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
1682 	}
1683 
1684 	// Create framebuffer
1685 	{
1686 		const VkImageView attachmentBindInfos[2] =
1687 		{
1688 			*m_colorAttachmentView,
1689 			*m_depthAttachmentView,
1690 		};
1691 
1692 		const VkFramebufferCreateInfo framebufferParams =
1693 		{
1694 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType              sType;
1695 			DE_NULL,									// const void*                  pNext;
1696 			0u,											// VkFramebufferCreateFlags     flags;
1697 			*m_renderPass,								// VkRenderPass                 renderPass;
1698 			2u,											// deUint32                     attachmentCount;
1699 			attachmentBindInfos,						// const VkImageView*           pAttachments;
1700 			(deUint32)renderSize.x(),					// deUint32                     width;
1701 			(deUint32)renderSize.y(),					// deUint32                     height;
1702 			1u,											// deUint32                     layers;
1703 		};
1704 
1705 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1706 	}
1707 
1708 }
1709 
BasicGraphicsTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass,const bool hostQueryReset)1710 BasicGraphicsTestInstance::BasicGraphicsTestInstance (Context&				context,
1711 													  const StageFlagVector	stages,
1712 													  const bool			inRenderPass,
1713 													  const bool			hostQueryReset)
1714 													  : TimestampTestInstance (context,stages,inRenderPass, hostQueryReset)
1715 													  , m_renderSize		(32, 32)
1716 													  , m_colorFormat		(VK_FORMAT_R8G8B8A8_UNORM)
1717 													  , m_depthFormat		(VK_FORMAT_D16_UNORM)
1718 													  , m_pipelineBuilder	(context)
1719 {
1720 	buildVertexBuffer();
1721 
1722 	buildRenderPass(m_colorFormat, m_depthFormat);
1723 
1724 	buildFrameBuffer(m_renderSize, m_colorFormat, m_depthFormat);
1725 
1726 	m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert");
1727 	m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag");
1728 
1729 	m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1730 
1731 }
1732 
~BasicGraphicsTestInstance(void)1733 BasicGraphicsTestInstance::~BasicGraphicsTestInstance (void)
1734 {
1735 }
1736 
configCommandBuffer(void)1737 void BasicGraphicsTestInstance::configCommandBuffer (void)
1738 {
1739 	const DeviceInterface&		vk							= m_context.getDeviceInterface();
1740 
1741 	const VkClearValue			attachmentClearValues[2]	=
1742 	{
1743 		defaultClearValue(m_colorFormat),
1744 		defaultClearValue(m_depthFormat),
1745 	};
1746 
1747 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1748 
1749 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1750 		0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
1751 
1752 	if (!m_hostQueryReset)
1753 		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1754 
1755 	beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
1756 
1757 	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1758 	VkDeviceSize offsets = 0u;
1759 	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1760 	vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
1761 
1762 	if(m_inRenderPass)
1763 	{
1764 	  deUint32 timestampEntry = 0u;
1765 
1766 	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1767 	  {
1768 		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1769 	  }
1770 	}
1771 
1772 	endRenderPass(vk, *m_cmdBuffer);
1773 
1774 	if(!m_inRenderPass)
1775 	{
1776 	  deUint32 timestampEntry = 0u;
1777 
1778 	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1779 	  {
1780 		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1781 	  }
1782 	}
1783 
1784 	endCommandBuffer(vk, *m_cmdBuffer);
1785 }
1786 
1787 class AdvGraphicsTest : public BasicGraphicsTest
1788 {
1789 public:
AdvGraphicsTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)1790 						  AdvGraphicsTest	(tcu::TestContext&			testContext,
1791 											 const std::string&			name,
1792 											 const std::string&			description,
1793 											 const TimestampTestParam*	param)
1794 							  : BasicGraphicsTest(testContext, name, description, param)
1795 							  { }
1796 
~AdvGraphicsTest(void)1797 	virtual               ~AdvGraphicsTest (void) { }
1798 	virtual void          initPrograms     (SourceCollections& programCollection) const;
1799 	virtual TestInstance* createInstance   (Context& context) const;
1800 };
1801 
1802 class AdvGraphicsTestInstance : public BasicGraphicsTestInstance
1803 {
1804 public:
1805 				 AdvGraphicsTestInstance	(Context&				context,
1806 											 const StageFlagVector	stages,
1807 											 const bool				inRenderPass,
1808 											 const bool				hostQueryReset);
1809 
1810 	virtual      ~AdvGraphicsTestInstance	(void);
1811 	virtual void configCommandBuffer		(void);
1812 
1813 protected:
1814 	virtual void featureSupportCheck		(void);
1815 
1816 protected:
1817 	VkPhysicalDeviceFeatures	m_features;
1818 	deUint32					m_draw_count;
1819 	de::MovePtr<Allocation>		m_indirectBufferAlloc;
1820 	Move<VkBuffer>				m_indirectBuffer;
1821 };
1822 
initPrograms(SourceCollections & programCollection) const1823 void AdvGraphicsTest::initPrograms (SourceCollections& programCollection) const
1824 {
1825 	BasicGraphicsTest::initPrograms(programCollection);
1826 
1827 	programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
1828 		"#version 310 es\n"
1829 		"#extension GL_EXT_geometry_shader : enable\n"
1830 		"layout(triangles) in;\n"
1831 		"layout(triangle_strip, max_vertices = 3) out;\n"
1832 		"layout(location = 0) in highp vec4 in_vtxColor[];\n"
1833 		"layout(location = 0) out highp vec4 vtxColor;\n"
1834 		"void main (void)\n"
1835 		"{\n"
1836 		"  for(int ndx=0; ndx<3; ndx++)\n"
1837 		"  {\n"
1838 		"    gl_Position = gl_in[ndx].gl_Position;\n"
1839 		"    vtxColor    = in_vtxColor[ndx];\n"
1840 		"    EmitVertex();\n"
1841 		"  }\n"
1842 		"  EndPrimitive();\n"
1843 		"}\n");
1844 
1845 	programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
1846 		"#version 310 es\n"
1847 		"#extension GL_EXT_tessellation_shader : enable\n"
1848 		"layout(vertices = 3) out;\n"
1849 		"layout(location = 0) in highp vec4 color[];\n"
1850 		"layout(location = 0) out highp vec4 vtxColor[];\n"
1851 		"void main()\n"
1852 		"{\n"
1853 		"  gl_TessLevelOuter[0] = 4.0;\n"
1854 		"  gl_TessLevelOuter[1] = 4.0;\n"
1855 		"  gl_TessLevelOuter[2] = 4.0;\n"
1856 		"  gl_TessLevelInner[0] = 4.0;\n"
1857 		"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1858 		"  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
1859 		"}\n");
1860 
1861 	programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
1862 		"#version 310 es\n"
1863 		"#extension GL_EXT_tessellation_shader : enable\n"
1864 		"layout(triangles, fractional_even_spacing, ccw) in;\n"
1865 		"layout(location = 0) in highp vec4 colors[];\n"
1866 		"layout(location = 0) out highp vec4 vtxColor;\n"
1867 		"void main() \n"
1868 		"{\n"
1869 		"  float u = gl_TessCoord.x;\n"
1870 		"  float v = gl_TessCoord.y;\n"
1871 		"  float w = gl_TessCoord.z;\n"
1872 		"  vec4 pos = vec4(0);\n"
1873 		"  vec4 color = vec4(0);\n"
1874 		"  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
1875 		"  color.xyz += u * colors[0].xyz;\n"
1876 		"  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
1877 		"  color.xyz += v * colors[1].xyz;\n"
1878 		"  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
1879 		"  color.xyz += w * colors[2].xyz;\n"
1880 		"  pos.w = 1.0;\n"
1881 		"  color.w = 1.0;\n"
1882 		"  gl_Position = pos;\n"
1883 		"  vtxColor = color;\n"
1884 		"}\n");
1885 }
1886 
createInstance(Context & context) const1887 TestInstance* AdvGraphicsTest::createInstance (Context& context) const
1888 {
1889 	return new AdvGraphicsTestInstance(context,m_stages,m_inRenderPass,m_hostQueryReset);
1890 }
1891 
featureSupportCheck(void)1892 void AdvGraphicsTestInstance::featureSupportCheck (void)
1893 {
1894 	for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1895 	{
1896 		switch(*it)
1897 		{
1898 			case VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT:
1899 				if (m_features.geometryShader == VK_FALSE)
1900 				{
1901 					TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1902 				}
1903 				break;
1904 			case VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT:
1905 			case VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT:
1906 				if (m_features.tessellationShader == VK_FALSE)
1907 				{
1908 					TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1909 				}
1910 				break;
1911 			case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
1912 			default:
1913 				break;
1914 		};
1915 	}
1916 }
1917 
AdvGraphicsTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass,const bool hostQueryReset)1918 AdvGraphicsTestInstance::AdvGraphicsTestInstance (Context&				context,
1919 												  const StageFlagVector	stages,
1920 												  const bool			inRenderPass,
1921 												  const bool			hostQueryReset)
1922 	: BasicGraphicsTestInstance(context, stages, inRenderPass, hostQueryReset)
1923 {
1924 	m_features = m_context.getDeviceFeatures();
1925 
1926 	// If necessary feature is not supported, throw error and fail current test
1927 	featureSupportCheck();
1928 
1929 	if(m_features.geometryShader == VK_TRUE)
1930 	{
1931 		m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo");
1932 	}
1933 
1934 	if(m_features.tessellationShader == VK_TRUE)
1935 	{
1936 		m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs");
1937 		m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes");
1938 		m_pipelineBuilder.enableTessellationStage(3);
1939 	}
1940 
1941 	m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1942 
1943 	// Prepare the indirect draw buffer
1944 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
1945 	const VkDevice			vkDevice	= m_context.getDevice();
1946 
1947 	if(m_features.multiDrawIndirect == VK_TRUE)
1948 	{
1949 		m_draw_count = 2;
1950 	}
1951 	else
1952 	{
1953 		m_draw_count = 1;
1954 	}
1955 
1956 	m_indirectBuffer = createBufferAndBindMemory(32u, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, &m_indirectBufferAlloc);
1957 
1958 	const VkDrawIndirectCommand indirectCmds[] =
1959 	{
1960 		{
1961 			12u,	// deUint32    vertexCount;
1962 			1u,		// deUint32    instanceCount;
1963 			0u,		// deUint32    firstVertex;
1964 			0u,		// deUint32    firstInstance;
1965 		},
1966 		{
1967 			12u,	// deUint32    vertexCount;
1968 			1u,		// deUint32    instanceCount;
1969 			11u,	// deUint32    firstVertex;
1970 			0u,		// deUint32    firstInstance;
1971 		},
1972 	};
1973 
1974 	// Load data into indirect draw buffer
1975 	deMemcpy(m_indirectBufferAlloc->getHostPtr(), indirectCmds, m_draw_count * sizeof(VkDrawIndirectCommand));
1976 	flushAlloc(vk, vkDevice, *m_indirectBufferAlloc);
1977 
1978 }
1979 
~AdvGraphicsTestInstance(void)1980 AdvGraphicsTestInstance::~AdvGraphicsTestInstance (void)
1981 {
1982 }
1983 
configCommandBuffer(void)1984 void AdvGraphicsTestInstance::configCommandBuffer (void)
1985 {
1986 	const DeviceInterface&		vk							= m_context.getDeviceInterface();
1987 
1988 	const VkClearValue			attachmentClearValues[2]	=
1989 	{
1990 		defaultClearValue(m_colorFormat),
1991 		defaultClearValue(m_depthFormat),
1992 	};
1993 
1994 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1995 
1996 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1997 		0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
1998 
1999 	if (!m_hostQueryReset)
2000 		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
2001 
2002 	beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
2003 
2004 	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
2005 
2006 	VkDeviceSize offsets = 0u;
2007 	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
2008 
2009 	vk.cmdDrawIndirect(*m_cmdBuffer, *m_indirectBuffer, 0u, m_draw_count, sizeof(VkDrawIndirectCommand));
2010 
2011 	if(m_inRenderPass)
2012 	{
2013 	  deUint32 timestampEntry = 0u;
2014 	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
2015 	  {
2016 		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
2017 	  }
2018 	}
2019 
2020 	endRenderPass(vk, *m_cmdBuffer);
2021 
2022 	if(!m_inRenderPass)
2023 	{
2024 	  deUint32 timestampEntry = 0u;
2025 	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
2026 	  {
2027 		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
2028 	  }
2029 	}
2030 
2031 	endCommandBuffer(vk, *m_cmdBuffer);
2032 }
2033 
2034 class BasicComputeTest : public TimestampTest
2035 {
2036 public:
BasicComputeTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)2037 							BasicComputeTest	(tcu::TestContext&			testContext,
2038 												 const std::string&			name,
2039 												 const std::string&			description,
2040 												 const TimestampTestParam*	param)
2041 							  : TimestampTest(testContext, name, description, param)
2042 							  { }
2043 
~BasicComputeTest(void)2044 	virtual					~BasicComputeTest	(void) { }
2045 	virtual void			initPrograms		(SourceCollections& programCollection) const;
2046 	virtual TestInstance*	createInstance		(Context& context) const;
2047 };
2048 
2049 class BasicComputeTestInstance : public TimestampTestInstance
2050 {
2051 public:
2052 					BasicComputeTestInstance	(Context&				context,
2053 												 const StageFlagVector	stages,
2054 												 const bool				inRenderPass,
2055 												 const bool				hostQueryReset);
2056 
2057 	virtual			~BasicComputeTestInstance	(void);
2058 	virtual void	configCommandBuffer			(void);
2059 protected:
2060 	de::MovePtr<Allocation>     m_inputBufAlloc;
2061 	Move<VkBuffer>              m_inputBuf;
2062 	de::MovePtr<Allocation>     m_outputBufAlloc;
2063 	Move<VkBuffer>              m_outputBuf;
2064 
2065 	Move<VkDescriptorPool>      m_descriptorPool;
2066 	Move<VkDescriptorSet>       m_descriptorSet;
2067 	Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2068 
2069 	Move<VkPipelineLayout>      m_pipelineLayout;
2070 	Move<VkShaderModule>        m_computeShaderModule;
2071 	Move<VkPipeline>            m_computePipelines;
2072 };
2073 
initPrograms(SourceCollections & programCollection) const2074 void BasicComputeTest::initPrograms (SourceCollections& programCollection) const
2075 {
2076 	TimestampTest::initPrograms(programCollection);
2077 
2078 	programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
2079 		"#version 310 es\n"
2080 		"layout(local_size_x = 128) in;\n"
2081 		"layout(std430) buffer;\n"
2082 		"layout(binding = 0) readonly buffer Input0\n"
2083 		"{\n"
2084 		"  vec4 elements[];\n"
2085 		"} input_data0;\n"
2086 		"layout(binding = 1) writeonly buffer Output\n"
2087 		"{\n"
2088 		"  vec4 elements[];\n"
2089 		"} output_data;\n"
2090 		"void main()\n"
2091 		"{\n"
2092 		"  uint ident = gl_GlobalInvocationID.x;\n"
2093 		"  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
2094 		"}");
2095 }
2096 
createInstance(Context & context) const2097 TestInstance* BasicComputeTest::createInstance (Context& context) const
2098 {
2099 	return new BasicComputeTestInstance(context,m_stages,m_inRenderPass, m_hostQueryReset);
2100 }
2101 
BasicComputeTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass,const bool hostQueryReset)2102 BasicComputeTestInstance::BasicComputeTestInstance (Context&				context,
2103 												    const StageFlagVector	stages,
2104 												    const bool				inRenderPass,
2105 												    const bool				hostQueryReset)
2106 	: TimestampTestInstance(context, stages, inRenderPass, hostQueryReset)
2107 {
2108 	const DeviceInterface&	vk			= context.getDeviceInterface();
2109 	const VkDevice			vkDevice	= context.getDevice();
2110 
2111 	// Create buffer object, allocate storage, and generate input data
2112 	const VkDeviceSize		size		= sizeof(tcu::Vec4) * 128u * 128u;
2113 
2114 	m_inputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_inputBufAlloc);
2115 
2116 	// Load vertices into buffer
2117 	tcu::Vec4*				pVec		= reinterpret_cast<tcu::Vec4*>(m_inputBufAlloc->getHostPtr());
2118 
2119 	for (deUint32 ndx = 0u; ndx < (128u * 128u); ndx++)
2120 	{
2121 		for (deUint32 component = 0u; component < 4u; component++)
2122 		{
2123 			pVec[ndx][component]= (float)(ndx * (component + 1u));
2124 		}
2125 	}
2126 
2127 	flushAlloc(vk, vkDevice, *m_inputBufAlloc);
2128 
2129 	m_outputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_outputBufAlloc);
2130 
2131 	std::vector<VkDescriptorBufferInfo> descriptorInfos;
2132 
2133 	descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, size));
2134 	descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf, 0u, size));
2135 
2136 	// Create descriptor set layout
2137 	DescriptorSetLayoutBuilder descLayoutBuilder;
2138 
2139 	for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
2140 	{
2141 		descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2142 	}
2143 
2144 	m_descriptorSetLayout = descLayoutBuilder.build(vk, vkDevice);
2145 
2146 	// Create descriptor pool
2147 	m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2148 
2149 	// Create descriptor set
2150 	const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
2151 	{
2152 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType                 sType;
2153 		DE_NULL,										// const void*                     pNext;
2154 		*m_descriptorPool,								// VkDescriptorPool                descriptorPool;
2155 		1u,												// deUint32                        setLayoutCount;
2156 		&m_descriptorSetLayout.get(),					// const VkDescriptorSetLayout*    pSetLayouts;
2157 	};
2158 	m_descriptorSet   = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);
2159 
2160 	DescriptorSetUpdateBuilder  builder;
2161 	for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
2162 	{
2163 		builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(descriptorNdx), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfos[descriptorNdx]);
2164 	}
2165 	builder.update(vk, vkDevice);
2166 
2167 	// Create compute pipeline layout
2168 	const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
2169 	{
2170 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType                 sType;
2171 		DE_NULL,										// const void*                     pNext;
2172 		0u,												// VkPipelineLayoutCreateFlags     flags;
2173 		1u,												// deUint32                        setLayoutCount;
2174 		&m_descriptorSetLayout.get(),					// const VkDescriptorSetLayout*    pSetLayouts;
2175 		0u,												// deUint32                        pushConstantRangeCount;
2176 		DE_NULL,										// const VkPushConstantRange*      pPushConstantRanges;
2177 	};
2178 
2179 	m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
2180 
2181 	// Create compute shader
2182 	VkShaderModuleCreateInfo shaderModuleCreateInfo =
2183 	{
2184 		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,									// VkStructureType             sType;
2185 		DE_NULL,																		// const void*                 pNext;
2186 		0u,																				// VkShaderModuleCreateFlags   flags;
2187 		m_context.getBinaryCollection().get("basic_compute").getSize(),					// deUintptr                   codeSize;
2188 		(deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(),	// const deUint32*             pCode;
2189 
2190 	};
2191 
2192 	m_computeShaderModule = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
2193 
2194 	// Create compute pipeline
2195 	const VkPipelineShaderStageCreateInfo stageCreateInfo =
2196 	{
2197 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType                     sType;
2198 		DE_NULL,												// const void*                         pNext;
2199 		0u,														// VkPipelineShaderStageCreateFlags    flags;
2200 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits               stage;
2201 		*m_computeShaderModule,									// VkShaderModule                      module;
2202 		"main",													// const char*                         pName;
2203 		DE_NULL,												// const VkSpecializationInfo*         pSpecializationInfo;
2204 	};
2205 
2206 	const VkComputePipelineCreateInfo pipelineCreateInfo =
2207 	{
2208 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType                 sType;
2209 		DE_NULL,										// const void*                     pNext;
2210 		0u,												// VkPipelineCreateFlags           flags;
2211 		stageCreateInfo,								// VkPipelineShaderStageCreateInfo stage;
2212 		*m_pipelineLayout,								// VkPipelineLayout                layout;
2213 		(VkPipeline)0,									// VkPipeline                      basePipelineHandle;
2214 		0u,												// deInt32                         basePipelineIndex;
2215 	};
2216 
2217 	m_computePipelines = createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo);
2218 }
2219 
~BasicComputeTestInstance(void)2220 BasicComputeTestInstance::~BasicComputeTestInstance (void)
2221 {
2222 }
2223 
configCommandBuffer(void)2224 void BasicComputeTestInstance::configCommandBuffer (void)
2225 {
2226 	const DeviceInterface& vk = m_context.getDeviceInterface();
2227 
2228 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2229 
2230 	if (!m_hostQueryReset)
2231 		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
2232 
2233 	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
2234 	vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
2235 	vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);
2236 
2237 	deUint32 timestampEntry = 0u;
2238 	for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
2239 	{
2240 		vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
2241 	}
2242 
2243 	endCommandBuffer(vk, *m_cmdBuffer);
2244 }
2245 
2246 class TransferTest : public TimestampTest
2247 {
2248 public:
2249 							TransferTest	(tcu::TestContext&			testContext,
2250 											 const std::string&			name,
2251 											 const std::string&			description,
2252 											 const TimestampTestParam*	param);
2253 
~TransferTest(void)2254 	virtual					~TransferTest	(void) { }
2255 	virtual void			initPrograms	(SourceCollections& programCollection) const;
2256 	virtual TestInstance*	createInstance	(Context& context) const;
2257 
2258 protected:
2259 	TransferMethod        m_method;
2260 };
2261 
2262 class TransferTestInstance : public TimestampTestInstance
2263 {
2264 public:
2265 					TransferTestInstance	(Context&					context,
2266 											 const StageFlagVector		stages,
2267 											 const bool					inRenderPass,
2268 											 const bool					hostQueryReset,
2269 											 const TransferMethod		method);
2270 
2271 	virtual         ~TransferTestInstance	(void);
2272 	virtual void    configCommandBuffer		(void);
2273 	virtual void	initialImageTransition	(VkCommandBuffer			cmdBuffer,
2274 											 VkImage					image,
2275 											 VkImageSubresourceRange	subRange,
2276 											 VkImageLayout				layout);
2277 protected:
2278 	TransferMethod			m_method;
2279 
2280 	VkDeviceSize			m_bufSize;
2281 	Move<VkBuffer>			m_srcBuffer;
2282 	Move<VkBuffer>			m_dstBuffer;
2283 	de::MovePtr<Allocation> m_srcBufferAlloc;
2284 	de::MovePtr<Allocation> m_dstBufferAlloc;
2285 
2286 	VkFormat				m_imageFormat;
2287 	deInt32					m_imageWidth;
2288 	deInt32					m_imageHeight;
2289 	VkDeviceSize			m_imageSize;
2290 	Move<VkImage>			m_srcImage;
2291 	Move<VkImage>			m_dstImage;
2292 	Move<VkImage>			m_depthImage;
2293 	Move<VkImage>			m_msImage;
2294 	de::MovePtr<Allocation>	m_srcImageAlloc;
2295 	de::MovePtr<Allocation>	m_dstImageAlloc;
2296 	de::MovePtr<Allocation>	m_depthImageAlloc;
2297 	de::MovePtr<Allocation>	m_msImageAlloc;
2298 };
2299 
TransferTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)2300 TransferTest::TransferTest (tcu::TestContext&			testContext,
2301 						    const std::string&			name,
2302 						    const std::string&			description,
2303 						    const TimestampTestParam*	param)
2304 	: TimestampTest(testContext, name, description, param)
2305 {
2306 	const TransferTimestampTestParam* transferParam = dynamic_cast<const TransferTimestampTestParam*>(param);
2307 	m_method = transferParam->getMethod();
2308 }
2309 
initPrograms(SourceCollections & programCollection) const2310 void TransferTest::initPrograms (SourceCollections& programCollection) const
2311 {
2312 	TimestampTest::initPrograms(programCollection);
2313 }
2314 
createInstance(Context & context) const2315 TestInstance* TransferTest::createInstance (Context& context) const
2316 {
2317   return new TransferTestInstance(context, m_stages, m_inRenderPass, m_hostQueryReset, m_method);
2318 }
2319 
TransferTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass,const bool hostQueryReset,const TransferMethod method)2320 TransferTestInstance::TransferTestInstance (Context&				context,
2321 										    const StageFlagVector	stages,
2322 										    const bool				inRenderPass,
2323 										    const bool				hostQueryReset,
2324 										    const TransferMethod	method)
2325 	: TimestampTestInstance(context, stages, inRenderPass, hostQueryReset)
2326 	, m_method(method)
2327 	, m_bufSize(256u)
2328 	, m_imageFormat(VK_FORMAT_R8G8B8A8_UNORM)
2329 	, m_imageWidth(4u)
2330 	, m_imageHeight(4u)
2331 	, m_imageSize(256u)
2332 {
2333 	const DeviceInterface&	vk			= context.getDeviceInterface();
2334 	const VkDevice			vkDevice	= context.getDevice();
2335 
2336 	// Create src buffer
2337 	m_srcBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &m_srcBufferAlloc);
2338 
2339 	// Init the source buffer memory
2340 	char* pBuf = reinterpret_cast<char*>(m_srcBufferAlloc->getHostPtr());
2341 	deMemset(pBuf, 0xFF, sizeof(char)*(size_t)m_bufSize);
2342 	flushAlloc(vk, vkDevice, *m_srcBufferAlloc);
2343 
2344 	// Create dst buffer
2345 	m_dstBuffer	= createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &m_dstBufferAlloc);
2346 
2347 	// Create src/dst/depth image
2348 	m_srcImage		= createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
2349 												 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2350 												 VK_SAMPLE_COUNT_1_BIT,
2351 												 &m_srcImageAlloc);
2352 	m_dstImage		= createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
2353 												 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2354 												 VK_SAMPLE_COUNT_1_BIT,
2355 												 &m_dstImageAlloc);
2356 	m_depthImage	= createImage2DAndBindMemory(VK_FORMAT_D16_UNORM, m_imageWidth, m_imageHeight,
2357 												 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2358 												 VK_SAMPLE_COUNT_1_BIT,
2359 												 &m_depthImageAlloc);
2360 	m_msImage		= createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
2361 												 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2362 												 VK_SAMPLE_COUNT_4_BIT,
2363 												 &m_msImageAlloc);
2364 }
2365 
~TransferTestInstance(void)2366 TransferTestInstance::~TransferTestInstance (void)
2367 {
2368 }
2369 
configCommandBuffer(void)2370 void TransferTestInstance::configCommandBuffer (void)
2371 {
2372 	const DeviceInterface& vk = m_context.getDeviceInterface();
2373 
2374 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2375 
2376 	// Initialize buffer/image
2377 	vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
2378 
2379 	const VkClearColorValue srcClearValue =
2380 	{
2381 		{1.0f, 1.0f, 1.0f, 1.0f}
2382 	};
2383 	const VkClearColorValue dstClearValue =
2384 	{
2385 		{0.0f, 0.0f, 0.0f, 0.0f}
2386 	};
2387 	const struct VkImageSubresourceRange subRangeColor =
2388 	{
2389 		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags  aspectMask;
2390 		0u,							// deUint32            baseMipLevel;
2391 		1u,							// deUint32            mipLevels;
2392 		0u,							// deUint32            baseArrayLayer;
2393 		1u,							// deUint32            arraySize;
2394 	};
2395 	const struct VkImageSubresourceRange subRangeDepth =
2396 	{
2397 		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags  aspectMask;
2398 		0u,							// deUint32            baseMipLevel;
2399 		1u,							// deUint32            mipLevels;
2400 		0u,							// deUint32            baseArrayLayer;
2401 		1u,							// deUint32            arraySize;
2402 	};
2403 
2404 	initialImageTransition(*m_cmdBuffer, *m_srcImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
2405 	initialImageTransition(*m_cmdBuffer, *m_dstImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
2406 
2407 	vk.cmdClearColorImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
2408 	vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &dstClearValue, 1u, &subRangeColor);
2409 
2410 	// synchronize the Clear commands before starting any copy
2411 	const vk::VkMemoryBarrier barrier =
2412 	{
2413 		vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,							// VkStructureType	sType;
2414 		DE_NULL,														// const void*		pNext;
2415 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,								// VkAccessFlags	srcAccessMask;
2416 		vk::VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags	dstAccessMask;
2417 	};
2418 	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
2419 
2420 	if (!m_hostQueryReset)
2421 		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
2422 
2423 	// Copy Operations
2424 	const VkImageSubresourceLayers imgSubResCopy =
2425 	{
2426 		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags  aspectMask;
2427 		0u,							// deUint32            mipLevel;
2428 		0u,							// deUint32            baseArrayLayer;
2429 		1u,							// deUint32            layerCount;
2430 	};
2431 
2432 	const VkOffset3D nullOffset  = {0u, 0u, 0u};
2433 	const VkExtent3D imageExtent = {(deUint32)m_imageWidth, (deUint32)m_imageHeight, 1u};
2434 	const VkOffset3D imageOffset = {(int)m_imageWidth, (int)m_imageHeight, 1};
2435 
2436 	switch(m_method)
2437 	{
2438 		case TRANSFER_METHOD_COPY_BUFFER:
2439 			{
2440 				const VkBufferCopy  copyBufRegion =
2441 					{
2442 						0u,			// VkDeviceSize    srcOffset;
2443 						0u,			// VkDeviceSize    destOffset;
2444 						m_bufSize,	// VkDeviceSize    copySize;
2445 					};
2446 
2447 				vk.cmdCopyBuffer(*m_cmdBuffer, *m_srcBuffer, *m_dstBuffer, 1u, &copyBufRegion);
2448 				break;
2449 			}
2450 		case TRANSFER_METHOD_COPY_IMAGE:
2451 			{
2452 				const VkImageCopy copyImageRegion =
2453 				{
2454 					imgSubResCopy,	// VkImageSubresourceCopy  srcSubresource;
2455 					nullOffset,		// VkOffset3D              srcOffset;
2456 					imgSubResCopy,	// VkImageSubresourceCopy  destSubresource;
2457 					nullOffset,		// VkOffset3D              destOffset;
2458 					imageExtent,	// VkExtent3D              extent;
2459 
2460 				};
2461 
2462 				vk.cmdCopyImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &copyImageRegion);
2463 				break;
2464 			}
2465 		case TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE:
2466 			{
2467 				const VkBufferImageCopy bufImageCopy =
2468 				{
2469 					0u,							// VkDeviceSize            bufferOffset;
2470 					(deUint32)m_imageWidth,		// deUint32                bufferRowLength;
2471 					(deUint32)m_imageHeight,	// deUint32                bufferImageHeight;
2472 					imgSubResCopy,				// VkImageSubresourceCopy  imageSubresource;
2473 					nullOffset,					// VkOffset3D              imageOffset;
2474 					imageExtent,				// VkExtent3D              imageExtent;
2475 				};
2476 
2477 				vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_srcBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &bufImageCopy);
2478 				break;
2479 			}
2480 		case TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER:
2481 			{
2482 				const VkBufferImageCopy imgBufferCopy =
2483 				{
2484 					0u,							// VkDeviceSize            bufferOffset;
2485 					(deUint32)m_imageWidth,		// deUint32                bufferRowLength;
2486 					(deUint32)m_imageHeight,	// deUint32                bufferImageHeight;
2487 					imgSubResCopy,				// VkImageSubresourceCopy  imageSubresource;
2488 					nullOffset,					// VkOffset3D              imageOffset;
2489 					imageExtent,				// VkExtent3D              imageExtent;
2490 				};
2491 
2492 				vk.cmdCopyImageToBuffer(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstBuffer, 1u, &imgBufferCopy);
2493 				break;
2494 			}
2495 		case TRANSFER_METHOD_BLIT_IMAGE:
2496 			{
2497 				const VkImageBlit imageBlt =
2498 				{
2499 					imgSubResCopy,	// VkImageSubresourceCopy  srcSubresource;
2500 					{
2501 						nullOffset,
2502 						imageOffset,
2503 					},
2504 					imgSubResCopy,	// VkImageSubresourceCopy  destSubresource;
2505 					{
2506 						nullOffset,
2507 						imageOffset,
2508 					}
2509 				};
2510 
2511 				vk.cmdBlitImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageBlt, VK_FILTER_NEAREST);
2512 				break;
2513 			}
2514 		case TRANSFER_METHOD_CLEAR_COLOR_IMAGE:
2515 			{
2516 				vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
2517 				break;
2518 			}
2519 		case TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE:
2520 			{
2521 				initialImageTransition(*m_cmdBuffer, *m_depthImage, subRangeDepth, VK_IMAGE_LAYOUT_GENERAL);
2522 
2523 				const VkClearDepthStencilValue clearDSValue =
2524 				{
2525 					1.0f,	// float       depth;
2526 					0u,		// deUint32    stencil;
2527 				};
2528 
2529 				vk.cmdClearDepthStencilImage(*m_cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_GENERAL, &clearDSValue, 1u, &subRangeDepth);
2530 				break;
2531 			}
2532 		case TRANSFER_METHOD_FILL_BUFFER:
2533 			{
2534 				vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
2535 				break;
2536 			}
2537 		case TRANSFER_METHOD_UPDATE_BUFFER:
2538 			{
2539 				const deUint32 data[] =
2540 				{
2541 					0xdeadbeef, 0xabcdef00, 0x12345678
2542 				};
2543 
2544 				vk.cmdUpdateBuffer(*m_cmdBuffer, *m_dstBuffer, 0x10, sizeof(data), data);
2545 				break;
2546 			}
2547 		case TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS:
2548 			{
2549 				vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
2550 				vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 8u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2551 
2552 				const vk::VkBufferMemoryBarrier bufferBarrier =
2553 				{
2554 					vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2555 					DE_NULL,										// const void*		pNext;
2556 					vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2557 					vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2558 					VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
2559 					VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
2560 					*m_dstBuffer,									// VkBuffer			buffer;
2561 					0ull,											// VkDeviceSize		offset;
2562 					VK_WHOLE_SIZE									// VkDeviceSize		size;
2563 				};
2564 
2565 				vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u,
2566 									  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
2567 
2568 				vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
2569 				break;
2570 			}
2571 		case TRANSFER_METHOD_RESOLVE_IMAGE:
2572 			{
2573 				const VkImageResolve imageResolve =
2574 				{
2575 					imgSubResCopy,                              // VkImageSubresourceLayers  srcSubresource;
2576 					nullOffset,                                 // VkOffset3D                srcOffset;
2577 					imgSubResCopy,                              // VkImageSubresourceLayers  destSubresource;
2578 					nullOffset,                                 // VkOffset3D                destOffset;
2579 					imageExtent,                                // VkExtent3D                extent;
2580 				};
2581 
2582 				initialImageTransition(*m_cmdBuffer, *m_msImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
2583 				vk.cmdClearColorImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
2584 				vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
2585 				vk.cmdResolveImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolve);
2586 				break;
2587 			}
2588 		default:
2589 			DE_FATAL("Unknown Transfer Method!");
2590 			break;
2591 	};
2592 
2593 	deUint32 timestampEntry = 0u;
2594 
2595 	for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
2596 	{
2597 		vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
2598 	}
2599 
2600 	endCommandBuffer(vk, *m_cmdBuffer);
2601 }
2602 
initialImageTransition(VkCommandBuffer cmdBuffer,VkImage image,VkImageSubresourceRange subRange,VkImageLayout layout)2603 void TransferTestInstance::initialImageTransition (VkCommandBuffer cmdBuffer, VkImage image, VkImageSubresourceRange subRange, VkImageLayout layout)
2604 {
2605 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
2606 
2607 	const VkImageMemoryBarrier	imageMemBarrier	=
2608 	{
2609 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType          sType;
2610 		DE_NULL,								// const void*              pNext;
2611 		0u,										// VkAccessFlags            srcAccessMask;
2612 		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags            dstAccessMask;
2613 		VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout            oldLayout;
2614 		layout,									// VkImageLayout            newLayout;
2615 		VK_QUEUE_FAMILY_IGNORED,				// uint32_t                 srcQueueFamilyIndex;
2616 		VK_QUEUE_FAMILY_IGNORED,				// uint32_t                 dstQueueFamilyIndex;
2617 		image,									// VkImage                  image;
2618 		subRange								// VkImageSubresourceRange  subresourceRange;
2619 	};
2620 
2621 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageMemBarrier);
2622 }
2623 
2624 class ResetTimestampQueryBeforeCopyTest : public vkt::TestCase
2625 {
2626 public:
ResetTimestampQueryBeforeCopyTest(tcu::TestContext & testContext,const std::string & name,const std::string & description)2627 	ResetTimestampQueryBeforeCopyTest							(tcu::TestContext&	testContext,
2628 																 const std::string&	name,
2629 																 const std::string&	description)
2630 		: vkt::TestCase(testContext, name, description)
2631 		{ }
~ResetTimestampQueryBeforeCopyTest(void)2632 	virtual               ~ResetTimestampQueryBeforeCopyTest	(void) { }
2633 	virtual void          initPrograms							(SourceCollections&	programCollection) const;
2634 	virtual TestInstance* createInstance						(Context&			context) const;
2635 };
2636 
2637 class ResetTimestampQueryBeforeCopyTestInstance : public vkt::TestInstance
2638 {
2639 public:
2640 							ResetTimestampQueryBeforeCopyTestInstance	(Context& context);
~ResetTimestampQueryBeforeCopyTestInstance(void)2641 	virtual					~ResetTimestampQueryBeforeCopyTestInstance	(void) { }
2642 	virtual tcu::TestStatus	iterate										(void);
2643 protected:
2644 	struct TimestampWithAvailability
2645 	{
2646 		deUint64 timestamp;
2647 		deUint64 availability;
2648 	};
2649 
2650 	Move<VkCommandPool>		m_cmdPool;
2651 	Move<VkCommandBuffer>	m_cmdBuffer;
2652 	Move<VkQueryPool>		m_queryPool;
2653 
2654 	Move<VkBuffer>			m_resultBuffer;
2655 	de::MovePtr<Allocation>	m_resultBufferMemory;
2656 };
2657 
initPrograms(SourceCollections & programCollection) const2658 void ResetTimestampQueryBeforeCopyTest::initPrograms (SourceCollections& programCollection) const
2659 {
2660 	vkt::TestCase::initPrograms(programCollection);
2661 }
2662 
createInstance(Context & context) const2663 TestInstance* ResetTimestampQueryBeforeCopyTest::createInstance (Context& context) const
2664 {
2665 	return new ResetTimestampQueryBeforeCopyTestInstance(context);
2666 }
2667 
ResetTimestampQueryBeforeCopyTestInstance(Context & context)2668 ResetTimestampQueryBeforeCopyTestInstance::ResetTimestampQueryBeforeCopyTestInstance (Context& context)
2669 	: vkt::TestInstance(context)
2670 {
2671 	const DeviceInterface&	vk					= context.getDeviceInterface();
2672 	const VkDevice			vkDevice			= context.getDevice();
2673 	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
2674 	Allocator&				allocator			= m_context.getDefaultAllocator();
2675 
2676 	// Check support for timestamp queries
2677 	checkTimestampsSupported(context);
2678 
2679 	const VkQueryPoolCreateInfo queryPoolParams =
2680 	{
2681 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
2682 		DE_NULL,									// const void*                   pNext;
2683 		0u,											// VkQueryPoolCreateFlags        flags;
2684 		VK_QUERY_TYPE_TIMESTAMP,					// VkQueryType                   queryType;
2685 		1u,											// deUint32                      entryCount;
2686 		0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
2687 	};
2688 
2689 	m_queryPool		= createQueryPool(vk, vkDevice, &queryPoolParams);
2690 	m_cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2691 	m_cmdBuffer		= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2692 
2693 	// Create results buffer.
2694 	const VkBufferCreateInfo bufferCreateInfo =
2695 	{
2696 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2697 		DE_NULL,									// const void*			pNext;
2698 		0u,											// VkBufferCreateFlags	flags;
2699 		sizeof(TimestampWithAvailability),			// VkDeviceSize			size;
2700 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
2701 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2702 		1u,											// deUint32				queueFamilyIndexCount;
2703 		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
2704 	};
2705 
2706 	m_resultBuffer			= createBuffer(vk, vkDevice, &bufferCreateInfo);
2707 	m_resultBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
2708 	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
2709 
2710 	const vk::VkBufferMemoryBarrier bufferBarrier =
2711 	{
2712 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2713 		DE_NULL,										// const void*		pNext;
2714 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2715 		vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2716 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
2717 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
2718 		*m_resultBuffer,								// VkBuffer			buffer;
2719 		0ull,											// VkDeviceSize		offset;
2720 		VK_WHOLE_SIZE									// VkDeviceSize		size;
2721 	};
2722 
2723 	// Prepare command buffer.
2724 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2725 	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
2726 	vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
2727 	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
2728 	vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_resultBuffer, 0u, sizeof(TimestampWithAvailability), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
2729 	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
2730 	endCommandBuffer(vk, *m_cmdBuffer);
2731 }
2732 
iterate(void)2733 tcu::TestStatus ResetTimestampQueryBeforeCopyTestInstance::iterate (void)
2734 {
2735 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2736 	const VkDevice				vkDevice	= m_context.getDevice();
2737 	const VkQueue				queue		= m_context.getUniversalQueue();
2738 	TimestampWithAvailability	ta;
2739 
2740 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
2741 	invalidateAlloc(vk, vkDevice, *m_resultBufferMemory);
2742 	deMemcpy(&ta, m_resultBufferMemory->getHostPtr(), sizeof(ta));
2743 	return ((ta.availability != 0)? tcu::TestStatus::fail("Availability bit nonzero after resetting query") : tcu::TestStatus::pass("Pass"));
2744 }
2745 
2746 
2747 class TwoCmdBuffersTest : public TimestampTest
2748 {
2749 public:
TwoCmdBuffersTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TwoCmdBuffersTestParam * param)2750 							TwoCmdBuffersTest	(tcu::TestContext&				testContext,
2751 												 const std::string&				name,
2752 												 const std::string&				description,
2753 												 const TwoCmdBuffersTestParam*	param)
2754 : TimestampTest (testContext, name, description, param), m_cmdBufferLevel(param->getCmdBufferLevel()) { }
~TwoCmdBuffersTest(void)2755 	virtual					~TwoCmdBuffersTest	(void) { }
2756 	virtual TestInstance*	createInstance		(Context&						context) const;
2757 
2758 protected:
2759 	VkCommandBufferLevel	m_cmdBufferLevel;
2760 };
2761 
2762 class TwoCmdBuffersTestInstance : public TimestampTestInstance
2763 {
2764 public:
2765 							TwoCmdBuffersTestInstance	(Context&				context,
2766 														 const StageFlagVector	stages,
2767 														 const bool				inRenderPass,
2768 														 const bool				hostQueryReset,
2769 														 VkCommandBufferLevel	cmdBufferLevel);
2770 	virtual					~TwoCmdBuffersTestInstance	(void);
2771 	virtual tcu::TestStatus	iterate						(void);
2772 protected:
2773 	virtual void			configCommandBuffer			(void);
2774 
2775 protected:
2776 	Move<VkCommandBuffer>	m_secondCmdBuffer;
2777 	Move<VkBuffer>			m_dstBuffer;
2778 	de::MovePtr<Allocation> m_dstBufferAlloc;
2779 	VkCommandBufferLevel	m_cmdBufferLevel;
2780 };
2781 
createInstance(Context & context) const2782 TestInstance* TwoCmdBuffersTest::createInstance (Context& context) const
2783 {
2784 	return new TwoCmdBuffersTestInstance(context, m_stages, m_inRenderPass, m_hostQueryReset, m_cmdBufferLevel);
2785 }
2786 
TwoCmdBuffersTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass,const bool hostQueryReset,VkCommandBufferLevel cmdBufferLevel)2787 TwoCmdBuffersTestInstance::TwoCmdBuffersTestInstance (Context&					context,
2788 													  const StageFlagVector		stages,
2789 													  const bool				inRenderPass,
2790 													  const bool				hostQueryReset,
2791 													  VkCommandBufferLevel		cmdBufferLevel)
2792 : TimestampTestInstance (context, stages, inRenderPass, hostQueryReset), m_cmdBufferLevel(cmdBufferLevel)
2793 {
2794 	const DeviceInterface&	vk			= context.getDeviceInterface();
2795 	const VkDevice			vkDevice	= context.getDevice();
2796 
2797 	m_secondCmdBuffer	= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, cmdBufferLevel);
2798 	m_dstBuffer			= createBufferAndBindMemory(1024, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &m_dstBufferAlloc);
2799 }
2800 
~TwoCmdBuffersTestInstance(void)2801 TwoCmdBuffersTestInstance::~TwoCmdBuffersTestInstance (void)
2802 {
2803 }
2804 
configCommandBuffer(void)2805 void TwoCmdBuffersTestInstance::configCommandBuffer (void)
2806 {
2807 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
2808 
2809 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
2810 	{
2811 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
2812 		DE_NULL,										// const void*                              pNext;
2813 		0u,												// VkCommandBufferUsageFlags                flags;
2814 		(const VkCommandBufferInheritanceInfo*)DE_NULL	// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
2815 	};
2816 
2817 	const vk::VkBufferMemoryBarrier bufferBarrier =
2818 	{
2819 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2820 		DE_NULL,										// const void*		pNext;
2821 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2822 		vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2823 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
2824 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
2825 		*m_dstBuffer,									// VkBuffer			buffer;
2826 		0ull,											// VkDeviceSize		offset;
2827 		VK_WHOLE_SIZE									// VkDeviceSize		size;
2828 	};
2829 
2830 	if (m_cmdBufferLevel == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
2831 	{
2832 		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2833 		if (!m_hostQueryReset)
2834 			vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
2835 		vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, *m_queryPool, 0);
2836 		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2837 		VK_CHECK(vk.beginCommandBuffer(*m_secondCmdBuffer, &cmdBufferBeginInfo));
2838 		vk.cmdCopyQueryPoolResults(*m_secondCmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 0u, VK_QUERY_RESULT_WAIT_BIT);
2839 		vk.cmdPipelineBarrier(*m_secondCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u,
2840 							  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
2841 		VK_CHECK(vk.endCommandBuffer(*m_secondCmdBuffer));
2842 	}
2843 	else
2844 	{
2845 		const VkCommandBufferInheritanceInfo inheritanceInfo		=
2846 		{
2847 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,	// VkStructureType                  sType;
2848 			DE_NULL,											// const void*                      pNext;
2849 			DE_NULL,											// VkRenderPass                     renderPass;
2850 			0u,													// deUint32                         subpass;
2851 			DE_NULL,											// VkFramebuffer                    framebuffer;
2852 			VK_FALSE,											// VkBool32                         occlusionQueryEnable;
2853 			0u,													// VkQueryControlFlags              queryFlags;
2854 			0u													// VkQueryPipelineStatisticFlags    pipelineStatistics;
2855 		};
2856 
2857 		const VkCommandBufferBeginInfo cmdBufferBeginInfoSecondary	=
2858 		{
2859 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
2860 			DE_NULL,										// const void*                              pNext;
2861 			0u,												// VkCommandBufferUsageFlags                flags;
2862 			&inheritanceInfo								// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
2863 		};
2864 
2865 		VK_CHECK(vk.beginCommandBuffer(*m_secondCmdBuffer, &cmdBufferBeginInfoSecondary));
2866 		vk.cmdResetQueryPool(*m_secondCmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
2867 		vk.cmdWriteTimestamp(*m_secondCmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, *m_queryPool, 0);
2868 		VK_CHECK(vk.endCommandBuffer(*m_secondCmdBuffer));
2869 		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2870 		vk.cmdExecuteCommands(m_cmdBuffer.get(), 1u, &m_secondCmdBuffer.get());
2871 		vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 0u, VK_QUERY_RESULT_WAIT_BIT);
2872 		vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u,
2873 							  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
2874 		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2875 	}
2876 }
2877 
iterate(void)2878 tcu::TestStatus TwoCmdBuffersTestInstance::iterate (void)
2879 {
2880 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
2881 	const VkQueue				queue			= m_context.getUniversalQueue();
2882 
2883 	configCommandBuffer();
2884 
2885 	const VkCommandBuffer		cmdBuffers[]	= { m_cmdBuffer.get(), m_secondCmdBuffer.get() };
2886 
2887 	const VkSubmitInfo			submitInfo		=
2888 	{
2889 		VK_STRUCTURE_TYPE_SUBMIT_INFO,									// VkStructureType                sType;
2890 		DE_NULL,														// const void*                    pNext;
2891 		0u,																// deUint32                       waitSemaphoreCount;
2892 		DE_NULL,														// const VkSemaphore*             pWaitSemaphores;
2893 		(const VkPipelineStageFlags*)DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
2894 		m_cmdBufferLevel == VK_COMMAND_BUFFER_LEVEL_PRIMARY ? 2u : 1u,	// deUint32                       commandBufferCount;
2895 		cmdBuffers,														// const VkCommandBuffer*         pCommandBuffers;
2896 		0u,																// deUint32                       signalSemaphoreCount;
2897 		DE_NULL,														// const VkSemaphore*             pSignalSemaphores;
2898 	};
2899 
2900 	if (m_hostQueryReset)
2901 	{
2902 		// Only reset the pool for the primary command buffer, the secondary command buffer will reset the pool by itself.
2903 		vk.resetQueryPool(m_context.getDevice(), *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
2904 	}
2905 
2906 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
2907 	VK_CHECK(vk.queueWaitIdle(queue));
2908 
2909 	// Always pass in case no crash occurred.
2910 	return tcu::TestStatus::pass("Pass");
2911 }
2912 
2913 class ConsistentQueryResultsTest : public vkt::TestCase
2914 {
2915 public:
ConsistentQueryResultsTest(tcu::TestContext & testContext,const std::string & name,const std::string & description)2916 	ConsistentQueryResultsTest							(tcu::TestContext&	testContext,
2917 														 const std::string&	name,
2918 														 const std::string&	description)
2919 		: vkt::TestCase(testContext, name, description)
2920 		{ }
~ConsistentQueryResultsTest(void)2921 	virtual               ~ConsistentQueryResultsTest	(void) { }
2922 	virtual void          initPrograms					(SourceCollections&	programCollection) const;
2923 	virtual TestInstance* createInstance				(Context&			context) const;
2924 };
2925 
2926 class ConsistentQueryResultsTestInstance : public vkt::TestInstance
2927 {
2928 public:
2929 							ConsistentQueryResultsTestInstance	(Context& context);
~ConsistentQueryResultsTestInstance(void)2930 	virtual					~ConsistentQueryResultsTestInstance	(void) { }
2931 	virtual tcu::TestStatus	iterate								(void);
2932 protected:
2933 	Move<VkCommandPool>		m_cmdPool;
2934 	Move<VkCommandBuffer>	m_cmdBuffer;
2935 	Move<VkQueryPool>		m_queryPool;
2936 
2937 	deUint64				m_timestampMask;
2938 	Move<VkBuffer>			m_resultBuffer32Bits;
2939 	Move<VkBuffer>			m_resultBuffer64Bits;
2940 	de::MovePtr<Allocation>	m_resultBufferMemory32Bits;
2941 	de::MovePtr<Allocation>	m_resultBufferMemory64Bits;
2942 };
2943 
initPrograms(SourceCollections & programCollection) const2944 void ConsistentQueryResultsTest::initPrograms(SourceCollections& programCollection) const
2945 {
2946 	vkt::TestCase::initPrograms(programCollection);
2947 }
2948 
createInstance(Context & context) const2949 TestInstance* ConsistentQueryResultsTest::createInstance(Context& context) const
2950 {
2951 	return new ConsistentQueryResultsTestInstance(context);
2952 }
2953 
ConsistentQueryResultsTestInstance(Context & context)2954 ConsistentQueryResultsTestInstance::ConsistentQueryResultsTestInstance(Context& context)
2955 	: vkt::TestInstance(context)
2956 {
2957 	const DeviceInterface&	vk					= context.getDeviceInterface();
2958 	const VkDevice			vkDevice			= context.getDevice();
2959 	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
2960 	Allocator&				allocator			= m_context.getDefaultAllocator();
2961 
2962 	// Check support for timestamp queries
2963 	m_timestampMask = checkTimestampsSupported(context);
2964 
2965 	const VkQueryPoolCreateInfo queryPoolParams =
2966 	{
2967 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
2968 		DE_NULL,									// const void*                   pNext;
2969 		0u,											// VkQueryPoolCreateFlags        flags;
2970 		VK_QUERY_TYPE_TIMESTAMP,					// VkQueryType                   queryType;
2971 		1u,											// deUint32                      entryCount;
2972 		0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
2973 	};
2974 
2975 	m_queryPool		= createQueryPool(vk, vkDevice, &queryPoolParams);
2976 	m_cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2977 	m_cmdBuffer		= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2978 
2979 	// Create results buffer.
2980 	VkBufferCreateInfo bufferCreateInfo =
2981 	{
2982 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2983 		DE_NULL,									// const void*			pNext;
2984 		0u,											// VkBufferCreateFlags	flags;
2985 		0u,											// VkDeviceSize			size;
2986 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
2987 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2988 		1u,											// deUint32				queueFamilyIndexCount;
2989 		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
2990 	};
2991 
2992 	// 32 bits.
2993 	bufferCreateInfo.size		= sizeof(deUint32);
2994 	m_resultBuffer32Bits		= createBuffer(vk, vkDevice, &bufferCreateInfo);
2995 	m_resultBufferMemory32Bits	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_resultBuffer32Bits), MemoryRequirement::HostVisible);
2996 	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_resultBuffer32Bits, m_resultBufferMemory32Bits->getMemory(), m_resultBufferMemory32Bits->getOffset()));
2997 
2998 	// 64 bits.
2999 	bufferCreateInfo.size		= sizeof(deUint64);
3000 	m_resultBuffer64Bits		= createBuffer(vk, vkDevice, &bufferCreateInfo);
3001 	m_resultBufferMemory64Bits	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_resultBuffer64Bits), MemoryRequirement::HostVisible);
3002 	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_resultBuffer64Bits, m_resultBufferMemory64Bits->getMemory(), m_resultBufferMemory64Bits->getOffset()));
3003 
3004 	vk::VkBufferMemoryBarrier bufferBarrier =
3005 	{
3006 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
3007 		DE_NULL,										// const void*		pNext;
3008 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
3009 		vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
3010 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
3011 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
3012 		DE_NULL,										// VkBuffer			buffer;
3013 		0ull,											// VkDeviceSize		offset;
3014 		VK_WHOLE_SIZE									// VkDeviceSize		size;
3015 	};
3016 
3017 	// Prepare command buffer.
3018 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
3019 	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
3020 	vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
3021 
3022 	// 32 bits.
3023 	bufferBarrier.buffer = *m_resultBuffer32Bits;
3024 	vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_resultBuffer32Bits, 0u, sizeof(deUint32), VK_QUERY_RESULT_WAIT_BIT);
3025 	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
3026 
3027 	// 64 bits.
3028 	bufferBarrier.buffer = *m_resultBuffer64Bits;
3029 	vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_resultBuffer64Bits, 0u, sizeof(deUint64), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
3030 	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
3031 
3032 	endCommandBuffer(vk, *m_cmdBuffer);
3033 }
3034 
iterate(void)3035 tcu::TestStatus ConsistentQueryResultsTestInstance::iterate(void)
3036 {
3037 	const DeviceInterface&      vk          = m_context.getDeviceInterface();
3038 	const VkDevice              vkDevice    = m_context.getDevice();
3039 	const VkQueue               queue       = m_context.getUniversalQueue();
3040 
3041 	deUint32					tsBuffer32Bits;
3042 	deUint64					tsBuffer64Bits;
3043 	deUint32					tsGet32Bits;
3044 	deUint64					tsGet64Bits;
3045 
3046 	constexpr deUint32			maxDeUint32Value = std::numeric_limits<deUint32>::max();
3047 
3048 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
3049 
3050 	// Get results from buffers.
3051 	invalidateAlloc(vk, vkDevice, *m_resultBufferMemory32Bits);
3052 	invalidateAlloc(vk, vkDevice, *m_resultBufferMemory64Bits);
3053 	deMemcpy(&tsBuffer32Bits, m_resultBufferMemory32Bits->getHostPtr(), sizeof(tsBuffer32Bits));
3054 	deMemcpy(&tsBuffer64Bits, m_resultBufferMemory64Bits->getHostPtr(), sizeof(tsBuffer64Bits));
3055 
3056 	// Get results with vkGetQueryPoolResults().
3057 	VK_CHECK(vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, 1u, sizeof(tsGet32Bits), &tsGet32Bits, sizeof(tsGet32Bits), VK_QUERY_RESULT_WAIT_BIT));
3058 	VK_CHECK(vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, 1u, sizeof(tsGet64Bits), &tsGet64Bits, sizeof(tsGet64Bits), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)));
3059 
3060 	// Check timestamp mask for both 64-bit results.
3061 	checkTimestampBits(tsBuffer64Bits, m_timestampMask);
3062 	checkTimestampBits(tsGet64Bits, m_timestampMask);
3063 
3064 	// Check results are consistent.
3065 	if (tsBuffer32Bits == tsGet32Bits &&
3066 		tsBuffer64Bits == tsGet64Bits &&
3067 		(((tsGet64Bits & maxDeUint32Value) == tsGet32Bits) ||
3068 		((tsGet64Bits > maxDeUint32Value) && (maxDeUint32Value == tsGet32Bits))))
3069 	{
3070 		return tcu::TestStatus::pass("Pass");
3071 	}
3072 
3073 	std::ostringstream msg;
3074 	msg << std::hex << "Results are inconsistent:"
3075 		<< " B32=0x" << tsBuffer32Bits
3076 		<< " B64=0x" << tsBuffer64Bits
3077 		<< " G32=0x" << tsGet32Bits
3078 		<< " G64=0x" << tsGet64Bits;
3079 	return tcu::TestStatus::fail(msg.str());
3080 }
3081 
3082 } // anonymous
3083 
createTimestampTests(tcu::TestContext & testCtx)3084 tcu::TestCaseGroup* createTimestampTests (tcu::TestContext& testCtx)
3085 {
3086 	de::MovePtr<tcu::TestCaseGroup> timestampTests (new tcu::TestCaseGroup(testCtx, "timestamp", "timestamp tests"));
3087 
3088 	// Basic Graphics Tests
3089 	{
3090 		de::MovePtr<tcu::TestCaseGroup> basicGraphicsTests (new tcu::TestCaseGroup(testCtx, "basic_graphics_tests", "Record timestamp in different pipeline stages of basic graphics tests"));
3091 
3092 		const VkPipelineStageFlagBits basicGraphicsStages0[][2] =
3093 		{
3094 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_INPUT_BIT},
3095 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
3096 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
3097 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT},
3098 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
3099 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
3100 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT},
3101 		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
3102 		};
3103 		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages0); stageNdx++)
3104 		{
3105 			TimestampTestParam param(basicGraphicsStages0[stageNdx], 2u, true, false);
3106 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3107 			param.toggleInRenderPass();
3108 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3109 			// Host Query reset tests
3110 			param.toggleHostQueryReset();
3111 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3112 			param.toggleInRenderPass();
3113 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3114 		}
3115 
3116 		const VkPipelineStageFlagBits basicGraphicsStages1[][3] =
3117 		{
3118 		  {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,      VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
3119 		  {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,  VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
3120 		};
3121 		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages1); stageNdx++)
3122 		{
3123 			TimestampTestParam param(basicGraphicsStages1[stageNdx], 3u, true, false);
3124 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3125 			param.toggleInRenderPass();
3126 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3127 			// Host Query reset tests
3128 			param.toggleHostQueryReset();
3129 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3130 			param.toggleInRenderPass();
3131 			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
3132 		}
3133 
3134 		timestampTests->addChild(basicGraphicsTests.release());
3135 	}
3136 
3137 	// Advanced Graphics Tests
3138 	{
3139 		de::MovePtr<tcu::TestCaseGroup> advGraphicsTests (new tcu::TestCaseGroup(testCtx, "advanced_graphics_tests", "Record timestamp in different pipeline stages of advanced graphics tests"));
3140 
3141 		const VkPipelineStageFlagBits advGraphicsStages[][2] =
3142 		{
3143 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT},
3144 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT},
3145 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT},
3146 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
3147 		};
3148 		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(advGraphicsStages); stageNdx++)
3149 		{
3150 			TimestampTestParam param(advGraphicsStages[stageNdx], 2u, true, false);
3151 			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
3152 			param.toggleInRenderPass();
3153 			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
3154 			// Host Query reset tests
3155 			param.toggleHostQueryReset();
3156 			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
3157 			param.toggleInRenderPass();
3158 			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
3159 		}
3160 
3161 		timestampTests->addChild(advGraphicsTests.release());
3162 	}
3163 
3164 	// Basic Compute Tests
3165 	{
3166 		de::MovePtr<tcu::TestCaseGroup> basicComputeTests (new tcu::TestCaseGroup(testCtx, "basic_compute_tests", "Record timestamp for compute stages"));
3167 
3168 		const VkPipelineStageFlagBits basicComputeStages[][2] =
3169 		{
3170 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
3171 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
3172 		};
3173 		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicComputeStages); stageNdx++)
3174 		{
3175 			TimestampTestParam param(basicComputeStages[stageNdx], 2u, false, false);
3176 			basicComputeTests->addChild(newTestCase<BasicComputeTest>(testCtx, &param));
3177 			// Host Query reset test
3178 			param.toggleHostQueryReset();
3179 			basicComputeTests->addChild(newTestCase<BasicComputeTest>(testCtx, &param));
3180 		}
3181 
3182 		timestampTests->addChild(basicComputeTests.release());
3183 	}
3184 
3185 	// Transfer Tests
3186 	{
3187 		de::MovePtr<tcu::TestCaseGroup> transferTests (new tcu::TestCaseGroup(testCtx, "transfer_tests", "Record timestamp for transfer stages"));
3188 
3189 		const VkPipelineStageFlagBits transferStages[][2] =
3190 		{
3191 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT},
3192 			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT},
3193 		};
3194 		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(transferStages); stageNdx++)
3195 		{
3196 			for (deUint32 method = 0u; method < TRANSFER_METHOD_LAST; method++)
3197 			{
3198 				TransferTimestampTestParam param(transferStages[stageNdx], 2u, false, false, method);
3199 				transferTests->addChild(newTestCase<TransferTest>(testCtx, &param));
3200 				// Host Query reset test
3201 				param.toggleHostQueryReset();
3202 				transferTests->addChild(newTestCase<TransferTest>(testCtx, &param));
3203 			}
3204 		}
3205 
3206 		timestampTests->addChild(transferTests.release());
3207 	}
3208 
3209 	// Calibrated Timestamp Tests.
3210 	{
3211 		de::MovePtr<tcu::TestCaseGroup> calibratedTimestampTests (new tcu::TestCaseGroup(testCtx, "calibrated", "VK_EXT_calibrated_timestamps tests"));
3212 
3213 		calibratedTimestampTests->addChild(new CalibratedTimestampTest<CalibratedTimestampDevDomainTestInstance>	(testCtx, "dev_domain_test",	"Test device domain"));
3214 		calibratedTimestampTests->addChild(new CalibratedTimestampTest<CalibratedTimestampHostDomainTestInstance>	(testCtx, "host_domain_test",	"Test host domain"));
3215 		calibratedTimestampTests->addChild(new CalibratedTimestampTest<CalibratedTimestampCalibrationTestInstance>	(testCtx, "calibration_test",	"Test calibration using device and host domains"));
3216 
3217 		timestampTests->addChild(calibratedTimestampTests.release());
3218 	}
3219 
3220 	// Misc Tests
3221 	{
3222 		de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc_tests", "Misc tests that can not be categorized to other group."));
3223 
3224 		const VkPipelineStageFlagBits miscStages[] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
3225 		TimestampTestParam param(miscStages, 1u, false, false);
3226 		miscTests->addChild(new TimestampTest(testCtx,
3227 											  "timestamp_only",
3228 											  "Only write timestamp command in the commmand buffer",
3229 											  &param));
3230 
3231 		TwoCmdBuffersTestParam twoCmdBuffersParamPrimary(miscStages, 1u, false, false, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3232 		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
3233 												  "two_cmd_buffers_primary",
3234 												  "Issue query in a command buffer and copy it on another primary command buffer",
3235 												  &twoCmdBuffersParamPrimary));
3236 
3237 		TwoCmdBuffersTestParam twoCmdBuffersParamSecondary(miscStages, 1u, false, false, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3238 		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
3239 												  "two_cmd_buffers_secondary",
3240 												  "Issue query in a secondary command buffer and copy it on a primary command buffer",
3241 												  &twoCmdBuffersParamSecondary));
3242 		// Misc: Host Query Reset tests
3243 		param.toggleHostQueryReset();
3244 		miscTests->addChild(new TimestampTest(testCtx,
3245 											  "timestamp_only_host_query_reset",
3246 											  "Only write timestamp command in the commmand buffer",
3247 											  &param));
3248 		TwoCmdBuffersTestParam twoCmdBuffersParamPrimaryHostQueryReset(miscStages, 1u, false, true, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3249 		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
3250 												  "two_cmd_buffers_primary_host_query_reset",
3251 												  "Issue query in a command buffer and copy it on another primary command buffer",
3252 												  &twoCmdBuffersParamPrimaryHostQueryReset));
3253 
3254 		TwoCmdBuffersTestParam twoCmdBuffersParamSecondaryHostQueryReset(miscStages, 1u, false, true, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3255 		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
3256 												  "two_cmd_buffers_secondary_host_query_reset",
3257 												  "Issue query in a secondary command buffer and copy it on a primary command buffer",
3258 												  &twoCmdBuffersParamSecondaryHostQueryReset));
3259 
3260 		// Reset timestamp query before copying results.
3261 		miscTests->addChild(new ResetTimestampQueryBeforeCopyTest(testCtx,
3262 																  "reset_query_before_copy",
3263 																  "Issue a timestamp query and reset it before copying results"));
3264 
3265 		// Check consistency between 32 and 64 bits.
3266 		miscTests->addChild(new ConsistentQueryResultsTest(testCtx,
3267 														   "consistent_results",
3268 														   "Check consistency between 32-bit and 64-bit timestamp"));
3269 
3270 		timestampTests->addChild(miscTests.release());
3271 	}
3272 
3273 	return timestampTests.release();
3274 }
3275 
3276 } // pipeline
3277 
3278 } // vkt
3279