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