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