• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan Statistics Query Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktQueryPoolStatisticsTests.hpp"
25 #include "vktTestCase.hpp"
26 
27 #include "vktDrawImageObjectUtil.hpp"
28 #include "vktDrawBufferObjectUtil.hpp"
29 #include "vktDrawCreateInfoUtil.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkObjUtil.hpp"
36 
37 #include "deMath.h"
38 
39 #include "tcuTestLog.hpp"
40 #include "tcuResource.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "vkImageUtil.hpp"
43 #include "tcuCommandLine.hpp"
44 #include "tcuRGBA.hpp"
45 #include "tcuStringTemplate.hpp"
46 #include "tcuMaybe.hpp"
47 
48 #include <vector>
49 #include <utility>
50 #include <algorithm>
51 
52 using std::vector;
53 using std::pair;
54 
55 namespace vkt
56 {
57 namespace QueryPool
58 {
59 namespace
60 {
61 
62 using namespace vk;
63 using namespace Draw;
64 
65 //Test parameters
66 enum
67 {
68 	WIDTH	= 64,
69 	HEIGHT	= 64
70 };
71 
72 enum ResetType
73 {
74 	RESET_TYPE_NORMAL = 0,
75 	RESET_TYPE_HOST,
76 	RESET_TYPE_BEFORE_COPY,
77 	RESET_TYPE_LAST
78 };
79 
80 enum CopyType
81 {
82 	COPY_TYPE_GET = 0,
83 	COPY_TYPE_CMD,
84 };
85 
inputTypeToGLString(const VkPrimitiveTopology & inputType)86 std::string inputTypeToGLString (const VkPrimitiveTopology& inputType)
87 {
88 	switch (inputType)
89 	{
90 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
91 			return "points";
92 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
93 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
94 			return "lines";
95 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
96 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
97 			return "lines_adjacency";
98 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
99 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
100 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
101 			return "triangles";
102 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
103 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
104 			return "triangles_adjacency";
105 		default:
106 			DE_ASSERT(DE_FALSE);
107 			return "error";
108 	}
109 }
110 
outputTypeToGLString(const VkPrimitiveTopology & outputType)111 std::string outputTypeToGLString (const VkPrimitiveTopology& outputType)
112 {
113 	switch (outputType)
114 	{
115 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
116 			return "points";
117 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
118 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
119 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
120 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
121 				return "line_strip";
122 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
123 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
124 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
125 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
126 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
127 			return "triangle_strip";
128 		default:
129 			DE_ASSERT(DE_FALSE);
130 			return "error";
131 	}
132 }
133 
134 using Pair32						= pair<deUint32, deUint32>;
135 using Pair64						= pair<deUint64, deUint64>;
136 using ResultsVector					= vector<deUint64>;
137 using ResultsVectorWithAvailability	= vector<Pair64>;
138 
139 // Get query pool results as a vector. Note results are always converted to
140 // deUint64, but the actual vkGetQueryPoolResults call will use the 64-bits flag
141 // or not depending on your preferences.
GetQueryPoolResultsVector(ResultsVector & output,const DeviceInterface & vk,vk::VkDevice device,vk::VkQueryPool queryPool,deUint32 firstQuery,deUint32 queryCount,VkQueryResultFlags flags)142 vk::VkResult GetQueryPoolResultsVector(
143 	ResultsVector& output, const DeviceInterface& vk, vk::VkDevice device, vk::VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount, VkQueryResultFlags flags)
144 {
145 	if (flags & vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
146 		TCU_THROW(InternalError, "Availability flag passed when expecting results as ResultsVector");
147 
148 	vk::VkResult result;
149 	output.resize(queryCount);
150 
151 	if (flags & vk::VK_QUERY_RESULT_64_BIT)
152 	{
153 		constexpr size_t	stride		= sizeof(ResultsVector::value_type);
154 		const size_t		totalSize	= stride * output.size();
155 		result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, output.data(), stride, flags);
156 	}
157 	else
158 	{
159 		using IntermediateVector = vector<deUint32>;
160 
161 		IntermediateVector	intermediate(queryCount);
162 
163 		// Try to preserve existing data if possible.
164 		std::transform(begin(output), end(output), begin(intermediate), [](deUint64 v) { return static_cast<deUint32>(v); });
165 
166 		constexpr size_t	stride		= sizeof(decltype(intermediate)::value_type);
167 		const size_t		totalSize	= stride * intermediate.size();
168 
169 		// Get and copy results.
170 		result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, intermediate.data(), stride, flags);
171 		std::copy(begin(intermediate), end(intermediate), begin(output));
172 	}
173 
174 	return result;
175 }
176 
177 // Same as the normal GetQueryPoolResultsVector but returning the availability
178 // bit associated to each query in addition to the query value.
GetQueryPoolResultsVector(ResultsVectorWithAvailability & output,const DeviceInterface & vk,vk::VkDevice device,vk::VkQueryPool queryPool,deUint32 firstQuery,deUint32 queryCount,VkQueryResultFlags flags)179 vk::VkResult GetQueryPoolResultsVector(
180 	ResultsVectorWithAvailability& output, const DeviceInterface& vk, vk::VkDevice device, vk::VkQueryPool queryPool, deUint32 firstQuery, deUint32 queryCount, VkQueryResultFlags flags)
181 {
182 	flags |= vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
183 
184 	vk::VkResult result;
185 	output.resize(queryCount);
186 
187 	if (flags & vk::VK_QUERY_RESULT_64_BIT)
188 	{
189 		constexpr size_t	stride		= sizeof(ResultsVectorWithAvailability::value_type);
190 		const size_t		totalSize	= stride * output.size();
191 		result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, output.data(), stride, flags);
192 	}
193 	else
194 	{
195 		using IntermediateVector = vector<Pair32>;
196 
197 		IntermediateVector	intermediate(queryCount);
198 
199 		// Try to preserve existing output data if possible.
200 		std::transform(begin(output), end(output), begin(intermediate), [](const Pair64& p) { return Pair32{static_cast<deUint32>(p.first), static_cast<deUint32>(p.second)}; });
201 
202 		constexpr size_t	stride		= sizeof(decltype(intermediate)::value_type);
203 		const size_t		totalSize	= stride * intermediate.size();
204 
205 		// Get and copy.
206 		result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, intermediate.data(), stride, flags);
207 		std::transform(begin(intermediate), end(intermediate), begin(output), [](const Pair32& p) { return Pair64{p.first, p.second}; });
208 	}
209 
210 	return result;
211 }
212 
213 // Get query pool results as a vector. Note results are always converted to
214 // deUint64, but the actual vkCmdCopyQueryPoolResults call will use the 64-bits flag
215 // or not depending on your preferences.
cmdCopyQueryPoolResultsVector(ResultsVector & output,const DeviceInterface & vk,vk::VkDevice device,const vk::Allocation & allocation,deUint32 queryCount,VkQueryResultFlags flags,deBool dstOffset)216 void cmdCopyQueryPoolResultsVector(
217 	  ResultsVector& output, const DeviceInterface& vk, vk::VkDevice device, const vk::Allocation& allocation, deUint32 queryCount, VkQueryResultFlags flags, deBool dstOffset)
218 {
219 	if (flags & vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
220 		TCU_THROW(InternalError, "Availability flag passed when expecting results as ResultsVector");
221 
222 	output.resize(queryCount);
223 
224 	void* allocationData = allocation.getHostPtr();
225 	vk::invalidateAlloc(vk, device, allocation);
226 
227 	if (flags & vk::VK_QUERY_RESULT_64_BIT)
228 	{
229 		constexpr size_t	stride		= sizeof(ResultsVector::value_type);
230 		const size_t		totalSize	= stride * output.size();
231 		const deUint32		offset		= dstOffset ? 1u : 0u;
232 		deMemcpy(output.data(), (reinterpret_cast<ResultsVector::value_type*>(allocationData) + offset), totalSize);
233 	}
234 	else
235 	{
236 		using IntermediateVector = vector<deUint32>;
237 
238 		IntermediateVector	intermediate(queryCount);
239 
240 		// Try to preserve existing data if possible.
241 		std::transform(begin(output), end(output), begin(intermediate), [](deUint64 v) { return static_cast<deUint32>(v); });
242 
243 		constexpr size_t	stride		= sizeof(decltype(intermediate)::value_type);
244 		const size_t		totalSize	= stride * intermediate.size();
245 		const deUint32		offset		= dstOffset ? 1u : 0u;
246 		// Get and copy results.
247 		deMemcpy(intermediate.data(), (reinterpret_cast<decltype(intermediate)::value_type*>(allocationData) + offset), totalSize);
248 		std::copy(begin(intermediate), end(intermediate), begin(output));
249 	}
250 }
251 
252 // Same as the normal cmdCopyQueryPoolResultsVector but returning the availability
253 // bit associated to each query in addition to the query value.
cmdCopyQueryPoolResultsVector(ResultsVectorWithAvailability & output,const DeviceInterface & vk,vk::VkDevice device,const vk::Allocation & allocation,deUint32 queryCount,VkQueryResultFlags flags,deBool dstOffset)254 void cmdCopyQueryPoolResultsVector(
255    ResultsVectorWithAvailability& output, const DeviceInterface& vk, vk::VkDevice device, const vk::Allocation& allocation, deUint32 queryCount, VkQueryResultFlags flags, deBool dstOffset)
256 {
257 	flags |= vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
258 
259 	output.resize(queryCount);
260 
261 	void* allocationData = allocation.getHostPtr();
262 	vk::invalidateAlloc(vk, device, allocation);
263 
264 	if (flags & vk::VK_QUERY_RESULT_64_BIT)
265 	{
266 		constexpr size_t	stride		= sizeof(ResultsVectorWithAvailability::value_type);
267 		const size_t		totalSize	= stride * output.size();
268 		const deUint32		offset		= dstOffset ? 1u : 0u;
269 		deMemcpy(output.data(), (reinterpret_cast<ResultsVectorWithAvailability::value_type*>(allocationData) + offset), totalSize);
270 	}
271 	else
272 	{
273 		using IntermediateVector = vector<Pair32>;
274 
275 		IntermediateVector	intermediate(queryCount);
276 
277 		// Try to preserve existing output data if possible.
278 		std::transform(begin(output), end(output), begin(intermediate), [](const Pair64& p) { return Pair32{static_cast<deUint32>(p.first), static_cast<deUint32>(p.second)}; });
279 
280 		constexpr size_t	stride		= sizeof(decltype(intermediate)::value_type);
281 		const size_t		totalSize	= stride * intermediate.size();
282 		const deUint32		offset		= dstOffset ? 1u : 0u;
283 
284 		// Get and copy.
285 		deMemcpy(intermediate.data(), (reinterpret_cast<decltype(intermediate)::value_type*>(allocationData) + offset), totalSize);
286 		std::transform(begin(intermediate), end(intermediate), begin(output), [](const Pair32& p) { return Pair64{p.first, p.second}; });
287 	}
288 }
289 
290 // Generic parameters structure.
291 struct GenericParameters
292 {
293 	ResetType	resetType;
294 	CopyType	copyType;
295 	deBool		query64Bits;
296 	deBool		dstOffset;
297 
GenericParametersvkt::QueryPool::__anonc1410ac00111::GenericParameters298 	GenericParameters (ResetType resetType_, CopyType copyType_, deBool query64Bits_, deBool dstOffset_)
299 		: resetType{resetType_}, copyType{copyType_}, query64Bits{query64Bits_}, dstOffset{dstOffset_}
300 		{}
301 
querySizeFlagsvkt::QueryPool::__anonc1410ac00111::GenericParameters302 	VkQueryResultFlags querySizeFlags () const
303 	{
304 		return (query64Bits ? static_cast<VkQueryResultFlags>(vk::VK_QUERY_RESULT_64_BIT) : 0u);
305 	}
306 };
307 
beginSecondaryCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkQueryPipelineStatisticFlags queryFlags,const VkRenderPass renderPass=(VkRenderPass)0u,const VkFramebuffer framebuffer=(VkFramebuffer)0u,const VkCommandBufferUsageFlags bufferUsageFlags=VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)308 void beginSecondaryCommandBuffer (const DeviceInterface&				vk,
309 								  const VkCommandBuffer					commandBuffer,
310 								  const VkQueryPipelineStatisticFlags	queryFlags,
311 								  const VkRenderPass					renderPass = (VkRenderPass)0u,
312 								  const VkFramebuffer					framebuffer = (VkFramebuffer)0u,
313 								  const VkCommandBufferUsageFlags		bufferUsageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)
314 {
315 	const VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
316 	{
317 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
318 		DE_NULL,
319 		renderPass,					// renderPass
320 		0u,							// subpass
321 		framebuffer,				// framebuffer
322 		VK_FALSE,					// occlusionQueryEnable
323 		(VkQueryControlFlags)0u,	// queryFlags
324 		queryFlags,					// pipelineStatistics
325 	};
326 
327 	const VkCommandBufferBeginInfo			info					=
328 	{
329 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType							sType;
330 		DE_NULL,										// const void*								pNext;
331 		bufferUsageFlags,								// VkCommandBufferUsageFlags				flags;
332 		&secCmdBufInheritInfo,							// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
333 	};
334 	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
335 }
336 
makeQueryPool(const DeviceInterface & vk,const VkDevice device,deUint32 queryCount,VkQueryPipelineStatisticFlags statisticFlags)337 Move<VkQueryPool> makeQueryPool (const DeviceInterface& vk, const VkDevice device, deUint32 queryCount, VkQueryPipelineStatisticFlags statisticFlags )
338 {
339 	const VkQueryPoolCreateInfo queryPoolCreateInfo =
340 	{
341 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType					sType
342 		DE_NULL,									// const void*						pNext
343 		(VkQueryPoolCreateFlags)0,					// VkQueryPoolCreateFlags			flags
344 		VK_QUERY_TYPE_PIPELINE_STATISTICS ,			// VkQueryType						queryType
345 		queryCount,									// deUint32							entryCount
346 		statisticFlags,								// VkQueryPipelineStatisticFlags	pipelineStatistics
347 	};
348 	return createQueryPool(vk, device, &queryPoolCreateInfo);
349 }
350 
calculatePearsonCorrelation(const std::vector<deUint64> & x,const ResultsVector & y)351 double calculatePearsonCorrelation(const std::vector<deUint64>& x, const ResultsVector& y)
352 {
353 	// This function calculates Pearson correlation coefficient ( https://en.wikipedia.org/wiki/Pearson_correlation_coefficient )
354 	// Two statistical variables are linear ( == fully corellated ) when fabs( Pearson corelation coefficient ) == 1
355 	// Two statistical variables are independent when pearson corelation coefficient == 0
356 	// If fabs( Pearson coefficient ) is > 0.8 then these two variables are almost linear
357 
358 	DE_ASSERT(x.size() == y.size());
359 	DE_ASSERT(x.size() > 1);
360 
361 	// calculate mean values
362 	double xMean = 0.0, yMean = 0.0;
363 	for (deUint32 i = 0; i < x.size(); ++i)
364 	{
365 		xMean += static_cast<double>(x[i]);
366 		yMean += static_cast<double>(y[i]);
367 	}
368 	xMean /= static_cast<double>(x.size());
369 	yMean /= static_cast<double>(x.size());
370 
371 	// calculate standard deviations
372 	double xS = 0.0, yS = 0.0;
373 	for (deUint32 i = 0; i < x.size(); ++i)
374 	{
375 		double xv = static_cast<double>(x[i]) - xMean;
376 		double yv = static_cast<double>(y[i]) - yMean;
377 
378 		xS += xv * xv;
379 		yS += yv * yv;
380 	}
381 	xS = sqrt( xS / static_cast<double>(x.size() - 1) );
382 	yS = sqrt( yS / static_cast<double>(x.size() - 1) );
383 
384 	// calculate Pearson coefficient
385 	double pearson = 0.0;
386 	for (deUint32 i = 0; i < x.size(); ++i)
387 	{
388 		double xv = (static_cast<double>(x[i]) - xMean ) / xS;
389 		double yv = (static_cast<double>(y[i]) - yMean ) / yS;
390 		pearson   += xv * yv;
391 	}
392 
393 	return pearson / static_cast<double>(x.size() - 1);
394 }
395 
calculatePearsonCorrelation(const std::vector<deUint64> & x,const ResultsVectorWithAvailability & ya)396 double calculatePearsonCorrelation(const std::vector<deUint64>& x, const ResultsVectorWithAvailability& ya)
397 {
398 	ResultsVector y;
399 	for (const auto& elt : ya)
400 		y.push_back(elt.first);
401 	return calculatePearsonCorrelation(x, y);
402 }
403 
clearBuffer(const DeviceInterface & vk,const VkDevice device,const de::SharedPtr<Buffer> buffer,const VkDeviceSize bufferSizeBytes)404 void clearBuffer (const DeviceInterface& vk, const VkDevice device, const de::SharedPtr<Buffer> buffer, const VkDeviceSize bufferSizeBytes)
405 {
406 	const std::vector<deUint8>	data			((size_t)bufferSizeBytes, 0u);
407 	const Allocation&			allocation		= buffer->getBoundMemory();
408 	void*						allocationData	= allocation.getHostPtr();
409 	invalidateAlloc(vk, device, allocation);
410 	deMemcpy(allocationData, &data[0], (size_t)bufferSizeBytes);
411 }
412 
413 class StatisticQueryTestInstance : public TestInstance
414 {
415 public:
416 					StatisticQueryTestInstance	(Context& context, deUint32 queryCount, deBool dstOffset);
417 
418 protected:
419 	struct ValueAndAvailability
420 	{
421 		deUint64 value;
422 		deUint64 availability;
423 	};
424 
425 	VkDeviceSize m_resetBufferSize;
426 	de::SharedPtr<Buffer> m_resetBuffer;
427 	deBool dstOffset;
428 
429 	virtual void			checkExtensions		(deBool hostResetQueryEnabled);
430 	tcu::TestStatus			verifyUnavailable	();
431 };
432 
StatisticQueryTestInstance(Context & context,deUint32 queryCount,deBool dstOffset_)433 StatisticQueryTestInstance::StatisticQueryTestInstance (Context& context, deUint32 queryCount, deBool dstOffset_)
434 	: TestInstance	(context)
435 	, m_resetBufferSize((queryCount + (dstOffset_ ? 1u : 0u)) * sizeof(ValueAndAvailability))
436 	, m_resetBuffer (Buffer::createAndAlloc(context.getDeviceInterface(),
437 											context.getDevice(),
438 											BufferCreateInfo(m_resetBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
439 											context.getDefaultAllocator(),
440 											vk::MemoryRequirement::HostVisible))
441 	, dstOffset		(dstOffset_)
442 {
443 	const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
444 	void* allocationData = allocation.getHostPtr();
445 	deMemset(allocationData, 0xff, static_cast<size_t>(m_resetBufferSize));
446 	flushAlloc(context.getDeviceInterface(), context.getDevice(), allocation);
447 }
448 
checkExtensions(deBool hostResetQueryEnabled)449 void StatisticQueryTestInstance::checkExtensions (deBool hostResetQueryEnabled)
450 {
451 	if (!m_context.getDeviceFeatures().pipelineStatisticsQuery)
452 		throw tcu::NotSupportedError("Pipeline statistics queries are not supported");
453 
454 	if (hostResetQueryEnabled == DE_TRUE)
455 	{
456 		// Check VK_EXT_host_query_reset is supported
457 		m_context.requireDeviceFunctionality("VK_EXT_host_query_reset");
458 		if(m_context.getHostQueryResetFeatures().hostQueryReset == VK_FALSE)
459 			throw tcu::NotSupportedError(std::string("Implementation doesn't support resetting queries from the host").c_str());
460 	}
461 }
462 
verifyUnavailable()463 tcu::TestStatus	StatisticQueryTestInstance::verifyUnavailable ()
464 {
465 	const vk::Allocation& allocation	= m_resetBuffer->getBoundMemory();
466 	const void* allocationData			= allocation.getHostPtr();
467 	deUint32 size						= dstOffset ? 2 : 1;
468 	std::vector<ValueAndAvailability>	va;
469 	va.resize(size);
470 
471 	vk::invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), allocation);
472 	deMemcpy(va.data(), allocationData, size * sizeof(ValueAndAvailability));
473 
474 	deBool failed = false;
475 	for (deUint32 idx = 0u; idx < size; idx++)
476 	{
477 		if (dstOffset && idx == 0)
478 		{
479 			// Check that the contents between 0 and dstOffset were not overwritten.
480 			failed |= va[idx].availability != 0xfffffffffffffffful || va[idx].value != 0xfffffffffffffffful;
481 			continue;
482 		}
483 
484 		failed |= va[idx].availability != 0;
485 	}
486 
487 	return failed ? tcu::TestStatus::fail("Availability bit nonzero after resetting query or dstOffset wrong values") : tcu::TestStatus::pass("Pass");
488 }
489 
490 class ComputeInvocationsTestInstance : public StatisticQueryTestInstance
491 {
492 public:
493 	struct ParametersCompute : public GenericParameters
494 	{
ParametersComputevkt::QueryPool::__anonc1410ac00111::ComputeInvocationsTestInstance::ParametersCompute495 		ParametersCompute (const tcu::UVec3& localSize_, const tcu::UVec3& groupSize_, const std::string& shaderName_, ResetType resetType_, CopyType copyType_, deBool query64Bits_, bool dstOffset_)
496 			: GenericParameters{resetType_, copyType_, query64Bits_, dstOffset_}
497 			, localSize(localSize_)
498 			, groupSize(groupSize_)
499 			, shaderName(shaderName_)
500 			{}
501 
502 		tcu::UVec3	localSize;
503 		tcu::UVec3	groupSize;
504 		std::string	shaderName;
505 	};
506 							ComputeInvocationsTestInstance		(Context& context, const std::vector<ParametersCompute>& parameters);
507 	tcu::TestStatus			iterate								(void);
508 protected:
509 	virtual tcu::TestStatus	executeTest							(const VkCommandPool&			cmdPool,
510 																 const VkPipelineLayout			pipelineLayout,
511 																 const VkDescriptorSet&			descriptorSet,
512 																 const de::SharedPtr<Buffer>	buffer,
513 																 const VkDeviceSize				bufferSizeBytes);
getComputeExecution(const ParametersCompute & parm) const514 	deUint32				getComputeExecution					(const ParametersCompute& parm) const
515 		{
516 			return parm.localSize.x() * parm.localSize.y() *parm.localSize.z() * parm.groupSize.x() * parm.groupSize.y() * parm.groupSize.z();
517 		}
518 	const std::vector<ParametersCompute>&	m_parameters;
519 };
520 
ComputeInvocationsTestInstance(Context & context,const std::vector<ParametersCompute> & parameters)521 ComputeInvocationsTestInstance::ComputeInvocationsTestInstance (Context& context, const std::vector<ParametersCompute>& parameters)
522 	: StatisticQueryTestInstance	(context, 1u, parameters[0].dstOffset)
523 	, m_parameters					(parameters)
524 {
525 }
526 
iterate(void)527 tcu::TestStatus	ComputeInvocationsTestInstance::iterate (void)
528 {
529 	checkExtensions((m_parameters[0].resetType == RESET_TYPE_HOST)? DE_TRUE : DE_FALSE);
530 	const DeviceInterface&				vk						= m_context.getDeviceInterface();
531 	const VkDevice						device					= m_context.getDevice();
532 	deUint32							maxSize					= 0u;
533 
534 	for(size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
535 		maxSize = deMaxu32(maxSize, getComputeExecution(m_parameters[parametersNdx]));
536 
537 	const VkDeviceSize					bufferSizeBytes			= static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>(sizeof(deUint32) * maxSize),
538 																								static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
539 	de::SharedPtr<Buffer>				buffer					= Buffer::createAndAlloc(vk, device, BufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
540 																							 m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
541 
542 	const Unique<VkDescriptorSetLayout>	descriptorSetLayout		(DescriptorSetLayoutBuilder()
543 			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
544 			.build(vk, device));
545 
546 	const Unique<VkPipelineLayout>		pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
547 
548 	const Unique<VkDescriptorPool>		descriptorPool			(DescriptorPoolBuilder()
549 			.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
550 			.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
551 
552 	const VkDescriptorSetAllocateInfo allocateParams		=
553 	{
554 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType				sType;
555 		DE_NULL,										// const void*					pNext;
556 		*descriptorPool,								// VkDescriptorPool				descriptorPool;
557 		1u,												// deUint32						setLayoutCount;
558 		&(*descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
559 	};
560 
561 	const Unique<VkDescriptorSet>		descriptorSet		(allocateDescriptorSet(vk, device, &allocateParams));
562 	const VkDescriptorBufferInfo		descriptorInfo		=
563 	{
564 		buffer->object(),	//VkBuffer		buffer;
565 		0ull,				//VkDeviceSize	offset;
566 		bufferSizeBytes,	//VkDeviceSize	range;
567 	};
568 
569 	DescriptorSetUpdateBuilder()
570 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
571 		.update(vk, device);
572 
573 	const CmdPoolCreateInfo			cmdPoolCreateInfo	(m_context.getUniversalQueueFamilyIndex());
574 	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, &cmdPoolCreateInfo));
575 
576 	return executeTest (*cmdPool, *pipelineLayout, *descriptorSet, buffer, bufferSizeBytes);
577 }
578 
executeTest(const VkCommandPool & cmdPool,const VkPipelineLayout pipelineLayout,const VkDescriptorSet & descriptorSet,const de::SharedPtr<Buffer> buffer,const VkDeviceSize bufferSizeBytes)579 tcu::TestStatus ComputeInvocationsTestInstance::executeTest (const VkCommandPool&			cmdPool,
580 															 const VkPipelineLayout			pipelineLayout,
581 															 const VkDescriptorSet&			descriptorSet,
582 															 const de::SharedPtr<Buffer>	buffer,
583 															 const VkDeviceSize				bufferSizeBytes)
584 {
585 	const DeviceInterface&				vk						= m_context.getDeviceInterface();
586 	const VkDevice						device					= m_context.getDevice();
587 	const VkQueue						queue					= m_context.getUniversalQueue();
588 	const VkBufferMemoryBarrier			computeFinishBarrier	=
589 	{
590 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,					// VkStructureType	sType;
591 		DE_NULL,													// const void*		pNext;
592 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,		// VkAccessFlags	srcAccessMask;
593 		VK_ACCESS_HOST_READ_BIT,									// VkAccessFlags	dstAccessMask;
594 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			srcQueueFamilyIndex;
595 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			destQueueFamilyIndex;
596 		buffer->object(),											// VkBuffer			buffer;
597 		0ull,														// VkDeviceSize		offset;
598 		bufferSizeBytes,											// VkDeviceSize		size;
599 	};
600 
601 	for(size_t parametersNdx = 0u; parametersNdx < m_parameters.size(); ++parametersNdx)
602 	{
603 		clearBuffer(vk, device, buffer, bufferSizeBytes);
604 		const Unique<VkShaderModule>			shaderModule				(createShaderModule(vk, device,
605 																			m_context.getBinaryCollection().get(m_parameters[parametersNdx].shaderName), (VkShaderModuleCreateFlags)0u));
606 
607 		const VkPipelineShaderStageCreateInfo	pipelineShaderStageParams	=
608 		{
609 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
610 			DE_NULL,												// const void*							pNext;
611 			(VkPipelineShaderStageCreateFlags)0u,					// VkPipelineShaderStageCreateFlags		flags;
612 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
613 			*shaderModule,											// VkShaderModule						module;
614 			"main",													// const char*							pName;
615 			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
616 		};
617 
618 		const VkComputePipelineCreateInfo		pipelineCreateInfo			=
619 		{
620 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType					sType;
621 			DE_NULL,										// const void*						pNext;
622 			(VkPipelineCreateFlags)0u,						// VkPipelineCreateFlags			flags;
623 			pipelineShaderStageParams,						// VkPipelineShaderStageCreateInfo	stage;
624 			pipelineLayout,									// VkPipelineLayout					layout;
625 			DE_NULL,										// VkPipeline						basePipelineHandle;
626 			0,												// deInt32							basePipelineIndex;
627 		};
628 		const Unique<VkPipeline> pipeline(createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo));
629 
630 		const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
631 		const Unique<VkQueryPool>		queryPool			(makeQueryPool(vk, device, 1u, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT));
632 
633 		beginCommandBuffer(vk, *cmdBuffer);
634 			if (m_parameters[0].resetType != RESET_TYPE_HOST)
635 				vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, 1u);
636 
637 			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
638 			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
639 
640 			vk.cmdBeginQuery(*cmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
641 			vk.cmdDispatch(*cmdBuffer, m_parameters[parametersNdx].groupSize.x(), m_parameters[parametersNdx].groupSize.y(), m_parameters[parametersNdx].groupSize.z());
642 			vk.cmdEndQuery(*cmdBuffer, *queryPool, 0u);
643 
644 			if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY || m_parameters[0].copyType == COPY_TYPE_CMD)
645 			{
646 				VkDeviceSize stride = m_parameters[0].querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
647 				vk::VkQueryResultFlags flags = m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
648 
649 				if (m_parameters[0].resetType == RESET_TYPE_HOST)
650 				{
651 					flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
652 					stride *= 2u;
653 				}
654 
655 				if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY)
656 				{
657 					vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, 1u);
658 					flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
659 					stride = sizeof(ValueAndAvailability);
660 				}
661 
662 				VkDeviceSize dstOffsetQuery = (m_parameters[0].dstOffset) ? stride : 0;
663 				vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, 1u, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
664 
665 				const VkBufferMemoryBarrier barrier =
666 				{
667 					VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
668 					DE_NULL,									//  const void*		pNext;
669 					VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
670 					VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
671 					VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
672 					VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
673 					m_resetBuffer->object(),					//  VkBuffer		buffer;
674 					0u,											//  VkDeviceSize	offset;
675 				    1u * stride + dstOffsetQuery,				//  VkDeviceSize	size;
676 				};
677 				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
678 			}
679 
680 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
681 				(VkDependencyFlags)0u, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &computeFinishBarrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
682 
683 		endCommandBuffer(vk, *cmdBuffer);
684 
685 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Compute shader invocations: " << getComputeExecution(m_parameters[parametersNdx]) << tcu::TestLog::EndMessage;
686 
687 		if (m_parameters[0].resetType == RESET_TYPE_HOST)
688 			vk.resetQueryPool(device, *queryPool, 0u, 1u);
689 
690 		// Wait for completion
691 		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
692 
693 		// Validate the results
694 		const Allocation& bufferAllocation = buffer->getBoundMemory();
695 		invalidateAlloc(vk, device, bufferAllocation);
696 
697 		if (m_parameters[0].resetType == RESET_TYPE_NORMAL)
698 		{
699 			ResultsVector data;
700 
701 			if (m_parameters[0].copyType == COPY_TYPE_CMD)
702 			{
703 				const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
704 				cmdCopyQueryPoolResultsVector(data, vk, device, allocation, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags()), m_parameters[0].dstOffset);
705 			}
706 			else
707 			{
708 				VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags())));
709 			}
710 
711 			if (getComputeExecution(m_parameters[parametersNdx]) != data[0])
712 				return tcu::TestStatus::fail("QueryPoolResults incorrect");
713 		}
714 		else if (m_parameters[0].resetType == RESET_TYPE_HOST)
715 		{
716 			ResultsVectorWithAvailability data;
717 
718 			if (m_parameters[0].copyType == COPY_TYPE_CMD)
719 			{
720 				const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
721 				cmdCopyQueryPoolResultsVector(data, vk, device, allocation, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT), m_parameters[0].dstOffset);
722 			}
723 			else
724 			{
725 				VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
726 			}
727 
728 			if (getComputeExecution(m_parameters[parametersNdx]) != data[0].first || data[0].second == 0)
729 				return tcu::TestStatus::fail("QueryPoolResults incorrect");
730 
731 			deUint64 temp = data[0].first;
732 
733 			vk.resetQueryPool(device, *queryPool, 0, 1u);
734 			vk::VkResult res = GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
735 			/* From Vulkan spec:
736 			 *
737 			 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
738 			 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
739 			 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
740 			 */
741 			if (res != vk::VK_NOT_READY || data[0].first != temp || data[0].second != 0u)
742 				return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
743 		}
744 		else
745 		{
746 			// With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
747 			return verifyUnavailable();
748 		}
749 
750 		const deUint32* bufferPtr = static_cast<deUint32*>(bufferAllocation.getHostPtr());
751 		for (deUint32 ndx = 0u; ndx < getComputeExecution(m_parameters[parametersNdx]); ++ndx)
752 		{
753 			if (bufferPtr[ndx] != ndx)
754 				return tcu::TestStatus::fail("Compute shader didn't write data to the buffer");
755 		}
756 	}
757 	return tcu::TestStatus::pass("Pass");
758 }
759 
760 class ComputeInvocationsSecondaryTestInstance : public ComputeInvocationsTestInstance
761 {
762 public:
763 							ComputeInvocationsSecondaryTestInstance	(Context& context, const std::vector<ParametersCompute>& parameters);
764 protected:
765 	tcu::TestStatus			executeTest								(const VkCommandPool&			cmdPool,
766 																	 const VkPipelineLayout			pipelineLayout,
767 																	 const VkDescriptorSet&			descriptorSet,
768 																	 const de::SharedPtr<Buffer>	buffer,
769 																	 const VkDeviceSize				bufferSizeBytes);
770 	virtual tcu::TestStatus	checkResult								(const de::SharedPtr<Buffer>	buffer,
771 																	 const VkQueryPool				queryPool);
772 };
773 
ComputeInvocationsSecondaryTestInstance(Context & context,const std::vector<ParametersCompute> & parameters)774 ComputeInvocationsSecondaryTestInstance::ComputeInvocationsSecondaryTestInstance	(Context& context, const std::vector<ParametersCompute>& parameters)
775 	: ComputeInvocationsTestInstance	(context, parameters)
776 {
777 }
778 
executeTest(const VkCommandPool & cmdPool,const VkPipelineLayout pipelineLayout,const VkDescriptorSet & descriptorSet,const de::SharedPtr<Buffer> buffer,const VkDeviceSize bufferSizeBytes)779 tcu::TestStatus ComputeInvocationsSecondaryTestInstance::executeTest (const VkCommandPool&			cmdPool,
780 																	  const VkPipelineLayout		pipelineLayout,
781 																	  const VkDescriptorSet&		descriptorSet,
782 																	  const de::SharedPtr<Buffer>	buffer,
783 																	  const VkDeviceSize			bufferSizeBytes)
784 {
785 	typedef de::SharedPtr<Unique<VkShaderModule> >	VkShaderModuleSp;
786 	typedef de::SharedPtr<Unique<VkPipeline> >		VkPipelineSp;
787 
788 	const DeviceInterface&					vk							= m_context.getDeviceInterface();
789 	const VkDevice							device						= m_context.getDevice();
790 	const VkQueue							queue						= m_context.getUniversalQueue();
791 
792 	const VkBufferMemoryBarrier				computeShaderWriteBarrier	=
793 	{
794 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,					// VkStructureType	sType;
795 		DE_NULL,													// const void*		pNext;
796 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,		// VkAccessFlags	srcAccessMask;
797 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,		// VkAccessFlags	dstAccessMask;
798 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			srcQueueFamilyIndex;
799 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			destQueueFamilyIndex;
800 		buffer->object(),											// VkBuffer			buffer;
801 		0ull,														// VkDeviceSize		offset;
802 		bufferSizeBytes,											// VkDeviceSize		size;
803 	};
804 
805 	const VkBufferMemoryBarrier				computeFinishBarrier		=
806 	{
807 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,					// VkStructureType	sType;
808 		DE_NULL,													// const void*		pNext;
809 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,		// VkAccessFlags	srcAccessMask;
810 		VK_ACCESS_HOST_READ_BIT,									// VkAccessFlags	dstAccessMask;
811 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			srcQueueFamilyIndex;
812 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			destQueueFamilyIndex;
813 		buffer->object(),											// VkBuffer			buffer;
814 		0ull,														// VkDeviceSize		offset;
815 		bufferSizeBytes,											// VkDeviceSize		size;
816 	};
817 
818 	std::vector<VkShaderModuleSp>			shaderModule;
819 	std::vector<VkPipelineSp>				pipeline;
820 	for(size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
821 	{
822 		shaderModule.push_back(VkShaderModuleSp(new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(m_parameters[parametersNdx].shaderName), (VkShaderModuleCreateFlags)0u))));
823 		const VkPipelineShaderStageCreateInfo	pipelineShaderStageParams	=
824 		{
825 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
826 			DE_NULL,												// const void*							pNext;
827 			0u,														// VkPipelineShaderStageCreateFlags		flags;
828 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
829 			shaderModule.back().get()->get(),						// VkShaderModule						module;
830 			"main",													// const char*							pName;
831 			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
832 		};
833 
834 		const VkComputePipelineCreateInfo		pipelineCreateInfo			=
835 		{
836 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType					sType;
837 			DE_NULL,										// const void*						pNext;
838 			0u,												// VkPipelineCreateFlags			flags;
839 			pipelineShaderStageParams,						// VkPipelineShaderStageCreateInfo	stage;
840 			pipelineLayout,									// VkPipelineLayout					layout;
841 			DE_NULL,										// VkPipeline						basePipelineHandle;
842 			0,												// deInt32							basePipelineIndex;
843 		};
844 		pipeline.push_back(VkPipelineSp(new Unique<VkPipeline>(createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo))));
845 	}
846 
847 	const Unique<VkCommandBuffer>				primaryCmdBuffer			(allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
848 	const Unique<VkCommandBuffer>				secondaryCmdBuffer			(allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY));
849 
850 	const Unique<VkQueryPool>					queryPool					(makeQueryPool(vk, device, 1u, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT));
851 
852 	clearBuffer(vk, device, buffer, bufferSizeBytes);
853 	beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT);
854 		vk.cmdBindDescriptorSets(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
855 		if (m_parameters[0].resetType != RESET_TYPE_HOST)
856 			vk.cmdResetQueryPool(*secondaryCmdBuffer, *queryPool, 0u, 1u);
857 		vk.cmdBeginQuery(*secondaryCmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
858 		for(size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
859 		{
860 				vk.cmdBindPipeline(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline[parametersNdx].get()->get());
861 				vk.cmdDispatch(*secondaryCmdBuffer, m_parameters[parametersNdx].groupSize.x(), m_parameters[parametersNdx].groupSize.y(), m_parameters[parametersNdx].groupSize.z());
862 
863 				vk.cmdPipelineBarrier(*secondaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
864 					(VkDependencyFlags)0u, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &computeShaderWriteBarrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
865 		}
866 		vk.cmdEndQuery(*secondaryCmdBuffer, *queryPool, 0u);
867 
868 		if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY || m_parameters[0].copyType == COPY_TYPE_CMD)
869 		{
870 			VkDeviceSize stride = m_parameters[0].querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
871 			vk::VkQueryResultFlags flags = m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
872 
873 			if (m_parameters[0].resetType == RESET_TYPE_HOST)
874 			{
875 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
876 				stride *= 2u;
877 			}
878 
879 			if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY)
880 			{
881 				vk.cmdResetQueryPool(*secondaryCmdBuffer, *queryPool, 0u, 1u);
882 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
883 				stride = sizeof(ValueAndAvailability);
884 			}
885 
886 			VkDeviceSize dstOffsetQuery = (m_parameters[0].dstOffset) ? stride : 0;
887 			vk.cmdCopyQueryPoolResults(*secondaryCmdBuffer, *queryPool, 0, 1u, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
888 
889 			const VkBufferMemoryBarrier barrier =
890 			{
891 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
892 				DE_NULL,									//  const void*		pNext;
893 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
894 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
895 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
896 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
897 				m_resetBuffer->object(),					//  VkBuffer		buffer;
898 				0u,											//  VkDeviceSize	offset;
899 				1u * stride + dstOffsetQuery,				//  VkDeviceSize	size;
900 			};
901 			vk.cmdPipelineBarrier(*secondaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
902 		}
903 
904 	endCommandBuffer(vk, *secondaryCmdBuffer);
905 
906 	beginCommandBuffer(vk, *primaryCmdBuffer);
907 		vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &secondaryCmdBuffer.get());
908 
909 		vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
910 			(VkDependencyFlags)0u, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &computeFinishBarrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
911 
912 	endCommandBuffer(vk, *primaryCmdBuffer);
913 
914 	// Secondary buffer is emitted only once, so it is safe to reset the query pool here.
915 	if (m_parameters[0].resetType == RESET_TYPE_HOST)
916 		vk.resetQueryPool(device, *queryPool, 0u, 1u);
917 
918 	// Wait for completion
919 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
920 	return checkResult(buffer, *queryPool);
921 }
922 
checkResult(const de::SharedPtr<Buffer> buffer,const VkQueryPool queryPool)923 tcu::TestStatus ComputeInvocationsSecondaryTestInstance::checkResult (const de::SharedPtr<Buffer> buffer, const VkQueryPool queryPool)
924 {
925 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
926 	const VkDevice			device				= m_context.getDevice();
927 	{
928 		deUint64 expected	= 0u;
929 		for(size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
930 			expected += getComputeExecution(m_parameters[parametersNdx]);
931 
932 		if (m_parameters[0].resetType == RESET_TYPE_NORMAL)
933 		{
934 			ResultsVector results;
935 			if (m_parameters[0].copyType == COPY_TYPE_CMD)
936 			{
937 				const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
938 				cmdCopyQueryPoolResultsVector(results, vk, device, allocation, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags()), m_parameters[0].dstOffset);
939 			}
940 			else
941 			{
942 				VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags())));
943 			}
944 
945 			if (expected != results[0])
946 				return tcu::TestStatus::fail("QueryPoolResults incorrect");
947 		}
948 		else if (m_parameters[0].resetType == RESET_TYPE_HOST)
949 		{
950 			ResultsVectorWithAvailability results;
951 
952 			if (m_parameters[0].copyType == COPY_TYPE_CMD)
953 			{
954 				const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
955 				cmdCopyQueryPoolResultsVector(results, vk, device, allocation, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT), m_parameters[0].dstOffset);
956 			}
957 			else
958 			{
959 				VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
960 			}
961 
962 			if (expected != results[0].first || results[0].second == 0u)
963 				return tcu::TestStatus::fail("QueryPoolResults incorrect");
964 
965 			deUint64 temp = results[0].first;
966 
967 			vk.resetQueryPool(device, queryPool, 0u, 1u);
968 			vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
969 			/* From Vulkan spec:
970 			 *
971 			 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
972 			 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
973 			 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
974 			 */
975 			if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0u)
976 				return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
977 		}
978 		else
979 		{
980 			// With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
981 			return verifyUnavailable();
982 		}
983 
984 	}
985 
986 	{
987 		// Validate the results
988 		const Allocation&	bufferAllocation	= buffer->getBoundMemory();
989 		invalidateAlloc(vk, device, bufferAllocation);
990 		const deUint32*		bufferPtr			= static_cast<deUint32*>(bufferAllocation.getHostPtr());
991 		deUint32			minSize				= ~0u;
992 		for(size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
993 			minSize = deMinu32(minSize, getComputeExecution(m_parameters[parametersNdx]));
994 		for (deUint32 ndx = 0u; ndx < minSize; ++ndx)
995 		{
996 			if (bufferPtr[ndx] != ndx * m_parameters.size())
997 				return tcu::TestStatus::fail("Compute shader didn't write data to the buffer");
998 		}
999 	}
1000 	return tcu::TestStatus::pass("Pass");
1001 }
1002 
1003 class ComputeInvocationsSecondaryInheritedTestInstance : public ComputeInvocationsSecondaryTestInstance
1004 {
1005 public:
1006 					ComputeInvocationsSecondaryInheritedTestInstance	(Context& context, const std::vector<ParametersCompute>& parameters);
1007 protected:
1008 	virtual void	checkExtensions							(deBool hostResetQueryEnabled);
1009 
1010 	tcu::TestStatus	executeTest								(const VkCommandPool&			cmdPool,
1011 															 const VkPipelineLayout			pipelineLayout,
1012 															 const VkDescriptorSet&			descriptorSet,
1013 															 const de::SharedPtr<Buffer>	buffer,
1014 															 const VkDeviceSize				bufferSizeBytes);
1015 };
1016 
ComputeInvocationsSecondaryInheritedTestInstance(Context & context,const std::vector<ParametersCompute> & parameters)1017 ComputeInvocationsSecondaryInheritedTestInstance::ComputeInvocationsSecondaryInheritedTestInstance	(Context& context, const std::vector<ParametersCompute>& parameters)
1018 	: ComputeInvocationsSecondaryTestInstance	(context, parameters)
1019 {
1020 }
1021 
checkExtensions(deBool hostResetQueryEnabled)1022 void ComputeInvocationsSecondaryInheritedTestInstance::checkExtensions (deBool hostResetQueryEnabled)
1023 {
1024 	StatisticQueryTestInstance::checkExtensions(hostResetQueryEnabled);
1025 	if (!m_context.getDeviceFeatures().inheritedQueries)
1026 		throw tcu::NotSupportedError("Inherited queries are not supported");
1027 }
1028 
executeTest(const VkCommandPool & cmdPool,const VkPipelineLayout pipelineLayout,const VkDescriptorSet & descriptorSet,const de::SharedPtr<Buffer> buffer,const VkDeviceSize bufferSizeBytes)1029 tcu::TestStatus ComputeInvocationsSecondaryInheritedTestInstance::executeTest (const VkCommandPool&			cmdPool,
1030 																			  const VkPipelineLayout		pipelineLayout,
1031 																			  const VkDescriptorSet&		descriptorSet,
1032 																			  const de::SharedPtr<Buffer>	buffer,
1033 																			  const VkDeviceSize			bufferSizeBytes)
1034 {
1035 	typedef de::SharedPtr<Unique<VkShaderModule> >	VkShaderModuleSp;
1036 	typedef de::SharedPtr<Unique<VkPipeline> >		VkPipelineSp;
1037 
1038 	const DeviceInterface&						vk								= m_context.getDeviceInterface();
1039 	const VkDevice								device							= m_context.getDevice();
1040 	const VkQueue								queue							= m_context.getUniversalQueue();
1041 
1042 	const VkBufferMemoryBarrier					computeShaderWriteBarrier		=
1043 	{
1044 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,					// VkStructureType	sType;
1045 		DE_NULL,													// const void*		pNext;
1046 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,		// VkAccessFlags	srcAccessMask;
1047 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,		// VkAccessFlags	dstAccessMask;
1048 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			srcQueueFamilyIndex;
1049 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			destQueueFamilyIndex;
1050 		buffer->object(),											// VkBuffer			buffer;
1051 		0ull,														// VkDeviceSize		offset;
1052 		bufferSizeBytes,											// VkDeviceSize		size;
1053 	};
1054 
1055 	const VkBufferMemoryBarrier					computeFinishBarrier			=
1056 	{
1057 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,					// VkStructureType	sType;
1058 		DE_NULL,													// const void*		pNext;
1059 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,		// VkAccessFlags	srcAccessMask;
1060 		VK_ACCESS_HOST_READ_BIT,									// VkAccessFlags	dstAccessMask;
1061 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			srcQueueFamilyIndex;
1062 		VK_QUEUE_FAMILY_IGNORED,									// deUint32			destQueueFamilyIndex;
1063 		buffer->object(),											// VkBuffer			buffer;
1064 		0ull,														// VkDeviceSize		offset;
1065 		bufferSizeBytes,											// VkDeviceSize		size;
1066 	};
1067 
1068 	std::vector<VkShaderModuleSp>				shaderModule;
1069 	std::vector<VkPipelineSp>					pipeline;
1070 	for(size_t parametersNdx = 0u; parametersNdx < m_parameters.size(); ++parametersNdx)
1071 	{
1072 		shaderModule.push_back(VkShaderModuleSp(new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(m_parameters[parametersNdx].shaderName), (VkShaderModuleCreateFlags)0u))));
1073 		const VkPipelineShaderStageCreateInfo	pipelineShaderStageParams		=
1074 		{
1075 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
1076 			DE_NULL,												// const void*						pNext;
1077 			0u,														// VkPipelineShaderStageCreateFlags	flags;
1078 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
1079 			shaderModule.back().get()->get(),						// VkShaderModule					module;
1080 			"main",													// const char*						pName;
1081 			DE_NULL,												// const VkSpecializationInfo*		pSpecializationInfo;
1082 		};
1083 
1084 		const VkComputePipelineCreateInfo		pipelineCreateInfo				=
1085 		{
1086 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType					sType;
1087 			DE_NULL,										// const void*						pNext;
1088 			0u,												// VkPipelineCreateFlags			flags;
1089 			pipelineShaderStageParams,						// VkPipelineShaderStageCreateInfo	stage;
1090 			pipelineLayout,									// VkPipelineLayout					layout;
1091 			DE_NULL,										// VkPipeline						basePipelineHandle;
1092 			0,												// deInt32							basePipelineIndex;
1093 		};
1094 		pipeline.push_back(VkPipelineSp(new Unique<VkPipeline>(createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo))));
1095 	}
1096 
1097 	const Unique<VkCommandBuffer>				primaryCmdBuffer			(allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1098 	const Unique<VkCommandBuffer>				secondaryCmdBuffer			(allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY));
1099 
1100 	const Unique<VkQueryPool>					queryPool					(makeQueryPool(vk, device, 1u, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT));
1101 
1102 	clearBuffer(vk, device, buffer, bufferSizeBytes);
1103 	beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT);
1104 		vk.cmdBindDescriptorSets(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1105 		for(size_t parametersNdx = 1; parametersNdx < m_parameters.size(); ++parametersNdx)
1106 		{
1107 				vk.cmdBindPipeline(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline[parametersNdx].get()->get());
1108 				vk.cmdDispatch(*secondaryCmdBuffer, m_parameters[parametersNdx].groupSize.x(), m_parameters[parametersNdx].groupSize.y(), m_parameters[parametersNdx].groupSize.z());
1109 
1110 				vk.cmdPipelineBarrier(*secondaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
1111 					(VkDependencyFlags)0u, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &computeShaderWriteBarrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
1112 		}
1113 	endCommandBuffer(vk, *secondaryCmdBuffer);
1114 
1115 	beginCommandBuffer(vk, *primaryCmdBuffer);
1116 		if (m_parameters[0].resetType != RESET_TYPE_HOST)
1117 			vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, 1u);
1118 		vk.cmdBindDescriptorSets(*primaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
1119 		vk.cmdBindPipeline(*primaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline[0].get()->get());
1120 
1121 		vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
1122 		vk.cmdDispatch(*primaryCmdBuffer, m_parameters[0].groupSize.x(), m_parameters[0].groupSize.y(), m_parameters[0].groupSize.z());
1123 
1124 		vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
1125 				(VkDependencyFlags)0u, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &computeShaderWriteBarrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
1126 
1127 		vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &secondaryCmdBuffer.get());
1128 
1129 		vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1130 			(VkDependencyFlags)0u, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &computeFinishBarrier, 0u, (const VkImageMemoryBarrier*)DE_NULL);
1131 
1132 		vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, 0u);
1133 
1134 		if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY || m_parameters[0].copyType == COPY_TYPE_CMD)
1135 		{
1136 			VkDeviceSize stride = m_parameters[0].querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
1137 			vk::VkQueryResultFlags flags = m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
1138 
1139 			if (m_parameters[0].resetType == RESET_TYPE_HOST)
1140 			{
1141 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1142 				stride *= 2u;
1143 			}
1144 
1145 			if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY)
1146 			{
1147 				vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, 1u);
1148 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1149 				stride = sizeof(ValueAndAvailability);
1150 			}
1151 
1152 			VkDeviceSize dstOffsetQuery = (m_parameters[0].dstOffset) ? stride : 0;
1153 			vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, 1u, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
1154 
1155 			const VkBufferMemoryBarrier barrier =
1156 			{
1157 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
1158 				DE_NULL,									//  const void*		pNext;
1159 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
1160 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
1161 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
1162 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
1163 				m_resetBuffer->object(),					//  VkBuffer		buffer;
1164 				0u,											//  VkDeviceSize	offset;
1165 			    1u * stride + dstOffsetQuery,				//  VkDeviceSize	size;
1166 			};
1167 			vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1168 		}
1169 
1170 	endCommandBuffer(vk, *primaryCmdBuffer);
1171 
1172 	if (m_parameters[0].resetType == RESET_TYPE_HOST)
1173 		vk.resetQueryPool(device, *queryPool, 0u, 1u);
1174 
1175 	// Wait for completion
1176 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
1177 	return checkResult(buffer, *queryPool);
1178 }
1179 
1180 class GraphicBasicTestInstance : public StatisticQueryTestInstance
1181 {
1182 public:
1183 	struct VertexData
1184 	{
VertexDatavkt::QueryPool::__anonc1410ac00111::GraphicBasicTestInstance::VertexData1185 		VertexData (const tcu::Vec4 position_, const tcu::Vec4 color_)
1186 			: position	(position_)
1187 			, color		(color_)
1188 		{}
1189 		tcu::Vec4	position;
1190 		tcu::Vec4	color;
1191 	};
1192 
1193 	struct ParametersGraphic : public GenericParameters
1194 	{
ParametersGraphicvkt::QueryPool::__anonc1410ac00111::GraphicBasicTestInstance::ParametersGraphic1195 		ParametersGraphic (const VkQueryPipelineStatisticFlags queryStatisticFlags_, const VkPrimitiveTopology primitiveTopology_, const ResetType resetType_, const CopyType copyType_, const deBool query64Bits_, const deBool vertexOnlyPipe_ = DE_FALSE, const deBool dstOffset_ = DE_FALSE)
1196 			: GenericParameters		{resetType_, copyType_, query64Bits_, dstOffset_}
1197 			, queryStatisticFlags	(queryStatisticFlags_)
1198 			, primitiveTopology		(primitiveTopology_)
1199 			, vertexOnlyPipe		(vertexOnlyPipe_)
1200 			{}
1201 
1202 		VkQueryPipelineStatisticFlags	queryStatisticFlags;
1203 		VkPrimitiveTopology				primitiveTopology;
1204 		deBool							vertexOnlyPipe;
1205 	};
1206 											GraphicBasicTestInstance			(vkt::Context&					context,
1207 																				 const std::vector<VertexData>&	data,
1208 																				 const ParametersGraphic&		parametersGraphic,
1209 																				 const std::vector<deUint64>&	drawRepeats );
1210 	tcu::TestStatus							iterate								(void);
1211 protected:
1212 	de::SharedPtr<Buffer>					creatAndFillVertexBuffer			(void);
1213 	virtual void							createPipeline						(void) = 0;
1214 	void									creatColorAttachmentAndRenderPass	(void);
1215 	bool									checkImage							(void);
1216 	virtual tcu::TestStatus					executeTest							(void) = 0;
1217 	virtual tcu::TestStatus					checkResult							(VkQueryPool queryPool) = 0;
1218 	virtual void							draw								(VkCommandBuffer cmdBuffer) = 0;
1219 
1220 	const VkFormat						m_colorAttachmentFormat;
1221 	de::SharedPtr<Image>				m_colorAttachmentImage;
1222 	de::SharedPtr<Image>				m_depthImage;
1223 	Move<VkImageView>					m_attachmentView;
1224 	Move<VkImageView>					m_depthiew;
1225 	Move<VkRenderPass>					m_renderPass;
1226 	Move<VkFramebuffer>					m_framebuffer;
1227 	Move<VkPipeline>					m_pipeline;
1228 	Move<VkPipelineLayout>				m_pipelineLayout;
1229 	const std::vector<VertexData>&		m_data;
1230 	const ParametersGraphic&			m_parametersGraphic;
1231 	std::vector<deUint64>				m_drawRepeats;
1232 };
1233 
GraphicBasicTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)1234 GraphicBasicTestInstance::GraphicBasicTestInstance (vkt::Context&					context,
1235 													const std::vector<VertexData>&	data,
1236 													const ParametersGraphic&		parametersGraphic,
1237 													const std::vector<deUint64>&	drawRepeats )
1238 	: StatisticQueryTestInstance	(context, static_cast<deUint32>(drawRepeats.size()), parametersGraphic.dstOffset)
1239 	, m_colorAttachmentFormat		(VK_FORMAT_R8G8B8A8_UNORM)
1240 	, m_data						(data)
1241 	, m_parametersGraphic			(parametersGraphic)
1242 	, m_drawRepeats					(drawRepeats)
1243 {
1244 }
1245 
iterate(void)1246 tcu::TestStatus GraphicBasicTestInstance::iterate (void)
1247 {
1248 	checkExtensions((m_parametersGraphic.resetType == RESET_TYPE_HOST)? DE_TRUE : DE_FALSE);
1249 	creatColorAttachmentAndRenderPass();
1250 	createPipeline();
1251 	return executeTest();
1252 }
1253 
creatAndFillVertexBuffer(void)1254 de::SharedPtr<Buffer> GraphicBasicTestInstance::creatAndFillVertexBuffer (void)
1255 {
1256 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
1257 	const VkDevice				device			= m_context.getDevice();
1258 
1259 	const VkDeviceSize			dataSize		= static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>( m_data.size() * sizeof(VertexData)),
1260 		static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
1261 
1262 	de::SharedPtr<Buffer>		vertexBuffer	= Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize,
1263 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
1264 
1265 	deUint8*					ptr				= reinterpret_cast<deUint8*>(vertexBuffer->getBoundMemory().getHostPtr());
1266 	deMemcpy(ptr, &m_data[0], static_cast<size_t>( m_data.size() * sizeof(VertexData)));
1267 
1268 	flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(), vertexBuffer->getBoundMemory().getOffset(), dataSize);
1269 	return vertexBuffer;
1270 }
1271 
creatColorAttachmentAndRenderPass(void)1272 void GraphicBasicTestInstance::creatColorAttachmentAndRenderPass (void)
1273 {
1274 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
1275 	const VkDevice			device	= m_context.getDevice();
1276 
1277 	{
1278 		VkExtent3D					imageExtent				=
1279 		{
1280 			WIDTH,	// width;
1281 			HEIGHT,	// height;
1282 			1u		// depth;
1283 		};
1284 
1285 		const ImageCreateInfo		colorImageCreateInfo	(VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
1286 															VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1287 
1288 		m_colorAttachmentImage	= Image::createAndAlloc(vk, device, colorImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
1289 
1290 		const ImageViewCreateInfo	attachmentViewInfo		(m_colorAttachmentImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
1291 		m_attachmentView			= createImageView(vk, device, &attachmentViewInfo);
1292 
1293 		ImageCreateInfo				depthImageCreateInfo	(vk::VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
1294 															 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
1295 
1296 		m_depthImage				= Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
1297 
1298 		// Construct a depth  view from depth image
1299 		const ImageViewCreateInfo	depthViewInfo			(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM);
1300 		m_depthiew				= vk::createImageView(vk, device, &depthViewInfo);
1301 	}
1302 
1303 	{
1304 		// Renderpass and Framebuffer
1305 		RenderPassCreateInfo		renderPassCreateInfo;
1306 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,						// format
1307 																	VK_SAMPLE_COUNT_1_BIT,						// samples
1308 																	VK_ATTACHMENT_LOAD_OP_CLEAR,				// loadOp
1309 																	VK_ATTACHMENT_STORE_OP_STORE ,				// storeOp
1310 																	VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// stencilLoadOp
1311 																	VK_ATTACHMENT_STORE_OP_STORE ,				// stencilLoadOp
1312 																	VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// initialLauout
1313 																	VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));	// finalLayout
1314 
1315 		renderPassCreateInfo.addAttachment(AttachmentDescription(VK_FORMAT_D16_UNORM,										// format
1316 																 vk::VK_SAMPLE_COUNT_1_BIT,									// samples
1317 																 vk::VK_ATTACHMENT_LOAD_OP_CLEAR,							// loadOp
1318 																 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,						// storeOp
1319 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// stencilLoadOp
1320 																 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,						// stencilLoadOp
1321 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,		// initialLauout
1322 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));	// finalLayout
1323 
1324 		const VkAttachmentReference	colorAttachmentReference =
1325 		{
1326 			0u,											// attachment
1327 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// layout
1328 		};
1329 
1330 		const VkAttachmentReference depthAttachmentReference =
1331 		{
1332 			1u,															// attachment
1333 			vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL		// layout
1334 		};
1335 
1336 		const VkSubpassDescription	subpass =
1337 		{
1338 			(VkSubpassDescriptionFlags) 0,		//VkSubpassDescriptionFlags		flags;
1339 			VK_PIPELINE_BIND_POINT_GRAPHICS,	//VkPipelineBindPoint			pipelineBindPoint;
1340 			0u,									//deUint32						inputAttachmentCount;
1341 			DE_NULL,							//const VkAttachmentReference*	pInputAttachments;
1342 			1u,									//deUint32						colorAttachmentCount;
1343 			&colorAttachmentReference,			//const VkAttachmentReference*	pColorAttachments;
1344 			DE_NULL,							//const VkAttachmentReference*	pResolveAttachments;
1345 			&depthAttachmentReference,			//const VkAttachmentReference*	pDepthStencilAttachment;
1346 			0u,									//deUint32						preserveAttachmentCount;
1347 			DE_NULL,							//const deUint32*				pPreserveAttachments;
1348 		};
1349 
1350 		renderPassCreateInfo.addSubpass(subpass);
1351 		m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
1352 
1353 		std::vector<vk::VkImageView> attachments(2);
1354 		attachments[0] = *m_attachmentView;
1355 		attachments[1] = *m_depthiew;
1356 
1357 		FramebufferCreateInfo		framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
1358 		m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
1359 	}
1360 }
1361 
checkImage(void)1362 bool GraphicBasicTestInstance::checkImage (void)
1363 {
1364 	if (m_parametersGraphic.vertexOnlyPipe)
1365 		return true;
1366 
1367 	const VkQueue						queue			= m_context.getUniversalQueue();
1368 	const VkOffset3D					zeroOffset		= { 0, 0, 0 };
1369 	const tcu::ConstPixelBufferAccess	renderedFrame	= m_colorAttachmentImage->readSurface(queue, m_context.getDefaultAllocator(),
1370 															VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
1371 	int									colorNdx		= 0;
1372 	tcu::Texture2D						referenceFrame	(mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
1373 	referenceFrame.allocLevel(0);
1374 
1375 	for (int y = 0; y < HEIGHT/2; ++y)
1376 	for (int x = 0; x < WIDTH/2; ++x)
1377 			referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1378 
1379 	colorNdx += 4;
1380 	for (int y =  HEIGHT/2; y < HEIGHT; ++y)
1381 	for (int x = 0; x < WIDTH/2; ++x)
1382 			referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1383 
1384 	colorNdx += 4;
1385 	for (int y = 0; y < HEIGHT/2; ++y)
1386 	for (int x =  WIDTH/2; x < WIDTH; ++x)
1387 			referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1388 
1389 	colorNdx += 4;
1390 	for (int y =  HEIGHT/2; y < HEIGHT; ++y)
1391 	for (int x =  WIDTH/2; x < WIDTH; ++x)
1392 			referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1393 
1394 	return tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", referenceFrame.getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR);
1395 }
1396 
1397 class VertexShaderTestInstance : public GraphicBasicTestInstance
1398 {
1399 public:
1400 							VertexShaderTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
1401 protected:
1402 	virtual void			createPipeline				(void);
1403 	virtual tcu::TestStatus	executeTest					(void);
1404 	virtual tcu::TestStatus	checkResult					(VkQueryPool queryPool);
1405 	void					draw						(VkCommandBuffer cmdBuffer);
1406 };
1407 
VertexShaderTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)1408 VertexShaderTestInstance::VertexShaderTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
1409 	: GraphicBasicTestInstance	(context, data, parametersGraphic, drawRepeats )
1410 {
1411 }
1412 
createPipeline(void)1413 void VertexShaderTestInstance::createPipeline (void)
1414 {
1415 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
1416 	const VkDevice			device	= m_context.getDevice();
1417 
1418 	switch (m_parametersGraphic.primitiveTopology)
1419 	{
1420 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
1421 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
1422 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
1423 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
1424 			if (!m_context.getDeviceFeatures().geometryShader)
1425 				throw tcu::NotSupportedError("Geometry shader are not supported");
1426 			break;
1427 		default:
1428 			break;
1429 	}
1430 
1431 	// Pipeline
1432 	Unique<VkShaderModule>	vs(createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), 0));
1433 	Move<VkShaderModule>	fs;
1434 
1435 	if (!m_parametersGraphic.vertexOnlyPipe)
1436 		fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), 0);
1437 
1438 	const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
1439 
1440 	const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
1441 	m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
1442 
1443 	const VkVertexInputBindingDescription vertexInputBindingDescription		=
1444 	{
1445 		0,											// binding;
1446 		static_cast<deUint32>(sizeof(VertexData)),	// stride;
1447 		VK_VERTEX_INPUT_RATE_VERTEX				// inputRate
1448 	};
1449 
1450 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
1451 	{
1452 		{
1453 			0u,
1454 			0u,
1455 			VK_FORMAT_R32G32B32A32_SFLOAT,
1456 			0u
1457 		},	// VertexElementData::position
1458 		{
1459 			1u,
1460 			0u,
1461 			VK_FORMAT_R32G32B32A32_SFLOAT,
1462 			static_cast<deUint32>(sizeof(tcu::Vec4))
1463 		},	// VertexElementData::color
1464 	};
1465 
1466 	const VkPipelineVertexInputStateCreateInfo vf_info			=
1467 	{																	// sType;
1468 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// pNext;
1469 		NULL,															// flags;
1470 		0u,																// vertexBindingDescriptionCount;
1471 		1u,																// pVertexBindingDescriptions;
1472 		&vertexInputBindingDescription,									// vertexAttributeDescriptionCount;
1473 		2u,																// pVertexAttributeDescriptions;
1474 		vertexInputAttributeDescriptions
1475 	};
1476 
1477 	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
1478 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
1479 	if (!m_parametersGraphic.vertexOnlyPipe)
1480 		pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
1481 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
1482 	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_parametersGraphic.primitiveTopology));
1483 	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
1484 
1485 	const VkViewport	viewport	= makeViewport(WIDTH, HEIGHT);
1486 	const VkRect2D		scissor		= makeRect2D(WIDTH, HEIGHT);
1487 	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1u, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
1488 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
1489 	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
1490 	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
1491 	pipelineCreateInfo.addState(vf_info);
1492 	m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
1493 }
1494 
executeTest(void)1495 tcu::TestStatus VertexShaderTestInstance::executeTest (void)
1496 {
1497 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
1498 	const VkDevice							device					= m_context.getDevice();
1499 	const VkQueue							queue					= m_context.getUniversalQueue();
1500 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
1501 
1502 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
1503 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
1504 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
1505 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
1506 
1507 	const VkDeviceSize						vertexBufferOffset		= 0u;
1508 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
1509 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
1510 
1511 	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1512 
1513 	beginCommandBuffer(vk, *cmdBuffer);
1514 	{
1515 		std::vector<VkClearValue>	renderPassClearValues	(2);
1516 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
1517 
1518 		initialTransitionColor2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1519 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1520 		initialTransitionDepth2DImage(vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1521 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1522 
1523 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
1524 			vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
1525 
1526 		beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0]);
1527 
1528 		for (deUint32 i = 0; i < queryCount; ++i)
1529 		{
1530 			vk.cmdBeginQuery(*cmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
1531 			vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1532 			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1533 
1534 			for(deUint64 j=0; j<m_drawRepeats[i]; ++j)
1535 				draw(*cmdBuffer);
1536 
1537 			vk.cmdEndQuery(*cmdBuffer, *queryPool, i);
1538 		}
1539 
1540 		endRenderPass(vk, *cmdBuffer);
1541 
1542 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
1543 		{
1544 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
1545 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
1546 
1547 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
1548 			{
1549 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1550 				stride *= 2u;
1551 			}
1552 
1553 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
1554 			{
1555 				vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
1556 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1557 				stride = sizeof(ValueAndAvailability);
1558 			}
1559 
1560 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
1561 			vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
1562 
1563 			const VkBufferMemoryBarrier barrier =
1564 			{
1565 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
1566 				DE_NULL,									//  const void*		pNext;
1567 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
1568 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
1569 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
1570 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
1571 				m_resetBuffer->object(),					//  VkBuffer		buffer;
1572 				0u,											//  VkDeviceSize	offset;
1573 				queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
1574 			};
1575 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1576 		}
1577 
1578 		transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1579 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1580 	}
1581 	endCommandBuffer(vk, *cmdBuffer);
1582 
1583 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
1584 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
1585 
1586 	// Wait for completion
1587 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1588 	return checkResult (*queryPool);
1589 }
1590 
checkResult(VkQueryPool queryPool)1591 tcu::TestStatus VertexShaderTestInstance::checkResult (VkQueryPool queryPool)
1592 {
1593 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
1594 	const VkDevice			device		= m_context.getDevice();
1595 	deUint64				expectedMin	= 0u;
1596 
1597 	switch(m_parametersGraphic.queryStatisticFlags)
1598 	{
1599 		case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT:
1600 			expectedMin = 16u;
1601 			break;
1602 		case VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT:
1603 			expectedMin =	m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST					? 15u :
1604 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY			?  8u :
1605 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY		? 14u :
1606 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY		?  6u :
1607 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY	?  8u :
1608 							16u;
1609 			break;
1610 		case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT:
1611 			expectedMin =	m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST						? 16u :
1612 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST						?  8u :
1613 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP						? 15u :
1614 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST					?  5u :
1615 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP					?  8u :
1616 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN						? 14u :
1617 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY			?  4u :
1618 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY		? 13u :
1619 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY		?  2u :
1620 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY	?  6u :
1621 							0u;
1622 			break;
1623 		case VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT:
1624 			expectedMin =	m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST						?     9u :
1625 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST						?   192u :
1626 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP						?   448u :
1627 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST					?  2016u :
1628 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP					?  4096u :
1629 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN						? 10208u :
1630 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY			?   128u :
1631 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY		?   416u :
1632 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY		?   992u :
1633 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY	?  3072u :
1634 							0u;
1635 			break;
1636 		default:
1637 			DE_FATAL("Unexpected type of statistics query");
1638 			break;
1639 	}
1640 
1641 	const deUint32 queryCount = static_cast<deUint32>(m_drawRepeats.size());
1642 
1643 	if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL)
1644 	{
1645 		ResultsVector results(queryCount, 0u);
1646 
1647 		if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
1648 		{
1649 			const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
1650 			cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags()), m_parametersGraphic.dstOffset);
1651 		}
1652 		else
1653 		{
1654 			VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
1655 		}
1656 
1657 		if (results[0] < expectedMin)
1658 			return tcu::TestStatus::fail("QueryPoolResults incorrect");
1659 		if (queryCount > 1)
1660 		{
1661 			double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
1662 			if ( fabs( pearson ) < 0.8 )
1663 				return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
1664 		}
1665 	}
1666 	else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
1667 	{
1668 		ResultsVectorWithAvailability results(queryCount, pair<deUint64, deUint64>(0u,0u));
1669 
1670 		if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
1671 		{
1672 			const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
1673 			cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT), m_parametersGraphic.dstOffset);
1674 		}
1675 		else
1676 		{
1677 			VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
1678 		}
1679 
1680 		if (results[0].first < expectedMin || results[0].second == 0)
1681 			return tcu::TestStatus::fail("QueryPoolResults incorrect");
1682 
1683 		if (queryCount > 1)
1684 		{
1685 			double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
1686 			if ( fabs( pearson ) < 0.8 )
1687 				return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
1688 		}
1689 
1690 		deUint64 temp = results[0].first;
1691 
1692 		vk.resetQueryPool(device, queryPool, 0, queryCount);
1693 		vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
1694 		/* From Vulkan spec:
1695 		 *
1696 		 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
1697 		 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
1698 		 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
1699 		 */
1700 		if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0)
1701 			return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
1702 	}
1703 	else
1704 	{
1705 		// With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
1706 		return verifyUnavailable();
1707 	}
1708 
1709 	if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP && !checkImage())
1710 		return tcu::TestStatus::fail("Result image doesn't match expected image.");
1711 
1712 	return tcu::TestStatus::pass("Pass");
1713 }
1714 
draw(VkCommandBuffer cmdBuffer)1715 void VertexShaderTestInstance::draw (VkCommandBuffer cmdBuffer)
1716 {
1717 	const DeviceInterface& vk = m_context.getDeviceInterface();
1718 	switch(m_parametersGraphic.primitiveTopology)
1719 	{
1720 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
1721 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
1722 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
1723 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
1724 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
1725 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
1726 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
1727 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
1728 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
1729 			vk.cmdDraw(cmdBuffer, 16u, 1u, 0u, 0u);
1730 			break;
1731 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
1732 			vk.cmdDraw(cmdBuffer, 4u, 1u, 0u,  0u);
1733 			vk.cmdDraw(cmdBuffer, 4u, 1u, 4u,  1u);
1734 			vk.cmdDraw(cmdBuffer, 4u, 1u, 8u,  2u);
1735 			vk.cmdDraw(cmdBuffer, 4u, 1u, 12u, 3u);
1736 			break;
1737 		default:
1738 			DE_ASSERT(0);
1739 			break;
1740 	}
1741 }
1742 
1743 class VertexShaderSecondaryTestInstance : public VertexShaderTestInstance
1744 {
1745 public:
1746 							VertexShaderSecondaryTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
1747 protected:
1748 	virtual tcu::TestStatus	executeTest							(void);
1749 };
1750 
VertexShaderSecondaryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)1751 VertexShaderSecondaryTestInstance::VertexShaderSecondaryTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
1752 	: VertexShaderTestInstance	(context, data, parametersGraphic, drawRepeats)
1753 {
1754 }
1755 
1756 typedef de::SharedPtr<vk::Unique<VkCommandBuffer>> VkCommandBufferSp;
1757 
executeTest(void)1758 tcu::TestStatus VertexShaderSecondaryTestInstance::executeTest (void)
1759 {
1760 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
1761 	const VkDevice							device					= m_context.getDevice();
1762 	const VkQueue							queue					= m_context.getUniversalQueue();
1763 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
1764 
1765 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
1766 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
1767 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
1768 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
1769 
1770 	const VkDeviceSize						vertexBufferOffset		= 0u;
1771 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
1772 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
1773 
1774 	const Unique<VkCommandBuffer>			primaryCmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1775 	std::vector<VkCommandBufferSp>			secondaryCmdBuffers(queryCount);
1776 
1777 	for (deUint32 i = 0; i < queryCount; ++i)
1778 		secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
1779 
1780 	for (deUint32 i = 0; i < queryCount; ++i)
1781 	{
1782 		beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags, *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
1783 		vk.cmdBeginQuery(secondaryCmdBuffers[i]->get(), *queryPool, i, (VkQueryControlFlags)0u);
1784 		vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1785 		vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
1786 		for(deUint32 j=0; j<m_drawRepeats[i]; ++j)
1787 			draw(secondaryCmdBuffers[i]->get());
1788 		vk.cmdEndQuery(secondaryCmdBuffers[i]->get(), *queryPool, i);
1789 		endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
1790 	}
1791 
1792 	beginCommandBuffer(vk, *primaryCmdBuffer);
1793 	{
1794 		std::vector<VkClearValue>	renderPassClearValues	(2);
1795 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
1796 
1797 		initialTransitionColor2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1798 									  vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1799 		initialTransitionDepth2DImage(vk, *primaryCmdBuffer, m_depthImage->object(), vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1800 									  vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1801 
1802 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
1803 			vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
1804 
1805 		beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0], VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1806 		for (deUint32 i = 0; i < queryCount; ++i)
1807 			vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
1808 		endRenderPass(vk, *primaryCmdBuffer);
1809 
1810 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
1811 		{
1812 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
1813 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
1814 
1815 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
1816 			{
1817 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1818 				stride *= 2u;
1819 			}
1820 
1821 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
1822 			{
1823 				vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
1824 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1825 				stride = sizeof(ValueAndAvailability);
1826 			}
1827 
1828 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
1829 			vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
1830 
1831 			const VkBufferMemoryBarrier barrier =
1832 			{
1833 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
1834 				DE_NULL,									//  const void*		pNext;
1835 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
1836 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
1837 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
1838 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
1839 				m_resetBuffer->object(),					//  VkBuffer		buffer;
1840 				0u,											//  VkDeviceSize	offset;
1841 				queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
1842 			};
1843 			vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1844 		}
1845 
1846 		transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1847 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1848 	}
1849 	endCommandBuffer(vk, *primaryCmdBuffer);
1850 
1851 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
1852 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
1853 
1854 	// Wait for completion
1855 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
1856 	return checkResult (*queryPool);
1857 }
1858 
1859 class VertexShaderSecondaryInheritedTestInstance : public VertexShaderTestInstance
1860 {
1861 public:
1862 							VertexShaderSecondaryInheritedTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
1863 protected:
1864 	virtual void			checkExtensions						(deBool hostQueryResetEnabled);
1865 	virtual tcu::TestStatus	executeTest							(void);
1866 };
1867 
VertexShaderSecondaryInheritedTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)1868 VertexShaderSecondaryInheritedTestInstance::VertexShaderSecondaryInheritedTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
1869 	: VertexShaderTestInstance	(context, data, parametersGraphic, drawRepeats)
1870 {
1871 }
1872 
checkExtensions(deBool hostQueryResetEnabled)1873 void VertexShaderSecondaryInheritedTestInstance::checkExtensions (deBool hostQueryResetEnabled)
1874 {
1875 	StatisticQueryTestInstance::checkExtensions(hostQueryResetEnabled);
1876 	if (!m_context.getDeviceFeatures().inheritedQueries)
1877 		throw tcu::NotSupportedError("Inherited queries are not supported");
1878 }
1879 
executeTest(void)1880 tcu::TestStatus VertexShaderSecondaryInheritedTestInstance::executeTest (void)
1881 {
1882 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
1883 	const VkDevice							device					= m_context.getDevice();
1884 	const VkQueue							queue					= m_context.getUniversalQueue();
1885 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
1886 
1887 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
1888 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
1889 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
1890 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
1891 
1892 	const VkDeviceSize						vertexBufferOffset		= 0u;
1893 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
1894 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
1895 
1896 	const Unique<VkCommandBuffer>			primaryCmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1897 	std::vector<VkCommandBufferSp>			secondaryCmdBuffers(queryCount);
1898 
1899 	for (deUint32 i = 0; i < queryCount; ++i)
1900 		secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
1901 
1902 	for (deUint32 i = 0; i < queryCount; ++i)
1903 	{
1904 		beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags, *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
1905 		vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1906 		vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
1907 		for (deUint32 j = 0; j<m_drawRepeats[i]; ++j)
1908 			draw(secondaryCmdBuffers[i]->get());
1909 		endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
1910 	}
1911 
1912 	beginCommandBuffer(vk, *primaryCmdBuffer);
1913 	{
1914 		std::vector<VkClearValue>	renderPassClearValues	(2);
1915 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
1916 
1917 		initialTransitionColor2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1918 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1919 		initialTransitionDepth2DImage(vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1920 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1921 
1922 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
1923 			vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
1924 
1925 		for (deUint32 i = 0; i < queryCount; ++i)
1926 		{
1927 			vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
1928 			beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0], VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1929 			vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
1930 			endRenderPass(vk, *primaryCmdBuffer);
1931 			vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, i);
1932 		}
1933 
1934 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
1935 		{
1936 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
1937 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
1938 
1939 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
1940 			{
1941 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1942 				stride *= 2u;
1943 			}
1944 
1945 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
1946 			{
1947 				vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
1948 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1949 				stride = sizeof(ValueAndAvailability);
1950 			}
1951 
1952 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
1953 			vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
1954 
1955 			const VkBufferMemoryBarrier barrier =
1956 			{
1957 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
1958 				DE_NULL,									//  const void*		pNext;
1959 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
1960 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
1961 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
1962 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
1963 				m_resetBuffer->object(),					//  VkBuffer		buffer;
1964 				0u,											//  VkDeviceSize	offset;
1965 			    queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
1966 			};
1967 			vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1968 		}
1969 
1970 		transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1971 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1972 	}
1973 	endCommandBuffer(vk, *primaryCmdBuffer);
1974 
1975 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
1976 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
1977 
1978 	// Wait for completion
1979 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
1980 	return checkResult (*queryPool);
1981 }
1982 
1983 class GeometryShaderTestInstance : public GraphicBasicTestInstance
1984 {
1985 public:
1986 							GeometryShaderTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
1987 protected:
1988 	virtual void			checkExtensions				(deBool hostQueryResetEnabled);
1989 	virtual void			createPipeline				(void);
1990 	virtual tcu::TestStatus	executeTest					(void);
1991 	tcu::TestStatus			checkResult					(VkQueryPool queryPool);
1992 	void					draw						(VkCommandBuffer cmdBuffer);
1993 };
1994 
GeometryShaderTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)1995 GeometryShaderTestInstance::GeometryShaderTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
1996 	: GraphicBasicTestInstance(context, data, parametersGraphic, drawRepeats)
1997 {
1998 }
1999 
checkExtensions(deBool hostQueryResetEnabled)2000 void GeometryShaderTestInstance::checkExtensions (deBool hostQueryResetEnabled)
2001 {
2002 	StatisticQueryTestInstance::checkExtensions(hostQueryResetEnabled);
2003 	if (!m_context.getDeviceFeatures().geometryShader)
2004 		throw tcu::NotSupportedError("Geometry shader are not supported");
2005 }
2006 
createPipeline(void)2007 void GeometryShaderTestInstance::createPipeline (void)
2008 {
2009 	const DeviceInterface&	vk						= m_context.getDeviceInterface();
2010 	const VkDevice			device					= m_context.getDevice();
2011 	const VkBool32			useGeomPointSize		= m_context.getDeviceFeatures().shaderTessellationAndGeometryPointSize && (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
2012 
2013 	// Pipeline
2014 	Unique<VkShaderModule> vs(createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), (VkShaderModuleCreateFlags)0));
2015 	Unique<VkShaderModule> gs(createShaderModule(vk, device, m_context.getBinaryCollection().get(useGeomPointSize ? "geometry_point_size" : "geometry"), (VkShaderModuleCreateFlags)0));
2016 	Unique<VkShaderModule> fs(createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), (VkShaderModuleCreateFlags)0));
2017 
2018 	const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
2019 
2020 	const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
2021 	m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
2022 
2023 	const VkVertexInputBindingDescription vertexInputBindingDescription		=
2024 	{
2025 		0u,											// binding;
2026 		static_cast<deUint32>(sizeof(VertexData)),	// stride;
2027 		VK_VERTEX_INPUT_RATE_VERTEX					// inputRate
2028 	};
2029 
2030 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
2031 	{
2032 		{
2033 			0u,
2034 			0u,
2035 			VK_FORMAT_R32G32B32A32_SFLOAT,
2036 			0u
2037 		},	// VertexElementData::position
2038 		{
2039 			1u,
2040 			0u,
2041 			VK_FORMAT_R32G32B32A32_SFLOAT,
2042 			static_cast<deUint32>(sizeof(tcu::Vec4))
2043 		},	// VertexElementData::color
2044 	};
2045 
2046 	const VkPipelineVertexInputStateCreateInfo vf_info			=
2047 	{																	// sType;
2048 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// pNext;
2049 		NULL,															// flags;
2050 		0u,																// vertexBindingDescriptionCount;
2051 		1,																// pVertexBindingDescriptions;
2052 		&vertexInputBindingDescription,									// vertexAttributeDescriptionCount;
2053 		2,																// pVertexAttributeDescriptions;
2054 		vertexInputAttributeDescriptions
2055 	};
2056 
2057 	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
2058 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
2059 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*gs, "main", VK_SHADER_STAGE_GEOMETRY_BIT));
2060 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
2061 	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_parametersGraphic.primitiveTopology));
2062 	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
2063 
2064 	const VkViewport	viewport	= makeViewport(WIDTH, HEIGHT);
2065 	const VkRect2D		scissor		= makeRect2D(WIDTH, HEIGHT);
2066 
2067 	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
2068 
2069 	if (m_context.getDeviceFeatures().depthBounds)
2070 		pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState(true, true, VK_COMPARE_OP_GREATER_OR_EQUAL, true));
2071 	else
2072 		pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
2073 
2074 	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState(false));
2075 	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
2076 	pipelineCreateInfo.addState(vf_info);
2077 	m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
2078 }
2079 
executeTest(void)2080 tcu::TestStatus GeometryShaderTestInstance::executeTest (void)
2081 {
2082 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
2083 	const VkDevice							device					= m_context.getDevice();
2084 	const VkQueue							queue					= m_context.getUniversalQueue();
2085 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
2086 
2087 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
2088 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
2089 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
2090 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2091 
2092 	const VkDeviceSize						vertexBufferOffset		= 0u;
2093 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
2094 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
2095 
2096 	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2097 
2098 	beginCommandBuffer(vk, *cmdBuffer);
2099 	{
2100 		std::vector<VkClearValue>	renderPassClearValues	(2);
2101 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2102 
2103 		initialTransitionColor2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2104 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2105 		initialTransitionDepth2DImage(vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2106 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2107 
2108 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2109 			vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2110 
2111 		beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0]);
2112 
2113 		for (deUint32 i = 0; i < queryCount; ++i)
2114 		{
2115 			vk.cmdBeginQuery(*cmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
2116 			vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
2117 			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2118 
2119 			for (deUint64 j = 0; j<m_drawRepeats[i]; ++j)
2120 				draw(*cmdBuffer);
2121 
2122 			vk.cmdEndQuery(*cmdBuffer, *queryPool, i);
2123 		}
2124 
2125 		endRenderPass(vk, *cmdBuffer);
2126 
2127 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2128 		{
2129 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
2130 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2131 
2132 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2133 			{
2134 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2135 				stride *= 2u;
2136 			}
2137 
2138 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2139 			{
2140 				vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2141 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2142 				stride = sizeof(ValueAndAvailability);
2143 			}
2144 
2145 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2146 			vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
2147 
2148 			const VkBufferMemoryBarrier barrier =
2149 			{
2150 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
2151 				DE_NULL,									//  const void*		pNext;
2152 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
2153 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
2154 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
2155 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
2156 				m_resetBuffer->object(),					//  VkBuffer		buffer;
2157 				0u,											//  VkDeviceSize	offset;
2158 				queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
2159 			};
2160 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2161 		}
2162 
2163 		transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2164 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2165 	}
2166 	endCommandBuffer(vk, *cmdBuffer);
2167 
2168 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2169 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2170 
2171 	// Wait for completion
2172 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2173 	return checkResult(*queryPool);
2174 }
2175 
checkResult(VkQueryPool queryPool)2176 tcu::TestStatus GeometryShaderTestInstance::checkResult (VkQueryPool queryPool)
2177 {
2178 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
2179 	const VkDevice			device		= m_context.getDevice();
2180 	deUint64				expectedMin	= 0u;
2181 
2182 	switch(m_parametersGraphic.queryStatisticFlags)
2183 	{
2184 		case VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT:
2185 			expectedMin =	m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST						? 16u :
2186 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST						? 8u :
2187 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP						? 15u :
2188 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST					? 4u :
2189 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP					? 4u :
2190 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN						? 14u :
2191 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY			? 4u :
2192 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY		? 13u :
2193 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY		? 2u :
2194 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY	? 6u :
2195 							0u;
2196 			break;
2197 		case VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT:
2198 		case VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT:
2199 		case VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT:
2200 			expectedMin =	m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST						? 112u :
2201 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST						? 32u :
2202 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP						? 60u :
2203 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST					? 8u :
2204 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP					? 8u :
2205 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN						? 28u :
2206 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY			? 16u :
2207 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY		? 52u :
2208 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY		? 4u :
2209 							m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY	? 12u :
2210 							0u;
2211 			break;
2212 		default:
2213 			DE_FATAL("Unexpected type of statistics query");
2214 			break;
2215 	}
2216 
2217 	const deUint32 queryCount = static_cast<deUint32>(m_drawRepeats.size());
2218 
2219 	if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL)
2220 	{
2221 		ResultsVector results(queryCount, 0u);
2222 
2223 		if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2224 		{
2225 			const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
2226 			cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags()), m_parametersGraphic.dstOffset);
2227 		}
2228 		else
2229 		{
2230 			VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
2231 		}
2232 
2233 		if (results[0] < expectedMin)
2234 			return tcu::TestStatus::fail("QueryPoolResults incorrect");
2235 		if (queryCount > 1)
2236 		{
2237 			double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2238 			if ( fabs( pearson ) < 0.8 )
2239 				return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2240 		}
2241 	}
2242 	else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2243 	{
2244 		ResultsVectorWithAvailability results(queryCount, pair<deUint64, deUint64>(0u, 0u));
2245 		if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2246 		{
2247 			const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
2248 			cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT), m_parametersGraphic.dstOffset);
2249 		}
2250 		else
2251 		{
2252 			VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
2253 		}
2254 
2255 		if (results[0].first < expectedMin || results[0].second == 0u)
2256 			return tcu::TestStatus::fail("QueryPoolResults incorrect");
2257 
2258 		if (queryCount > 1)
2259 		{
2260 			double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2261 			if ( fabs( pearson ) < 0.8 )
2262 				return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2263 		}
2264 
2265 		deUint64 temp = results[0].first;
2266 
2267 		vk.resetQueryPool(device, queryPool, 0, queryCount);
2268 		vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
2269 		/* From Vulkan spec:
2270 		 *
2271 		 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
2272 		 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
2273 		 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
2274 		 */
2275 		if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0u)
2276 			return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
2277 	}
2278 	else
2279 	{
2280 		// With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
2281 		return verifyUnavailable();
2282 	}
2283 
2284 	if ( (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST || m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ) && !checkImage())
2285 		return tcu::TestStatus::fail("Result image doesn't match expected image.");
2286 
2287 	return tcu::TestStatus::pass("Pass");
2288 }
2289 
draw(VkCommandBuffer cmdBuffer)2290 void GeometryShaderTestInstance::draw (VkCommandBuffer cmdBuffer)
2291 {
2292 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
2293 	if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
2294 		m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
2295 	{
2296 		vk.cmdDraw(cmdBuffer, 3u, 1u,  0u,  1u);
2297 		vk.cmdDraw(cmdBuffer, 3u, 1u,  4u,  1u);
2298 		vk.cmdDraw(cmdBuffer, 3u, 1u,  8u,  2u);
2299 		vk.cmdDraw(cmdBuffer, 3u, 1u, 12u,  3u);
2300 	}
2301 	else
2302 	{
2303 		vk.cmdDraw(cmdBuffer, 16u, 1u, 0u,  0u);
2304 	}
2305 }
2306 
2307 class GeometryShaderSecondaryTestInstance : public GeometryShaderTestInstance
2308 {
2309 public:
2310 							GeometryShaderSecondaryTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
2311 protected:
2312 	virtual tcu::TestStatus	executeTest							(void);
2313 };
2314 
GeometryShaderSecondaryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)2315 GeometryShaderSecondaryTestInstance::GeometryShaderSecondaryTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
2316 	: GeometryShaderTestInstance	(context, data, parametersGraphic, drawRepeats)
2317 {
2318 }
2319 
executeTest(void)2320 tcu::TestStatus GeometryShaderSecondaryTestInstance::executeTest (void)
2321 {
2322 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
2323 	const VkDevice							device					= m_context.getDevice();
2324 	const VkQueue							queue					= m_context.getUniversalQueue();
2325 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
2326 
2327 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
2328 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
2329 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
2330 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2331 
2332 	const VkDeviceSize						vertexBufferOffset		= 0;
2333 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
2334 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
2335 
2336 	const Unique<VkCommandBuffer>			primaryCmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2337 	std::vector<VkCommandBufferSp>			secondaryCmdBuffers(queryCount);
2338 
2339 	for (deUint32 i = 0; i < queryCount; ++i)
2340 		secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
2341 
2342 	for (deUint32 i = 0; i < queryCount; ++i)
2343 	{
2344 		beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags, *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2345 		vk.cmdBeginQuery(secondaryCmdBuffers[i]->get(), *queryPool, i, (VkQueryControlFlags)0u);
2346 		vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2347 		vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2348 		for (deUint32 j = 0; j<m_drawRepeats[i]; ++j)
2349 			draw(secondaryCmdBuffers[i]->get());
2350 		vk.cmdEndQuery(secondaryCmdBuffers[i]->get(), *queryPool, i);
2351 		endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
2352 	}
2353 
2354 	beginCommandBuffer(vk, *primaryCmdBuffer);
2355 	{
2356 		std::vector<VkClearValue>	renderPassClearValues	(2);
2357 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2358 
2359 		initialTransitionColor2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2360 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2361 		initialTransitionDepth2DImage(vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2362 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2363 
2364 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2365 			vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2366 		beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0], VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
2367 		for (deUint32 i = 0; i < queryCount; ++i)
2368 			vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
2369 		endRenderPass(vk, *primaryCmdBuffer);
2370 
2371 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2372 		{
2373 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
2374 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2375 
2376 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2377 			{
2378 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2379 				stride *= 2u;
2380 			}
2381 
2382 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2383 			{
2384 				vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2385 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2386 				stride = sizeof(ValueAndAvailability);
2387 			}
2388 
2389 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2390 			vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
2391 
2392 			const VkBufferMemoryBarrier barrier =
2393 			{
2394 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
2395 				DE_NULL,									//  const void*		pNext;
2396 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
2397 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
2398 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
2399 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
2400 				m_resetBuffer->object(),					//  VkBuffer		buffer;
2401 				0u,											//  VkDeviceSize	offset;
2402 				queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
2403 			};
2404 			vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2405 		}
2406 
2407 		transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2408 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2409 	}
2410 	endCommandBuffer(vk, *primaryCmdBuffer);
2411 
2412 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2413 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2414 
2415 	// Wait for completion
2416 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
2417 	return checkResult(*queryPool);
2418 }
2419 
2420 class GeometryShaderSecondaryInheritedTestInstance : public GeometryShaderTestInstance
2421 {
2422 public:
2423 							GeometryShaderSecondaryInheritedTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
2424 protected:
2425 	virtual void			checkExtensions						(deBool hostQueryResetEnabled);
2426 	virtual tcu::TestStatus	executeTest							(void);
2427 };
2428 
GeometryShaderSecondaryInheritedTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)2429 GeometryShaderSecondaryInheritedTestInstance::GeometryShaderSecondaryInheritedTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
2430 	: GeometryShaderTestInstance	(context, data, parametersGraphic, drawRepeats)
2431 {
2432 }
2433 
checkExtensions(deBool hostQueryResetEnabled)2434 void GeometryShaderSecondaryInheritedTestInstance::checkExtensions (deBool hostQueryResetEnabled)
2435 {
2436 	GeometryShaderTestInstance::checkExtensions(hostQueryResetEnabled);
2437 	if (!m_context.getDeviceFeatures().inheritedQueries)
2438 		throw tcu::NotSupportedError("Inherited queries are not supported");
2439 }
2440 
executeTest(void)2441 tcu::TestStatus GeometryShaderSecondaryInheritedTestInstance::executeTest (void)
2442 {
2443 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
2444 	const VkDevice							device					= m_context.getDevice();
2445 	const VkQueue							queue					= m_context.getUniversalQueue();
2446 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
2447 
2448 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
2449 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
2450 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
2451 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2452 
2453 	const VkDeviceSize						vertexBufferOffset		= 0u;
2454 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
2455 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
2456 
2457 	const Unique<VkCommandBuffer>			primaryCmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2458 	std::vector<VkCommandBufferSp>			secondaryCmdBuffers(queryCount);
2459 
2460 	for (deUint32 i = 0; i < queryCount; ++i)
2461 		secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
2462 
2463 	for (deUint32 i = 0; i < queryCount; ++i)
2464 	{
2465 		beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags, *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2466 		vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2467 		vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2468 		for (deUint32 j = 0; j<m_drawRepeats[i]; ++j)
2469 			draw(secondaryCmdBuffers[i]->get());
2470 		endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
2471 	}
2472 
2473 	beginCommandBuffer(vk, *primaryCmdBuffer);
2474 	{
2475 		std::vector<VkClearValue>	renderPassClearValues	(2);
2476 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2477 
2478 		initialTransitionColor2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2479 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2480 		initialTransitionDepth2DImage(vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2481 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2482 
2483 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2484 			vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2485 
2486 		for (deUint32 i = 0; i < queryCount; ++i)
2487 		{
2488 			vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
2489 			beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0], VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
2490 			vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
2491 			endRenderPass(vk, *primaryCmdBuffer);
2492 			vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, i);
2493 		}
2494 
2495 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2496 		{
2497 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
2498 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2499 
2500 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2501 			{
2502 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2503 				stride *= 2u;
2504 			}
2505 
2506 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2507 			{
2508 				vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2509 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2510 				stride = sizeof(ValueAndAvailability);
2511 			}
2512 
2513 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2514 			vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
2515 
2516 			const VkBufferMemoryBarrier barrier =
2517 			{
2518 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
2519 				DE_NULL,									//  const void*		pNext;
2520 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
2521 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
2522 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
2523 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
2524 				m_resetBuffer->object(),					//  VkBuffer		buffer;
2525 				0u,											//  VkDeviceSize	offset;
2526 			    queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
2527 			};
2528 			vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2529 		}
2530 
2531 		transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2532 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2533 	}
2534 	endCommandBuffer(vk, *primaryCmdBuffer);
2535 
2536 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2537 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2538 
2539 	// Wait for completion
2540 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
2541 	return checkResult(*queryPool);
2542 }
2543 
2544 class TessellationShaderTestInstance : public GraphicBasicTestInstance
2545 {
2546 public:
2547 							TessellationShaderTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
2548 protected:
2549 	virtual	void			checkExtensions				(deBool hostQueryResetEnabled);
2550 	virtual void			createPipeline				(void);
2551 	virtual tcu::TestStatus	executeTest					(void);
2552 	virtual tcu::TestStatus	checkResult					(VkQueryPool queryPool);
2553 	void					draw						(VkCommandBuffer cmdBuffer);
2554 };
2555 
TessellationShaderTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)2556 TessellationShaderTestInstance::TessellationShaderTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
2557 	: GraphicBasicTestInstance	(context, data, parametersGraphic, drawRepeats)
2558 {
2559 }
2560 
checkExtensions(deBool hostQueryResetEnabled)2561 void TessellationShaderTestInstance::checkExtensions (deBool hostQueryResetEnabled)
2562 {
2563 	StatisticQueryTestInstance::checkExtensions(hostQueryResetEnabled);
2564 	if (!m_context.getDeviceFeatures().tessellationShader)
2565 		throw tcu::NotSupportedError("Tessellation shader are not supported");
2566 }
2567 
2568 
createPipeline(void)2569 void TessellationShaderTestInstance::createPipeline (void)
2570 {
2571 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
2572 	const VkDevice			device	= m_context.getDevice();
2573 
2574 	// Pipeline
2575 	Unique<VkShaderModule> vs(createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), (VkShaderModuleCreateFlags)0));
2576 	Unique<VkShaderModule> tc(createShaderModule(vk, device, m_context.getBinaryCollection().get("tessellation_control"), (VkShaderModuleCreateFlags)0));
2577 	Unique<VkShaderModule> te(createShaderModule(vk, device, m_context.getBinaryCollection().get("tessellation_evaluation"), (VkShaderModuleCreateFlags)0));
2578 	Unique<VkShaderModule> fs(createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), (VkShaderModuleCreateFlags)0));
2579 
2580 	const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
2581 
2582 	const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
2583 	m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
2584 
2585 	const VkVertexInputBindingDescription vertexInputBindingDescription		=
2586 	{
2587 		0u,											// binding;
2588 		static_cast<deUint32>(sizeof(VertexData)),	// stride;
2589 		VK_VERTEX_INPUT_RATE_VERTEX					// inputRate
2590 	};
2591 
2592 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
2593 	{
2594 		{
2595 			0u,
2596 			0u,
2597 			VK_FORMAT_R32G32B32A32_SFLOAT,
2598 			0u
2599 		},	// VertexElementData::position
2600 		{
2601 			1u,
2602 			0u,
2603 			VK_FORMAT_R32G32B32A32_SFLOAT,
2604 			static_cast<deUint32>(sizeof(tcu::Vec4))
2605 		},	// VertexElementData::color
2606 	};
2607 
2608 	const VkPipelineVertexInputStateCreateInfo vf_info			=
2609 	{																	// sType;
2610 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// pNext;
2611 		NULL,															// flags;
2612 		0u,																// vertexBindingDescriptionCount;
2613 		1u,																// pVertexBindingDescriptions;
2614 		&vertexInputBindingDescription,									// vertexAttributeDescriptionCount;
2615 		2u,																// pVertexAttributeDescriptions;
2616 		vertexInputAttributeDescriptions
2617 	};
2618 
2619 	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
2620 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
2621 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*tc, "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
2622 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*te, "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
2623 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
2624 	pipelineCreateInfo.addState	(PipelineCreateInfo::TessellationState(4));
2625 	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST));
2626 	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
2627 
2628 	const VkViewport	viewport	= makeViewport(WIDTH, HEIGHT);
2629 	const VkRect2D		scissor		= makeRect2D(WIDTH, HEIGHT);
2630 
2631 	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
2632 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
2633 	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
2634 	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
2635 	pipelineCreateInfo.addState(vf_info);
2636 	m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
2637 }
2638 
executeTest(void)2639 tcu::TestStatus	TessellationShaderTestInstance::executeTest (void)
2640 {
2641 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
2642 	const VkDevice							device					= m_context.getDevice();
2643 	const VkQueue							queue					= m_context.getUniversalQueue();
2644 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
2645 
2646 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
2647 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
2648 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
2649 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2650 
2651 	const VkDeviceSize						vertexBufferOffset		= 0u;
2652 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
2653 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
2654 
2655 	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2656 
2657 	beginCommandBuffer(vk, *cmdBuffer);
2658 	{
2659 		std::vector<VkClearValue>	renderPassClearValues	(2);
2660 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2661 
2662 		initialTransitionColor2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2663 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2664 		initialTransitionDepth2DImage(vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2665 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2666 
2667 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2668 			vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2669 
2670 		beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0]);
2671 
2672 		for (deUint32 i = 0; i < queryCount; ++i)
2673 		{
2674 			vk.cmdBeginQuery(*cmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
2675 			vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
2676 			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2677 
2678 			for (deUint64 j = 0; j<m_drawRepeats[i]; ++j)
2679 				draw(*cmdBuffer);
2680 
2681 			vk.cmdEndQuery(*cmdBuffer, *queryPool, i);
2682 		}
2683 
2684 		endRenderPass(vk, *cmdBuffer);
2685 
2686 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2687 		{
2688 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
2689 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2690 
2691 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2692 			{
2693 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2694 				stride *= 2u;
2695 			}
2696 
2697 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2698 			{
2699 				vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2700 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2701 				stride = sizeof(ValueAndAvailability);
2702 			}
2703 
2704 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2705 			vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
2706 
2707 			const VkBufferMemoryBarrier barrier =
2708 			{
2709 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
2710 				DE_NULL,									//  const void*		pNext;
2711 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
2712 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
2713 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
2714 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
2715 				m_resetBuffer->object(),					//  VkBuffer		buffer;
2716 				0u,											//  VkDeviceSize	offset;
2717 			    queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
2718 			};
2719 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2720 		}
2721 
2722 		transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2723 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2724 	}
2725 	endCommandBuffer(vk, *cmdBuffer);
2726 
2727 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2728 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2729 
2730 	// Wait for completion
2731 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2732 	return checkResult (*queryPool);
2733 }
2734 
checkResult(VkQueryPool queryPool)2735 tcu::TestStatus TessellationShaderTestInstance::checkResult (VkQueryPool queryPool)
2736 {
2737 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
2738 	const VkDevice			device		= m_context.getDevice();
2739 	deUint64				expectedMin	= 0u;
2740 
2741 	switch(m_parametersGraphic.queryStatisticFlags)
2742 	{
2743 		case VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT:
2744 			expectedMin = 4u;
2745 			break;
2746 		case VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT:
2747 			expectedMin = 100u;
2748 			break;
2749 		default:
2750 			DE_FATAL("Unexpected type of statistics query");
2751 			break;
2752 	}
2753 
2754 	const deUint32 queryCount = static_cast<deUint32>(m_drawRepeats.size());
2755 
2756 	if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL)
2757 	{
2758 		ResultsVector results(queryCount, 0u);
2759 		if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2760 		{
2761 			const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
2762 			cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags()), m_parametersGraphic.dstOffset);
2763 		}
2764 		else
2765 		{
2766 			VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
2767 		}
2768 
2769 		if (results[0] < expectedMin)
2770 			return tcu::TestStatus::fail("QueryPoolResults incorrect");
2771 		if (queryCount > 1)
2772 		{
2773 			double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2774 			if ( fabs( pearson ) < 0.8 )
2775 				return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2776 		}
2777 
2778 		if (!checkImage())
2779 			return tcu::TestStatus::fail("Result image doesn't match expected image.");
2780 	}
2781 	else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2782 	{
2783 		ResultsVectorWithAvailability results(queryCount, pair<deUint64,deUint64>(0u,0u));
2784 		if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2785 		{
2786 			const vk::Allocation& allocation = m_resetBuffer->getBoundMemory();
2787 			cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT), m_parametersGraphic.dstOffset);
2788 		}
2789 		else
2790 		{
2791 			VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
2792 		}
2793 
2794 		if (results[0].first < expectedMin || results[0].second == 0u)
2795 			return tcu::TestStatus::fail("QueryPoolResults incorrect");
2796 
2797 		if (queryCount > 1)
2798 		{
2799 			double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2800 			if ( fabs( pearson ) < 0.8 )
2801 				return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2802 		}
2803 
2804 		deUint64 temp = results[0].first;
2805 
2806 		vk.resetQueryPool(device, queryPool, 0, queryCount);
2807 		vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
2808 		/* From Vulkan spec:
2809 		 *
2810 		 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
2811 		 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
2812 		 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
2813 		 */
2814 		if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0u)
2815 			return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
2816 	}
2817 	else
2818 	{
2819 		// With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
2820 		return verifyUnavailable();
2821 	}
2822 	return tcu::TestStatus::pass("Pass");
2823 }
2824 
draw(VkCommandBuffer cmdBuffer)2825 void TessellationShaderTestInstance::draw (VkCommandBuffer cmdBuffer)
2826 {
2827 	const DeviceInterface& vk = m_context.getDeviceInterface();
2828 	vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_data.size()), 1u, 0u, 0u);
2829 }
2830 
2831 class TessellationShaderSecondrayTestInstance : public TessellationShaderTestInstance
2832 {
2833 public:
2834 							TessellationShaderSecondrayTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
2835 protected:
2836 	virtual tcu::TestStatus	executeTest								(void);
2837 };
2838 
TessellationShaderSecondrayTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)2839 TessellationShaderSecondrayTestInstance::TessellationShaderSecondrayTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
2840 	: TessellationShaderTestInstance	(context, data, parametersGraphic, drawRepeats)
2841 {
2842 }
2843 
executeTest(void)2844 tcu::TestStatus	TessellationShaderSecondrayTestInstance::executeTest (void)
2845 {
2846 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
2847 	const VkDevice							device					= m_context.getDevice();
2848 	const VkQueue							queue					= m_context.getUniversalQueue();
2849 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
2850 
2851 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
2852 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
2853 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
2854 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2855 
2856 	const VkDeviceSize						vertexBufferOffset		= 0u;
2857 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
2858 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
2859 
2860 	const Unique<VkCommandBuffer>			primaryCmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2861 	std::vector<VkCommandBufferSp>			secondaryCmdBuffers(queryCount);
2862 
2863 	for (deUint32 i = 0; i < queryCount; ++i)
2864 		secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
2865 
2866 	for (deUint32 i = 0; i < queryCount; ++i)
2867 	{
2868 		beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags, *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2869 		vk.cmdBeginQuery(secondaryCmdBuffers[i]->get(), *queryPool, i, (VkQueryControlFlags)0u);
2870 		vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2871 		vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2872 		for (deUint32 j = 0; j<m_drawRepeats[i]; ++j)
2873 			draw(secondaryCmdBuffers[i]->get());
2874 		vk.cmdEndQuery(secondaryCmdBuffers[i]->get(), *queryPool, i);
2875 		endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
2876 	}
2877 
2878 	beginCommandBuffer(vk, *primaryCmdBuffer);
2879 	{
2880 		std::vector<VkClearValue>	renderPassClearValues	(2);
2881 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2882 
2883 		initialTransitionColor2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2884 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2885 		initialTransitionDepth2DImage(vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2886 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2887 
2888 		vk.cmdBindVertexBuffers(*primaryCmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2889 		vk.cmdBindPipeline(*primaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2890 
2891 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2892 			vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2893 
2894 		beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0], VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
2895 		for (deUint32 i = 0; i < queryCount; ++i)
2896 			vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
2897 		endRenderPass(vk, *primaryCmdBuffer);
2898 
2899 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY|| m_parametersGraphic.copyType == COPY_TYPE_CMD)
2900 		{
2901 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
2902 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2903 			deUint32 queryCountTess = queryCount;
2904 
2905 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2906 			{
2907 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2908 				stride *= 2u;
2909 			}
2910 
2911 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2912 			{
2913 				vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2914 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2915 				stride = sizeof(ValueAndAvailability);
2916 				queryCountTess = 1u;
2917 			}
2918 
2919 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2920 			vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCountTess, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
2921 
2922 			const VkBufferMemoryBarrier barrier =
2923 			{
2924 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
2925 				DE_NULL,									//  const void*		pNext;
2926 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
2927 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
2928 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
2929 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
2930 				m_resetBuffer->object(),					//  VkBuffer		buffer;
2931 				0u,											//  VkDeviceSize	offset;
2932 				queryCountTess * stride + dstOffsetQuery,	//  VkDeviceSize	size;
2933 			};
2934 			vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2935 		}
2936 
2937 		transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2938 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2939 	}
2940 	endCommandBuffer(vk, *primaryCmdBuffer);
2941 
2942 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2943 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2944 
2945 	// Wait for completion
2946 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
2947 	return checkResult (*queryPool);
2948 }
2949 
2950 class TessellationShaderSecondrayInheritedTestInstance : public TessellationShaderTestInstance
2951 {
2952 public:
2953 							TessellationShaderSecondrayInheritedTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats);
2954 protected:
2955 	virtual void			checkExtensions							(deBool hostQueryResetEnabled);
2956 	virtual tcu::TestStatus	executeTest								(void);
2957 };
2958 
TessellationShaderSecondrayInheritedTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<deUint64> & drawRepeats)2959 TessellationShaderSecondrayInheritedTestInstance::TessellationShaderSecondrayInheritedTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic, const std::vector<deUint64>& drawRepeats)
2960 	: TessellationShaderTestInstance	(context, data, parametersGraphic, drawRepeats)
2961 {
2962 }
2963 
checkExtensions(deBool hostQueryResetEnabled)2964 void TessellationShaderSecondrayInheritedTestInstance::checkExtensions (deBool hostQueryResetEnabled)
2965 {
2966 	TessellationShaderTestInstance::checkExtensions(hostQueryResetEnabled);
2967 	if (!m_context.getDeviceFeatures().inheritedQueries)
2968 		throw tcu::NotSupportedError("Inherited queries are not supported");
2969 }
2970 
executeTest(void)2971 tcu::TestStatus	TessellationShaderSecondrayInheritedTestInstance::executeTest (void)
2972 {
2973 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
2974 	const VkDevice							device					= m_context.getDevice();
2975 	const VkQueue							queue					= m_context.getUniversalQueue();
2976 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
2977 
2978 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
2979 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
2980 	const deUint32							queryCount				= static_cast<deUint32>(m_drawRepeats.size());
2981 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2982 
2983 	const VkDeviceSize						vertexBufferOffset		= 0u;
2984 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
2985 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
2986 
2987 	const Unique<VkCommandBuffer>			primaryCmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2988 	std::vector<VkCommandBufferSp>			secondaryCmdBuffers(queryCount);
2989 
2990 	for (deUint32 i = 0; i < queryCount; ++i)
2991 		secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
2992 
2993 	for (deUint32 i = 0; i < queryCount; ++i)
2994 	{
2995 		beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags, *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2996 		vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2997 		vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2998 		for (deUint32 j = 0; j<m_drawRepeats[i]; ++j)
2999 			draw(secondaryCmdBuffers[i]->get());
3000 		endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
3001 	}
3002 
3003 	beginCommandBuffer(vk, *primaryCmdBuffer);
3004 	{
3005 		std::vector<VkClearValue>	renderPassClearValues	(2);
3006 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
3007 
3008 		initialTransitionColor2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3009 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
3010 		initialTransitionDepth2DImage(vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3011 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3012 
3013 		if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
3014 			vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3015 
3016 		for (deUint32 i = 0; i < queryCount; ++i)
3017 		{
3018 			vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
3019 			beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0], VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
3020 			vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
3021 			endRenderPass(vk, *primaryCmdBuffer);
3022 			vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, i);
3023 		}
3024 
3025 		if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
3026 		{
3027 			VkDeviceSize stride = m_parametersGraphic.querySizeFlags() ? sizeof(deUint64) : sizeof(deUint32);
3028 			vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
3029 
3030 			if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3031 			{
3032 				flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3033 				stride *= 2u;
3034 			}
3035 
3036 			if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
3037 			{
3038 				vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3039 				flags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3040 				stride = sizeof(ValueAndAvailability);
3041 			}
3042 
3043 			VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
3044 			vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery, stride, flags);
3045 
3046 			const VkBufferMemoryBarrier barrier =
3047 			{
3048 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
3049 				DE_NULL,									//  const void*		pNext;
3050 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
3051 				VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
3052 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
3053 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
3054 				m_resetBuffer->object(),					//  VkBuffer		buffer;
3055 				0u,											//  VkDeviceSize	offset;
3056 				queryCount * stride + dstOffsetQuery,		//  VkDeviceSize	size;
3057 			};
3058 			vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
3059 		}
3060 
3061 		transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
3062 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3063 	}
3064 	endCommandBuffer(vk, *primaryCmdBuffer);
3065 
3066 	if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3067 		vk.resetQueryPool(device, *queryPool, 0u, queryCount);
3068 
3069 	// Wait for completion
3070 	submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
3071 	return checkResult (*queryPool);
3072 }
3073 
3074 template<class Instance>
3075 class QueryPoolStatisticsTest : public TestCase
3076 {
3077 public:
QueryPoolStatisticsTest(tcu::TestContext & context,const std::string & name,const std::string & description,const ResetType resetType,const CopyType copyType,deBool query64Bits,deBool dstOffset=DE_FALSE)3078 	QueryPoolStatisticsTest (tcu::TestContext &context, const std::string& name, const std::string& description, const ResetType resetType, const CopyType copyType, deBool query64Bits, deBool dstOffset = DE_FALSE)
3079 		: TestCase			(context, name.c_str(), description.c_str())
3080 	{
3081 		const tcu::UVec3	localSize[]		=
3082 		{
3083 			tcu::UVec3	(2u,			2u,	2u),
3084 			tcu::UVec3	(1u,			1u,	1u),
3085 			tcu::UVec3	(WIDTH/(7u*3u),	7u,	3u),
3086 		};
3087 
3088 		const tcu::UVec3	groupSize[]		=
3089 		{
3090 			tcu::UVec3	(2u,			2u,	2u),
3091 			tcu::UVec3	(WIDTH/(7u*3u),	7u,	3u),
3092 			tcu::UVec3	(1u,			1u,	1u),
3093 		};
3094 
3095 		DE_ASSERT(DE_LENGTH_OF_ARRAY(localSize) == DE_LENGTH_OF_ARRAY(groupSize));
3096 
3097 		for(int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(localSize); ++shaderNdx)
3098 		{
3099 			std::ostringstream	shaderName;
3100 			shaderName<< "compute_" << shaderNdx;
3101 			const ComputeInvocationsTestInstance::ParametersCompute	parameters(
3102 				localSize[shaderNdx],
3103 				groupSize[shaderNdx],
3104 				shaderName.str(),
3105 				resetType,
3106 				copyType,
3107 				query64Bits,
3108 				dstOffset
3109 			);
3110 			m_parameters.push_back(parameters);
3111 		}
3112 	}
3113 
createInstance(vkt::Context & context) const3114 	vkt::TestInstance* createInstance (vkt::Context& context) const
3115 	{
3116 		return new Instance(context, m_parameters);
3117 	}
3118 
initPrograms(SourceCollections & sourceCollections) const3119 	void initPrograms(SourceCollections& sourceCollections) const
3120 	{
3121 		std::ostringstream	source;
3122 		source	<< "layout(binding = 0) writeonly buffer Output {\n"
3123 				<< "	uint values[];\n"
3124 				<< "} sb_out;\n\n"
3125 				<< "void main (void) {\n"
3126 				<< "	uvec3 indexUvec3 = uvec3 (gl_GlobalInvocationID.x,\n"
3127 				<< "	                          gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x,\n"
3128 				<< "	                          gl_GlobalInvocationID.z * gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupSize.x * gl_WorkGroupSize.y);\n"
3129 				<< "	uint index = indexUvec3.x + indexUvec3.y + indexUvec3.z;\n"
3130 				<< "	sb_out.values[index] += index;\n"
3131 				<< "}\n";
3132 
3133 		for(size_t shaderNdx = 0; shaderNdx < m_parameters.size(); ++shaderNdx)
3134 		{
3135 			std::ostringstream	src;
3136 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3137 				<< "layout (local_size_x = " << m_parameters[shaderNdx].localSize.x() << ", local_size_y = " << m_parameters[shaderNdx].localSize.y() << ", local_size_z = " << m_parameters[shaderNdx].localSize.z() << ") in;\n"
3138 				<< source.str();
3139 			sourceCollections.glslSources.add(m_parameters[shaderNdx].shaderName) << glu::ComputeSource(src.str());
3140 		}
3141 	}
3142 private:
3143 	std::vector<ComputeInvocationsTestInstance::ParametersCompute>	m_parameters;
3144 };
3145 
3146 template<class Instance>
3147 class QueryPoolGraphicStatisticsTest : public TestCase
3148 {
3149 public:
QueryPoolGraphicStatisticsTest(tcu::TestContext & context,const std::string & name,const std::string & description,const GraphicBasicTestInstance::ParametersGraphic parametersGraphic,const std::vector<deUint64> & drawRepeats)3150 	QueryPoolGraphicStatisticsTest (tcu::TestContext &context, const std::string& name, const std::string& description, const GraphicBasicTestInstance::ParametersGraphic parametersGraphic, const std::vector<deUint64>& drawRepeats)
3151 		: TestCase				(context, name.c_str(), description.c_str())
3152 		, m_parametersGraphic	(parametersGraphic)
3153 		, m_drawRepeats			( drawRepeats )
3154 	{
3155 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3156 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3157 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3158 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3159 
3160 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3161 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3162 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3163 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3164 
3165 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3166 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3167 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3168 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3169 
3170 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3171 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3172 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3173 		m_data.push_back(GraphicBasicTestInstance::VertexData(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3174 	}
3175 
checkSupport(vkt::Context & context) const3176 	void checkSupport (vkt::Context& context) const
3177 	{
3178 		if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
3179 			context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
3180 			!context.getPortabilitySubsetFeatures().triangleFans)
3181 		{
3182 			TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
3183 		}
3184 	}
3185 
createInstance(vkt::Context & context) const3186 	vkt::TestInstance* createInstance (vkt::Context& context) const
3187 	{
3188 		return new Instance(context, m_data, m_parametersGraphic, m_drawRepeats);
3189 	}
3190 
initPrograms(SourceCollections & sourceCollections) const3191 	void initPrograms(SourceCollections& sourceCollections) const
3192 	{
3193 		{ // Vertex Shader
3194 			std::ostringstream	source;
3195 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3196 					<< "layout(location = 0) in highp vec4 in_position;\n"
3197 					<< "layout(location = 1) in vec4 in_color;\n"
3198 					<< "layout(location = 0) out vec4 out_color;\n"
3199 					<< "void main (void)\n"
3200 					<< "{\n"
3201 					<< "	gl_PointSize = 1.0;\n"
3202 					<< "	gl_Position = in_position;\n"
3203 					<< "	out_color = in_color;\n"
3204 					<< "}\n";
3205 			sourceCollections.glslSources.add("vertex") << glu::VertexSource(source.str());
3206 		}
3207 
3208 		if (m_parametersGraphic.queryStatisticFlags & (VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT|
3209 									VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT))
3210 		{// Tessellation control & evaluation
3211 			std::ostringstream source_tc;
3212 			source_tc	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3213 						<< "#extension GL_EXT_tessellation_shader : require\n"
3214 						<< "layout(vertices = 4) out;\n"
3215 						<< "layout(location = 0) in vec4 in_color[];\n"
3216 						<< "layout(location = 0) out vec4 out_color[];\n"
3217 						<< "\n"
3218 						<< "void main (void)\n"
3219 						<< "{\n"
3220 						<< "	if( gl_InvocationID == 0 )\n"
3221 						<< "	{\n"
3222 						<< "		gl_TessLevelInner[0] = 4.0f;\n"
3223 						<< "		gl_TessLevelInner[1] = 4.0f;\n"
3224 						<< "		gl_TessLevelOuter[0] = 4.0f;\n"
3225 						<< "		gl_TessLevelOuter[1] = 4.0f;\n"
3226 						<< "		gl_TessLevelOuter[2] = 4.0f;\n"
3227 						<< "		gl_TessLevelOuter[3] = 4.0f;\n"
3228 						<< "	}\n"
3229 						<< "	out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
3230 						<< "	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3231 						<< "}\n";
3232 			sourceCollections.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str());
3233 
3234 			std::ostringstream source_te;
3235 			source_te	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3236 						<< "#extension GL_EXT_tessellation_shader : require\n"
3237 						<< "layout( quads, equal_spacing, ccw ) in;\n"
3238 						<< "layout(location = 0) in vec4 in_color[];\n"
3239 						<< "layout(location = 0) out vec4 out_color;\n"
3240 						<< "void main (void)\n"
3241 						<< "{\n"
3242 						<< "	const float u = gl_TessCoord.x;\n"
3243 						<< "	const float v = gl_TessCoord.y;\n"
3244 						<< "	const float w = gl_TessCoord.z;\n"
3245 						<< "	gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n"
3246 						<< "	out_color = in_color[0];\n"
3247 						<< "}\n";
3248 			sourceCollections.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str());
3249 		}
3250 
3251 		if(m_parametersGraphic.queryStatisticFlags & (VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT |
3252 									VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT))
3253 		{ // Geometry Shader
3254 			const bool isTopologyPointSize = m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
3255 			std::ostringstream	source;
3256 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3257 					<< "layout("<<inputTypeToGLString(m_parametersGraphic.primitiveTopology)<<") in;\n"
3258 					<< "layout("<<outputTypeToGLString (m_parametersGraphic.primitiveTopology)<<", max_vertices = 16) out;\n"
3259 					<< "layout(location = 0) in vec4 in_color[];\n"
3260 					<< "layout(location = 0) out vec4 out_color;\n"
3261 					<< "void main (void)\n"
3262 					<< "{\n"
3263 					<< "	out_color = in_color[0];\n"
3264 					<< (isTopologyPointSize ? "${pointSize}" : "" )
3265 					<< "	gl_Position = gl_in[0].gl_Position;\n"
3266 					<< "	EmitVertex();\n"
3267 					<< "	EndPrimitive();\n"
3268 					<< "\n"
3269 					<< "	out_color = in_color[0];\n"
3270 					<< (isTopologyPointSize ? "${pointSize}" : "")
3271 					<< "	gl_Position = vec4(1.0, 1.0, 1.0, 1.0);\n"
3272 					<< "	EmitVertex();\n"
3273 					<< "	out_color = in_color[0];\n"
3274 					<< (isTopologyPointSize ? "${pointSize}" : "")
3275 					<< "	gl_Position = vec4(-1.0, -1.0, 1.0, 1.0);\n"
3276 					<< "	EmitVertex();\n"
3277 					<< "	EndPrimitive();\n"
3278 					<< "\n";
3279 			if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
3280 				m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
3281 			{
3282 				source	<< "\n"
3283 						<< "	out_color = in_color[0];\n"
3284 						<< "	gl_Position = gl_in[0].gl_Position;\n"
3285 						<< "	EmitVertex();\n"
3286 						<< "	out_color = in_color[0];\n"
3287 						<< "	gl_Position = gl_in[1].gl_Position;\n"
3288 						<< "	EmitVertex();\n"
3289 						<< "	out_color = in_color[0];\n"
3290 						<< "	gl_Position = gl_in[2].gl_Position;\n"
3291 						<< "	EmitVertex();\n"
3292 						<< "	out_color = in_color[0];\n"
3293 						<< "	gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
3294 						<< "	EmitVertex();\n"
3295 						<< "	EndPrimitive();\n";
3296 			}
3297 			else
3298 			{
3299 				source	<< "	out_color = in_color[0];\n"
3300 						<< (isTopologyPointSize ? "${pointSize}" : "")
3301 						<< "	gl_Position = vec4(1.0, 1.0, 1.0, 1.0);\n"
3302 						<< "	EmitVertex();\n"
3303 						<< "	out_color = in_color[0];\n"
3304 						<< (isTopologyPointSize ? "${pointSize}" : "")
3305 						<< "	gl_Position = vec4(1.0, -1.0, 1.0, 1.0);\n"
3306 						<< "	EmitVertex();\n"
3307 						<< "	out_color = in_color[0];\n"
3308 						<< (isTopologyPointSize ? "${pointSize}" : "")
3309 						<< "	gl_Position = vec4(-1.0, 1.0, 1.0, 1.0);\n"
3310 						<< "	EmitVertex();\n"
3311 						<< "	out_color = in_color[0];\n"
3312 						<< (isTopologyPointSize ? "${pointSize}" : "")
3313 						<< "	gl_Position = vec4(-1.0, -1.0, 1.0, 1.0);\n"
3314 						<< "	EmitVertex();\n"
3315 						<< "	EndPrimitive();\n";
3316 			}
3317 			source	<< "}\n";
3318 
3319 			if (isTopologyPointSize)
3320 			{
3321 				// Add geometry shader codes with and without gl_PointSize if the primitive topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST
3322 
3323 				tcu::StringTemplate sourceTemplate(source.str());
3324 
3325 				std::map<std::string, std::string> pointSize;
3326 				std::map<std::string, std::string> noPointSize;
3327 
3328 				pointSize["pointSize"]		= "	gl_PointSize = gl_in[0].gl_PointSize;\n";
3329 				noPointSize["pointSize"]	= "";
3330 
3331 				sourceCollections.glslSources.add("geometry") << glu::GeometrySource(sourceTemplate.specialize(noPointSize));
3332 				sourceCollections.glslSources.add("geometry_point_size") << glu::GeometrySource(sourceTemplate.specialize(pointSize));
3333 			}
3334 			else
3335 			{
3336 				sourceCollections.glslSources.add("geometry") << glu::GeometrySource(source.str());
3337 			}
3338 		}
3339 
3340 		if (!m_parametersGraphic.vertexOnlyPipe)
3341 		{ // Fragment Shader
3342 			std::ostringstream	source;
3343 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3344 					<< "layout(location = 0) in vec4 in_color;\n"
3345 					<< "layout(location = 0) out vec4 out_color;\n"
3346 					<< "void main()\n"
3347 					<<"{\n"
3348 					<< "	out_color = in_color;\n"
3349 					<< "}\n";
3350 			sourceCollections.glslSources.add("fragment") << glu::FragmentSource(source.str());
3351 		}
3352 	}
3353 private:
3354 	std::vector<GraphicBasicTestInstance::VertexData>	m_data;
3355 	const GraphicBasicTestInstance::ParametersGraphic	m_parametersGraphic;
3356 	std::vector<deUint64>								m_drawRepeats;
3357 };
3358 
3359 #define NUM_QUERY_STATISTICS 4
3360 
3361 class StatisticMultipleQueryTestInstance : public TestInstance
3362 {
3363 public:
3364 					StatisticMultipleQueryTestInstance	(Context& context, const deUint32 queryCount);
3365 protected:
3366 	de::SharedPtr<Buffer> m_queryBuffer;
3367 
3368 	virtual void			checkExtensions		();
3369 };
3370 
StatisticMultipleQueryTestInstance(Context & context,const deUint32 queryCount)3371 StatisticMultipleQueryTestInstance::StatisticMultipleQueryTestInstance (Context& context, const deUint32 queryCount)
3372 	: TestInstance	(context)
3373 	, m_queryBuffer (Buffer::createAndAlloc(context.getDeviceInterface(),
3374 											context.getDevice(),
3375 											BufferCreateInfo(NUM_QUERY_STATISTICS * sizeof(deUint64) * queryCount, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
3376 											context.getDefaultAllocator(),
3377 											vk::MemoryRequirement::HostVisible))
3378 {
3379 	const vk::Allocation& allocation = m_queryBuffer->getBoundMemory();
3380 	void* allocationData = allocation.getHostPtr();
3381 	deMemset(allocationData, 0xff, NUM_QUERY_STATISTICS * sizeof(deUint64) * queryCount);
3382 }
3383 
checkExtensions()3384 void StatisticMultipleQueryTestInstance::checkExtensions ()
3385 {
3386 	if (!m_context.getDeviceFeatures().pipelineStatisticsQuery)
3387 		throw tcu::NotSupportedError("Pipeline statistics queries are not supported");
3388 }
3389 
3390 class GraphicBasicMultipleQueryTestInstance : public StatisticMultipleQueryTestInstance
3391 {
3392 public:
3393 	struct VertexData
3394 	{
VertexDatavkt::QueryPool::__anonc1410ac00111::GraphicBasicMultipleQueryTestInstance::VertexData3395 		VertexData (const tcu::Vec4 position_, const tcu::Vec4 color_)
3396 			: position	(position_)
3397 			, color		(color_)
3398 		{}
3399 		tcu::Vec4	position;
3400 		tcu::Vec4	color;
3401 	};
3402 
3403 	struct ParametersGraphic : public GenericParameters
3404 	{
ParametersGraphicvkt::QueryPool::__anonc1410ac00111::GraphicBasicMultipleQueryTestInstance::ParametersGraphic3405 		ParametersGraphic (const VkQueryPipelineStatisticFlags queryStatisticFlags_, const VkQueryResultFlags queryFlags_, const deUint32 queryCount_, const deBool vertexOnlyPipe_, const CopyType copyType_, const deUint32 dstOffset_)
3406 			: GenericParameters		{ RESET_TYPE_NORMAL, copyType_, (queryFlags_ & VK_QUERY_RESULT_64_BIT) != 0u, dstOffset_ != 0u}
3407 			, queryStatisticFlags	(queryStatisticFlags_)
3408 			, vertexOnlyPipe		(vertexOnlyPipe_)
3409 			, queryFlags			(queryFlags_)
3410 			, queryCount			(queryCount_)
3411 			, dstOffset				(dstOffset_)
3412 			{}
3413 
3414 		VkQueryPipelineStatisticFlags	queryStatisticFlags;
3415 		VkPrimitiveTopology				primitiveTopology;
3416 		deBool							vertexOnlyPipe;
3417 		VkQueryResultFlags				queryFlags;
3418 		deUint32						queryCount;
3419 		deUint32						dstOffset;
3420 	};
3421 											GraphicBasicMultipleQueryTestInstance			(vkt::Context&					context,
3422 																							 const std::vector<VertexData>&	data,
3423 																							 const ParametersGraphic&		parametersGraphic);
3424 	tcu::TestStatus							iterate								(void);
3425 protected:
3426 	de::SharedPtr<Buffer>					creatAndFillVertexBuffer			(void);
3427 	virtual void							createPipeline						(void) = 0;
3428 	void									creatColorAttachmentAndRenderPass	(void);
3429 	virtual tcu::TestStatus					executeTest							(void) = 0;
3430 	virtual tcu::TestStatus					checkResult							(VkQueryPool queryPool) = 0;
3431 	virtual void							draw								(VkCommandBuffer cmdBuffer) = 0;
3432 
3433 	const VkFormat						m_colorAttachmentFormat;
3434 	de::SharedPtr<Image>				m_colorAttachmentImage;
3435 	de::SharedPtr<Image>				m_depthImage;
3436 	Move<VkImageView>					m_attachmentView;
3437 	Move<VkImageView>					m_depthiew;
3438 	Move<VkRenderPass>					m_renderPass;
3439 	Move<VkFramebuffer>					m_framebuffer;
3440 	Move<VkPipeline>					m_pipeline;
3441 	Move<VkPipelineLayout>				m_pipelineLayout;
3442 	const std::vector<VertexData>&		m_data;
3443 	const ParametersGraphic&			m_parametersGraphic;
3444 };
3445 
GraphicBasicMultipleQueryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic)3446 GraphicBasicMultipleQueryTestInstance::GraphicBasicMultipleQueryTestInstance (vkt::Context&					context,
3447 																			  const std::vector<VertexData>&	data,
3448 																			  const ParametersGraphic&		parametersGraphic)
3449 	: StatisticMultipleQueryTestInstance	(context, (parametersGraphic.queryCount + (parametersGraphic.dstOffset != 0u ? 1u : 0u)))
3450 	, m_colorAttachmentFormat		(VK_FORMAT_R8G8B8A8_UNORM)
3451 	, m_data						(data)
3452 	, m_parametersGraphic			(parametersGraphic)
3453 {
3454 }
3455 
iterate(void)3456 tcu::TestStatus GraphicBasicMultipleQueryTestInstance::iterate (void)
3457 {
3458 	checkExtensions();
3459 	creatColorAttachmentAndRenderPass();
3460 	createPipeline();
3461 	return executeTest();
3462 }
3463 
creatAndFillVertexBuffer(void)3464 de::SharedPtr<Buffer> GraphicBasicMultipleQueryTestInstance::creatAndFillVertexBuffer (void)
3465 {
3466 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
3467 	const VkDevice				device			= m_context.getDevice();
3468 
3469 	const VkDeviceSize			dataSize		= static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>( m_data.size() * sizeof(VertexData)),
3470 		static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
3471 
3472 	de::SharedPtr<Buffer>		vertexBuffer	= Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize,
3473 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
3474 
3475 	deUint8*					ptr				= reinterpret_cast<deUint8*>(vertexBuffer->getBoundMemory().getHostPtr());
3476 	deMemcpy(ptr, &m_data[0], static_cast<size_t>( m_data.size() * sizeof(VertexData)));
3477 
3478 	flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(), vertexBuffer->getBoundMemory().getOffset(), dataSize);
3479 	return vertexBuffer;
3480 }
3481 
creatColorAttachmentAndRenderPass(void)3482 void GraphicBasicMultipleQueryTestInstance::creatColorAttachmentAndRenderPass (void)
3483 {
3484 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
3485 	const VkDevice			device	= m_context.getDevice();
3486 
3487 	{
3488 		VkExtent3D					imageExtent				=
3489 		{
3490 			WIDTH,	// width;
3491 			HEIGHT,	// height;
3492 			1u		// depth;
3493 		};
3494 
3495 		const ImageCreateInfo		colorImageCreateInfo	(VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
3496 															VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
3497 
3498 		m_colorAttachmentImage	= Image::createAndAlloc(vk, device, colorImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
3499 
3500 		const ImageViewCreateInfo	attachmentViewInfo		(m_colorAttachmentImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
3501 		m_attachmentView			= createImageView(vk, device, &attachmentViewInfo);
3502 
3503 		ImageCreateInfo				depthImageCreateInfo	(vk::VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
3504 															 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
3505 
3506 		m_depthImage				= Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
3507 
3508 		// Construct a depth  view from depth image
3509 		const ImageViewCreateInfo	depthViewInfo			(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM);
3510 		m_depthiew				= vk::createImageView(vk, device, &depthViewInfo);
3511 	}
3512 
3513 	{
3514 		// Renderpass and Framebuffer
3515 		RenderPassCreateInfo		renderPassCreateInfo;
3516 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,						// format
3517 																	VK_SAMPLE_COUNT_1_BIT,						// samples
3518 																	VK_ATTACHMENT_LOAD_OP_CLEAR,				// loadOp
3519 																	VK_ATTACHMENT_STORE_OP_STORE ,				// storeOp
3520 																	VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// stencilLoadOp
3521 																	VK_ATTACHMENT_STORE_OP_STORE ,				// stencilLoadOp
3522 																	VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// initialLauout
3523 																	VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));	// finalLayout
3524 
3525 		renderPassCreateInfo.addAttachment(AttachmentDescription(VK_FORMAT_D16_UNORM,										// format
3526 																 vk::VK_SAMPLE_COUNT_1_BIT,									// samples
3527 																 vk::VK_ATTACHMENT_LOAD_OP_CLEAR,							// loadOp
3528 																 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,						// storeOp
3529 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// stencilLoadOp
3530 																 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,						// stencilLoadOp
3531 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,		// initialLauout
3532 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));	// finalLayout
3533 
3534 		const VkAttachmentReference	colorAttachmentReference =
3535 		{
3536 			0u,											// attachment
3537 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// layout
3538 		};
3539 
3540 		const VkAttachmentReference depthAttachmentReference =
3541 		{
3542 			1u,															// attachment
3543 			vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL		// layout
3544 		};
3545 
3546 		const VkSubpassDescription	subpass =
3547 		{
3548 			(VkSubpassDescriptionFlags) 0,		//VkSubpassDescriptionFlags		flags;
3549 			VK_PIPELINE_BIND_POINT_GRAPHICS,	//VkPipelineBindPoint			pipelineBindPoint;
3550 			0u,									//deUint32						inputAttachmentCount;
3551 			DE_NULL,							//const VkAttachmentReference*	pInputAttachments;
3552 			1u,									//deUint32						colorAttachmentCount;
3553 			&colorAttachmentReference,			//const VkAttachmentReference*	pColorAttachments;
3554 			DE_NULL,							//const VkAttachmentReference*	pResolveAttachments;
3555 			&depthAttachmentReference,			//const VkAttachmentReference*	pDepthStencilAttachment;
3556 			0u,									//deUint32						preserveAttachmentCount;
3557 			DE_NULL,							//const deUint32*				pPreserveAttachments;
3558 		};
3559 
3560 		renderPassCreateInfo.addSubpass(subpass);
3561 		m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
3562 
3563 		std::vector<vk::VkImageView> attachments(2);
3564 		attachments[0] = *m_attachmentView;
3565 		attachments[1] = *m_depthiew;
3566 
3567 		FramebufferCreateInfo		framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
3568 		m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
3569 	}
3570 }
3571 
3572 class VertexShaderMultipleQueryTestInstance : public GraphicBasicMultipleQueryTestInstance
3573 {
3574 public:
3575 							VertexShaderMultipleQueryTestInstance	(vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic);
3576 protected:
3577 	virtual void			createPipeline				(void);
3578 	virtual tcu::TestStatus	executeTest					(void);
3579 	virtual tcu::TestStatus	checkResult					(VkQueryPool queryPool);
3580 	void					draw						(VkCommandBuffer cmdBuffer);
3581 	deUint64				calculateExpectedMin		(VkQueryResultFlags flag);
3582 	deUint64				calculateExpectedMax		(VkQueryResultFlags flag);
3583 };
3584 
VertexShaderMultipleQueryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic)3585 VertexShaderMultipleQueryTestInstance::VertexShaderMultipleQueryTestInstance (vkt::Context& context, const std::vector<VertexData>& data, const ParametersGraphic& parametersGraphic)
3586 	: GraphicBasicMultipleQueryTestInstance	(context, data, parametersGraphic)
3587 {
3588 }
3589 
createPipeline(void)3590 void VertexShaderMultipleQueryTestInstance::createPipeline (void)
3591 {
3592 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
3593 	const VkDevice			device	= m_context.getDevice();
3594 
3595 	// Pipeline
3596 	Unique<VkShaderModule>	vs(createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), 0));
3597 	Move<VkShaderModule>	fs;
3598 
3599 	if (!m_parametersGraphic.vertexOnlyPipe)
3600 		fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), 0);
3601 
3602 	const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
3603 
3604 	const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
3605 	m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
3606 
3607 	const VkVertexInputBindingDescription vertexInputBindingDescription		=
3608 	{
3609 		0,											// binding;
3610 		static_cast<deUint32>(sizeof(VertexData)),	// stride;
3611 		VK_VERTEX_INPUT_RATE_VERTEX				// inputRate
3612 	};
3613 
3614 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
3615 	{
3616 		{
3617 			0u,
3618 			0u,
3619 			VK_FORMAT_R32G32B32A32_SFLOAT,
3620 			0u
3621 		},	// VertexElementData::position
3622 		{
3623 			1u,
3624 			0u,
3625 			VK_FORMAT_R32G32B32A32_SFLOAT,
3626 			static_cast<deUint32>(sizeof(tcu::Vec4))
3627 		},	// VertexElementData::color
3628 	};
3629 
3630 	const VkPipelineVertexInputStateCreateInfo vf_info			=
3631 	{																	// sType;
3632 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// pNext;
3633 		NULL,															// flags;
3634 		0u,																// vertexBindingDescriptionCount;
3635 		1u,																// pVertexBindingDescriptions;
3636 		&vertexInputBindingDescription,									// vertexAttributeDescriptionCount;
3637 		2u,																// pVertexAttributeDescriptions;
3638 		vertexInputAttributeDescriptions
3639 	};
3640 
3641 	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
3642 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
3643 	if (!m_parametersGraphic.vertexOnlyPipe)
3644 		pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
3645 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
3646 	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
3647 	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
3648 
3649 	const VkViewport	viewport	= makeViewport(WIDTH, HEIGHT);
3650 	const VkRect2D		scissor		= makeRect2D(WIDTH, HEIGHT);
3651 	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1u, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
3652 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
3653 	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
3654 	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
3655 	pipelineCreateInfo.addState(vf_info);
3656 	m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
3657 }
3658 
executeTest(void)3659 tcu::TestStatus VertexShaderMultipleQueryTestInstance::executeTest (void)
3660 {
3661 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
3662 	const VkDevice							device					= m_context.getDevice();
3663 	const VkQueue							queue					= m_context.getUniversalQueue();
3664 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
3665 
3666 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
3667 	const Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, &cmdPoolCreateInfo);
3668 	const Unique<VkQueryPool>				queryPool				(makeQueryPool(vk, device, m_parametersGraphic.queryCount, m_parametersGraphic.queryStatisticFlags));
3669 
3670 	const VkDeviceSize						vertexBufferOffset		= 0u;
3671 	const de::SharedPtr<Buffer>				vertexBufferSp			= creatAndFillVertexBuffer();
3672 	const VkBuffer							vertexBuffer			= vertexBufferSp->object();
3673 
3674 	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3675 
3676 	beginCommandBuffer(vk, *cmdBuffer);
3677 	{
3678 		std::vector<VkClearValue>	renderPassClearValues	(2);
3679 		deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
3680 
3681 		initialTransitionColor2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3682 									  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
3683 		initialTransitionDepth2DImage(vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3684 									  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3685 
3686 		vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, m_parametersGraphic.queryCount);
3687 
3688 		beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0]);
3689 
3690 		vk.cmdBeginQuery(*cmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
3691 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
3692 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3693 
3694 		draw(*cmdBuffer);
3695 
3696 		vk.cmdEndQuery(*cmdBuffer, *queryPool, 0u);
3697 
3698 		endRenderPass(vk, *cmdBuffer);
3699 
3700 		if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
3701 		{
3702 			vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, m_parametersGraphic.queryCount, m_queryBuffer->object(), m_parametersGraphic.dstOffset, NUM_QUERY_STATISTICS * sizeof(deUint64), m_parametersGraphic.queryFlags);
3703 
3704 			const VkDeviceSize bufferSize = NUM_QUERY_STATISTICS * sizeof(deUint64) * m_parametersGraphic.queryCount;
3705 			const VkBufferMemoryBarrier barrier =
3706 			{
3707 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
3708 				DE_NULL,									//  const void*		pNext;
3709 				VK_ACCESS_TRANSFER_WRITE_BIT,				//  VkAccessFlags	srcAccessMask;
3710 			    VK_ACCESS_HOST_READ_BIT,					//  VkAccessFlags	dstAccessMask;
3711 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
3712 				VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
3713 				m_queryBuffer->object(),					//  VkBuffer		buffer;
3714 				0u,											//  VkDeviceSize	offset;
3715 				bufferSize,									//  VkDeviceSize	size;
3716 			};
3717 
3718 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
3719 		}
3720 
3721 		transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
3722 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3723 	}
3724 	endCommandBuffer(vk, *cmdBuffer);
3725 
3726 	// Wait for completion
3727 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
3728 	return checkResult (*queryPool);
3729 }
3730 
calculateExpectedMin(VkQueryResultFlags flag)3731 deUint64 VertexShaderMultipleQueryTestInstance::calculateExpectedMin(VkQueryResultFlags flag)
3732 {
3733 	deUint64	expectedMin	= 0u;
3734 	switch (flag)
3735 	{
3736 	case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT:
3737 		expectedMin = 15u;
3738 		break;
3739 
3740 	case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT:
3741 		expectedMin = 5u;
3742 		break;
3743 
3744 	case VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT:
3745 		expectedMin = 15u;
3746 		break;
3747 
3748 	case VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT:
3749 		expectedMin = 2016u;
3750 		break;
3751 	default:
3752 		DE_FATAL("Unexpected type of statistics query");
3753 		break;
3754 	}
3755 	return expectedMin;
3756 }
3757 
3758 /* This is just to check that driver doesn't return garbage for the partial, no wait case.
3759  * TODO: adjust the values accordingly, in case some driver returns higher values.
3760  */
calculateExpectedMax(VkQueryResultFlags flag)3761 deUint64 VertexShaderMultipleQueryTestInstance::calculateExpectedMax(VkQueryResultFlags flag)
3762 {
3763 	deUint64	expectedMax	= 0u;
3764 	switch (flag)
3765 	{
3766 	case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT:
3767 		expectedMax = 16u;
3768 		break;
3769 
3770 	case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT:
3771 		expectedMax = 5u;
3772 		break;
3773 
3774 	case VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT:
3775 		expectedMax = 15u;
3776 		break;
3777 
3778 	case VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT:
3779 		expectedMax = 2304u;
3780 		break;
3781 	default:
3782 		DE_FATAL("Unexpected type of statistics query");
3783 		break;
3784 	}
3785 	return expectedMax;
3786 }
3787 
checkResult(VkQueryPool queryPool)3788 tcu::TestStatus VertexShaderMultipleQueryTestInstance::checkResult (VkQueryPool queryPool)
3789 {
3790 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
3791 	const VkDevice			device				= m_context.getDevice();
3792 	deUint32				queryCount			= (m_parametersGraphic.queryCount + (m_parametersGraphic.dstOffset ? 1u : 0u));
3793 	deUint32				size				= NUM_QUERY_STATISTICS * queryCount;
3794 	std::vector<deUint64>   results;
3795     results.resize(size);
3796 
3797 	deBool					hasPartialFlag		= (deBool)(m_parametersGraphic.queryFlags & VK_QUERY_RESULT_PARTIAL_BIT);
3798 	deBool					hasWaitFlag			= (deBool)(m_parametersGraphic.queryFlags & VK_QUERY_RESULT_WAIT_BIT);
3799 	// Use the last value of each query to store the availability bit for the vertexOnlyPipe case.
3800 	VkQueryResultFlags		queryFlags			= m_parametersGraphic.queryFlags;
3801 
3802 	if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
3803 	{
3804 		const vk::Allocation& allocation = m_queryBuffer->getBoundMemory();
3805 		const void* allocationData = allocation.getHostPtr();
3806 
3807 		vk::invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), allocation);
3808 		deMemcpy(results.data(), allocationData, size * sizeof(deUint64));
3809 	}
3810 	else
3811 	{
3812 		VkResult result = vk.getQueryPoolResults(device, queryPool, 0u, m_parametersGraphic.queryCount, size * sizeof(deUint64), results.data(), NUM_QUERY_STATISTICS * sizeof(deUint64), queryFlags);
3813 
3814 		if (!(result == VK_SUCCESS || (!hasWaitFlag && result == VK_NOT_READY)))
3815 			return tcu::TestStatus::fail("Unexpected getQueryPoolResults() returned value: " + de::toString(getResultStr(result)));
3816 	}
3817 
3818 	for (deUint32 queryIdx = 0; queryIdx < queryCount; queryIdx++)
3819 	{
3820 		deInt32					queryMask			= m_parametersGraphic.queryStatisticFlags;
3821 		deUint32				index				= queryIdx * NUM_QUERY_STATISTICS;
3822 		// Last element of each query is the availability value for the vertexOnlyPipe case.
3823 		deBool availableQuery = results[index + (NUM_QUERY_STATISTICS - 1)] != 0u;
3824 
3825 		// Check dstOffset values were not overwritten.
3826 		if (m_parametersGraphic.dstOffset != 0u && queryIdx == 0u)
3827 		{
3828 			const deUint64 refVal = 0xfffffffffffffffful;
3829 			for (; index < NUM_QUERY_STATISTICS; index++)
3830 			{
3831 				if (results[index] != refVal)
3832 					return tcu::TestStatus::fail("dstOffset values were overwritten");
3833 			}
3834 			continue;
3835         }
3836 
3837 		if (hasWaitFlag && !hasPartialFlag && !availableQuery)
3838 			return tcu::TestStatus::fail("Results should be available");
3839 
3840 		while(queryMask)
3841 		{
3842 			deInt32		statisticBit = deInt32BitScan(&queryMask);
3843 			deUint64	expectedMin	= calculateExpectedMin((1u << statisticBit));
3844 			deUint64	expectedMax	= calculateExpectedMax((1u << statisticBit));
3845 
3846 			if (availableQuery && (results[index] < expectedMin))
3847 				return tcu::TestStatus::fail("QueryPoolResults incorrect: wrong value (" + de::toString(results[index]) + ") is lower than expected (" + de::toString(expectedMin) + ")");
3848 
3849 			/* From the spec:
3850 			 *
3851 			 *    If VK_QUERY_RESULT_PARTIAL_BIT is set, VK_QUERY_RESULT_WAIT_BIT is not set,
3852 			 *    and the query's status is unavailable, an intermediate result value between zero
3853 			 *    and the final result value is written to pData for that query.
3854 			 */
3855 			if (hasPartialFlag && !hasWaitFlag && !availableQuery && results[index] > expectedMax)
3856 				return tcu::TestStatus::fail("QueryPoolResults incorrect: wrong partial value (" + de::toString(results[index]) + ") is greater than expected (" + de::toString(expectedMax) + ")");
3857 
3858 			index++;
3859 		}
3860 	}
3861 
3862 	return tcu::TestStatus::pass("Pass");
3863 }
3864 
draw(VkCommandBuffer cmdBuffer)3865 void VertexShaderMultipleQueryTestInstance::draw (VkCommandBuffer cmdBuffer)
3866 {
3867 	const DeviceInterface& vk = m_context.getDeviceInterface();
3868 	vk.cmdDraw(cmdBuffer, 16u, 1u, 0u, 0u);
3869 }
3870 
3871 template<class Instance>
3872 class QueryPoolGraphicMultipleQueryStatisticsTest : public TestCase
3873 {
3874 public:
QueryPoolGraphicMultipleQueryStatisticsTest(tcu::TestContext & context,const std::string & name,const std::string & description,const GraphicBasicMultipleQueryTestInstance::ParametersGraphic parametersGraphic)3875 	QueryPoolGraphicMultipleQueryStatisticsTest (tcu::TestContext &context, const std::string& name, const std::string& description, const GraphicBasicMultipleQueryTestInstance::ParametersGraphic parametersGraphic)
3876 		: TestCase				(context, name.c_str(), description.c_str())
3877 		, m_parametersGraphic	(parametersGraphic)
3878 	{
3879 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3880 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3881 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3882 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3883 
3884 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3885 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3886 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3887 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3888 
3889 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3890 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3891 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3892 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3893 
3894 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3895 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3896 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3897 		m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3898 	}
3899 
createInstance(vkt::Context & context) const3900 	vkt::TestInstance* createInstance (vkt::Context& context) const
3901 	{
3902 		return new Instance(context, m_data, m_parametersGraphic);
3903 	}
3904 
initPrograms(SourceCollections & sourceCollections) const3905 	void initPrograms(SourceCollections& sourceCollections) const
3906 	{
3907 		{ // Vertex Shader
3908 			std::ostringstream	source;
3909 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3910 					<< "layout(location = 0) in highp vec4 in_position;\n"
3911 					<< "layout(location = 1) in vec4 in_color;\n"
3912 					<< "layout(location = 0) out vec4 out_color;\n"
3913 					<< "void main (void)\n"
3914 					<< "{\n"
3915 					<< "	gl_PointSize = 1.0;\n"
3916 					<< "	gl_Position = in_position;\n"
3917 					<< "	out_color = in_color;\n"
3918 					<< "}\n";
3919 			sourceCollections.glslSources.add("vertex") << glu::VertexSource(source.str());
3920 		}
3921 
3922 		if (!m_parametersGraphic.vertexOnlyPipe)
3923 		{ // Fragment Shader
3924 			std::ostringstream	source;
3925 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3926 					<< "layout(location = 0) in vec4 in_color;\n"
3927 					<< "layout(location = 0) out vec4 out_color;\n"
3928 					<< "void main()\n"
3929 					<<"{\n"
3930 					<< "	out_color = in_color;\n"
3931 					<< "}\n";
3932 			sourceCollections.glslSources.add("fragment") << glu::FragmentSource(source.str());
3933 		}
3934 	}
3935 private:
3936 	std::vector<GraphicBasicMultipleQueryTestInstance::VertexData>	m_data;
3937 	const GraphicBasicMultipleQueryTestInstance::ParametersGraphic	m_parametersGraphic;
3938 };
3939 
3940 } //anonymous
3941 
QueryPoolStatisticsTests(tcu::TestContext & testCtx)3942 QueryPoolStatisticsTests::QueryPoolStatisticsTests (tcu::TestContext &testCtx)
3943 	: TestCaseGroup(testCtx, "statistics_query", "Tests for statistics queries")
3944 {
3945 }
3946 
bitPrefix(deBool query64bits,deBool dstOffset)3947 inline std::string bitPrefix(deBool query64bits, deBool dstOffset)
3948 {
3949 	std::string prefix = (query64bits ? "64bits_" : "32bits_");
3950 	prefix += (dstOffset ? "dstoffset_" : "");
3951 	return prefix;
3952 }
3953 
init(void)3954 void QueryPoolStatisticsTests::init (void)
3955 {
3956 	std::string topology_name [VK_PRIMITIVE_TOPOLOGY_LAST] =
3957 	{
3958 		"point_list",
3959 		"line_list",
3960 		"line_strip",
3961 		"triangle_list",
3962 		"triangle_strip",
3963 		"triangle_fan",
3964 		"line_list_with_adjacency",
3965 		"line_strip_with_adjacency",
3966 		"triangle_list_with_adjacency",
3967 		"triangle_strip_with_adjacency",
3968 		"patch_list"
3969 	};
3970 
3971 	std::vector<deUint64> sixRepeats								= { 1, 3, 5, 8, 15, 24 };
3972 	de::MovePtr<TestCaseGroup>	computeShaderInvocationsGroup		(new TestCaseGroup(m_testCtx, "compute_shader_invocations",			"Query pipeline statistic compute shader invocations"));
3973 	de::MovePtr<TestCaseGroup>	inputAssemblyVertices				(new TestCaseGroup(m_testCtx, "input_assembly_vertices",			"Query pipeline statistic input assembly vertices"));
3974 	de::MovePtr<TestCaseGroup>	inputAssemblyPrimitives				(new TestCaseGroup(m_testCtx, "input_assembly_primitives",			"Query pipeline statistic input assembly primitives"));
3975 	de::MovePtr<TestCaseGroup>	vertexShaderInvocations				(new TestCaseGroup(m_testCtx, "vertex_shader_invocations",			"Query pipeline statistic vertex shader invocation"));
3976 	de::MovePtr<TestCaseGroup>	fragmentShaderInvocations			(new TestCaseGroup(m_testCtx, "fragment_shader_invocations",		"Query pipeline statistic fragment shader invocation"));
3977 	de::MovePtr<TestCaseGroup>	geometryShaderInvocations			(new TestCaseGroup(m_testCtx, "geometry_shader_invocations",		"Query pipeline statistic geometry shader invocation"));
3978 	de::MovePtr<TestCaseGroup>	geometryShaderPrimitives			(new TestCaseGroup(m_testCtx, "geometry_shader_primitives",			"Query pipeline statistic geometry shader primitives"));
3979 	de::MovePtr<TestCaseGroup>	clippingInvocations					(new TestCaseGroup(m_testCtx, "clipping_invocations",				"Query pipeline statistic clipping invocations"));
3980 	de::MovePtr<TestCaseGroup>	clippingPrimitives					(new TestCaseGroup(m_testCtx, "clipping_primitives",				"Query pipeline statistic clipping primitives"));
3981 	de::MovePtr<TestCaseGroup>	tesControlPatches					(new TestCaseGroup(m_testCtx, "tes_control_patches",				"Query pipeline statistic tessellation control shader patches"));
3982 	de::MovePtr<TestCaseGroup>	tesEvaluationShaderInvocations		(new TestCaseGroup(m_testCtx, "tes_evaluation_shader_invocations",	"Query pipeline statistic tessellation evaluation shader invocations"));
3983 
3984 	de::MovePtr<TestCaseGroup>	vertexOnlyGroup									(new TestCaseGroup(m_testCtx, "vertex_only",						"Use only vertex shader in a graphics pipeline"));
3985 	de::MovePtr<TestCaseGroup>	inputAssemblyVerticesVertexOnly					(new TestCaseGroup(m_testCtx, "input_assembly_vertices",			"Query pipeline statistic input assembly vertices"));
3986 	de::MovePtr<TestCaseGroup>	inputAssemblyPrimitivesVertexOnly				(new TestCaseGroup(m_testCtx, "input_assembly_primitives",			"Query pipeline statistic input assembly primitives"));
3987 	de::MovePtr<TestCaseGroup>	vertexShaderInvocationsVertexOnly				(new TestCaseGroup(m_testCtx, "vertex_shader_invocations",			"Query pipeline statistic vertex shader invocation"));
3988 
3989 	de::MovePtr<TestCaseGroup>	hostQueryResetGroup								(new TestCaseGroup(m_testCtx, "host_query_reset",					"Check host query reset pipeline statistic compute shader invocations"));
3990 	de::MovePtr<TestCaseGroup>	computeShaderInvocationsGroupHostQueryReset		(new TestCaseGroup(m_testCtx, "compute_shader_invocations",			"Query pipeline statistic compute shader invocations"));
3991 	de::MovePtr<TestCaseGroup>	inputAssemblyVerticesHostQueryReset				(new TestCaseGroup(m_testCtx, "input_assembly_vertices",			"Query pipeline statistic input assembly vertices"));
3992 	de::MovePtr<TestCaseGroup>	inputAssemblyPrimitivesHostQueryReset			(new TestCaseGroup(m_testCtx, "input_assembly_primitives",			"Query pipeline statistic input assembly primitives"));
3993 	de::MovePtr<TestCaseGroup>	vertexShaderInvocationsHostQueryReset			(new TestCaseGroup(m_testCtx, "vertex_shader_invocations",			"Query pipeline statistic vertex shader invocation"));
3994 	de::MovePtr<TestCaseGroup>	fragmentShaderInvocationsHostQueryReset			(new TestCaseGroup(m_testCtx, "fragment_shader_invocations",		"Query pipeline statistic fragment shader invocation"));
3995 	de::MovePtr<TestCaseGroup>	geometryShaderInvocationsHostQueryReset			(new TestCaseGroup(m_testCtx, "geometry_shader_invocations",		"Query pipeline statistic geometry shader invocation"));
3996 	de::MovePtr<TestCaseGroup>	geometryShaderPrimitivesHostQueryReset			(new TestCaseGroup(m_testCtx, "geometry_shader_primitives",			"Query pipeline statistic geometry shader primitives"));
3997 	de::MovePtr<TestCaseGroup>	clippingInvocationsHostQueryReset				(new TestCaseGroup(m_testCtx, "clipping_invocations",				"Query pipeline statistic clipping invocations"));
3998 	de::MovePtr<TestCaseGroup>	clippingPrimitivesHostQueryReset				(new TestCaseGroup(m_testCtx, "clipping_primitives",				"Query pipeline statistic clipping primitives"));
3999 	de::MovePtr<TestCaseGroup>	tesControlPatchesHostQueryReset					(new TestCaseGroup(m_testCtx, "tes_control_patches",				"Query pipeline statistic tessellation control shader patches"));
4000 	de::MovePtr<TestCaseGroup>	tesEvaluationShaderInvocationsHostQueryReset	(new TestCaseGroup(m_testCtx, "tes_evaluation_shader_invocations",	"Query pipeline statistic tessellation evaluation shader invocations"));
4001 
4002 	de::MovePtr<TestCaseGroup>	resetBeforeCopyGroup							(new TestCaseGroup(m_testCtx, "reset_before_copy",					"Check pipeline statistic unavailability when resetting before copying"));
4003 	de::MovePtr<TestCaseGroup>	computeShaderInvocationsGroupResetBeforeCopy	(new TestCaseGroup(m_testCtx, "compute_shader_invocations",			"Query pipeline statistic compute shader invocations"));
4004 	de::MovePtr<TestCaseGroup>	inputAssemblyVerticesResetBeforeCopy			(new TestCaseGroup(m_testCtx, "input_assembly_vertices",			"Query pipeline statistic input assembly vertices"));
4005 	de::MovePtr<TestCaseGroup>	inputAssemblyPrimitivesResetBeforeCopy			(new TestCaseGroup(m_testCtx, "input_assembly_primitives",			"Query pipeline statistic input assembly primitives"));
4006 	de::MovePtr<TestCaseGroup>	vertexShaderInvocationsResetBeforeCopy			(new TestCaseGroup(m_testCtx, "vertex_shader_invocations",			"Query pipeline statistic vertex shader invocation"));
4007 	de::MovePtr<TestCaseGroup>	fragmentShaderInvocationsResetBeforeCopy		(new TestCaseGroup(m_testCtx, "fragment_shader_invocations",		"Query pipeline statistic fragment shader invocation"));
4008 	de::MovePtr<TestCaseGroup>	geometryShaderInvocationsResetBeforeCopy		(new TestCaseGroup(m_testCtx, "geometry_shader_invocations",		"Query pipeline statistic geometry shader invocation"));
4009 	de::MovePtr<TestCaseGroup>	geometryShaderPrimitivesResetBeforeCopy			(new TestCaseGroup(m_testCtx, "geometry_shader_primitives",			"Query pipeline statistic geometry shader primitives"));
4010 	de::MovePtr<TestCaseGroup>	clippingInvocationsResetBeforeCopy				(new TestCaseGroup(m_testCtx, "clipping_invocations",				"Query pipeline statistic clipping invocations"));
4011 	de::MovePtr<TestCaseGroup>	clippingPrimitivesResetBeforeCopy				(new TestCaseGroup(m_testCtx, "clipping_primitives",				"Query pipeline statistic clipping primitives"));
4012 	de::MovePtr<TestCaseGroup>	tesControlPatchesResetBeforeCopy				(new TestCaseGroup(m_testCtx, "tes_control_patches",				"Query pipeline statistic tessellation control shader patches"));
4013 	de::MovePtr<TestCaseGroup>	tesEvaluationShaderInvocationsResetBeforeCopy	(new TestCaseGroup(m_testCtx, "tes_evaluation_shader_invocations",	"Query pipeline statistic tessellation evaluation shader invocations"));
4014 
4015 	de::MovePtr<TestCaseGroup>	vertexShaderMultipleQueries						(new TestCaseGroup(m_testCtx, "multiple_queries",				"Query pipeline statistics related to vertex and fragment shaders"));
4016 
4017 	CopyType copyType[]															= { COPY_TYPE_GET,	COPY_TYPE_CMD };
4018 	std::string copyTypeStr[]													= { "",			"cmdcopyquerypoolresults_" };
4019 
4020 	for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4021 	{
4022 		for (deUint32 i = 0; i < 4; ++i)
4023 		{
4024 			deBool query64Bits = (i & 1);
4025 			deBool dstOffset = (i & 2);
4026 			std::string prefix = bitPrefix(query64Bits, dstOffset);
4027 
4028 			// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4029 			if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4030 				continue;
4031 
4032 			computeShaderInvocationsGroup->addChild(new QueryPoolStatisticsTest<ComputeInvocationsTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "primary",				"", RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, dstOffset));
4033 			computeShaderInvocationsGroup->addChild(new QueryPoolStatisticsTest<ComputeInvocationsSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary",			"", RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, dstOffset));
4034 			computeShaderInvocationsGroup->addChild(new QueryPoolStatisticsTest<ComputeInvocationsSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",	"", RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, dstOffset));
4035 
4036 			computeShaderInvocationsGroupHostQueryReset->addChild(new QueryPoolStatisticsTest<ComputeInvocationsTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "primary",				"", RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, dstOffset));
4037 			computeShaderInvocationsGroupHostQueryReset->addChild(new QueryPoolStatisticsTest<ComputeInvocationsSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary",			"", RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, dstOffset));
4038 			computeShaderInvocationsGroupHostQueryReset->addChild(new QueryPoolStatisticsTest<ComputeInvocationsSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",	"", RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, dstOffset));
4039 
4040 			computeShaderInvocationsGroupResetBeforeCopy->addChild(new QueryPoolStatisticsTest<ComputeInvocationsTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "primary",				"", RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, dstOffset));
4041 			computeShaderInvocationsGroupResetBeforeCopy->addChild(new QueryPoolStatisticsTest<ComputeInvocationsSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary",			"", RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, dstOffset));
4042 			computeShaderInvocationsGroupResetBeforeCopy->addChild(new QueryPoolStatisticsTest<ComputeInvocationsSecondaryInheritedTestInstance>(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",	"", RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, dstOffset));
4043 
4044 			//VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT
4045 			inputAssemblyVertices->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "primary",				"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4046 			inputAssemblyVertices->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary",			"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4047 			inputAssemblyVertices->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4048 
4049 			inputAssemblyVerticesVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "primary",				"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4050 			inputAssemblyVerticesVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>				(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary",			"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4051 			inputAssemblyVerticesVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4052 
4053 			inputAssemblyVerticesHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "primary",				"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4054 			inputAssemblyVerticesHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary",			"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4055 			inputAssemblyVerticesHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4056 
4057 
4058 			inputAssemblyVerticesResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "primary",				"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4059 			inputAssemblyVerticesResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary",			"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4060 			inputAssemblyVerticesResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4061 		}
4062 	}
4063 
4064 	//VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT
4065 	{
4066 		de::MovePtr<TestCaseGroup>	primary				(new TestCaseGroup(m_testCtx, "primary",			""));
4067 		de::MovePtr<TestCaseGroup>	secondary			(new TestCaseGroup(m_testCtx, "secondary",			""));
4068 		de::MovePtr<TestCaseGroup>	secondaryInherited	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4069 
4070 		de::MovePtr<TestCaseGroup>	primaryVertexOnly				(new TestCaseGroup(m_testCtx, "primary",			""));
4071 		de::MovePtr<TestCaseGroup>	secondaryVertexOnly				(new TestCaseGroup(m_testCtx, "secondary",			""));
4072 		de::MovePtr<TestCaseGroup>	secondaryInheritedVertexOnly	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4073 
4074 		de::MovePtr<TestCaseGroup>	primaryHostQueryReset				(new TestCaseGroup(m_testCtx, "primary",			""));
4075 		de::MovePtr<TestCaseGroup>	secondaryHostQueryReset				(new TestCaseGroup(m_testCtx, "secondary",			""));
4076 		de::MovePtr<TestCaseGroup>	secondaryInheritedHostQueryReset	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4077 
4078 		de::MovePtr<TestCaseGroup>	primaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "primary",			""));
4079 		de::MovePtr<TestCaseGroup>	secondaryResetBeforeCopy			(new TestCaseGroup(m_testCtx, "secondary",			""));
4080 		de::MovePtr<TestCaseGroup>	secondaryInheritedResetBeforeCopy	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4081 
4082 		for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4083 		{
4084 			for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++topologyNdx)
4085 			{
4086 				for (deUint32 i = 0; i < 4; ++i)
4087 				{
4088 					deBool query64Bits = (i & 1);
4089 					deBool dstOffset = (i & 2);
4090 					std::string prefix = bitPrefix(query64Bits, dstOffset);
4091 
4092 					// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4093 					if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4094 						continue;
4095 
4096 					primary->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4097 					secondary->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4098 					secondaryInherited->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4099 
4100 					primaryHostQueryReset->addChild				(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4101 					secondaryHostQueryReset->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4102 					secondaryInheritedHostQueryReset->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4103 
4104 					primaryVertexOnly->addChild				(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4105 					secondaryVertexOnly->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4106 					secondaryInheritedVertexOnly->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4107 
4108 					primaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4109 					secondaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4110 					secondaryInheritedResetBeforeCopy->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4111 				}
4112 			}
4113 		}
4114 
4115 		inputAssemblyPrimitives->addChild(primary.release());
4116 		inputAssemblyPrimitives->addChild(secondary.release());
4117 		inputAssemblyPrimitives->addChild(secondaryInherited.release());
4118 
4119 		inputAssemblyPrimitivesVertexOnly->addChild(primaryVertexOnly.release());
4120 		inputAssemblyPrimitivesVertexOnly->addChild(secondaryVertexOnly.release());
4121 		inputAssemblyPrimitivesVertexOnly->addChild(secondaryInheritedVertexOnly.release());
4122 
4123 		inputAssemblyPrimitivesHostQueryReset->addChild(primaryHostQueryReset.release());
4124 		inputAssemblyPrimitivesHostQueryReset->addChild(secondaryHostQueryReset.release());
4125 		inputAssemblyPrimitivesHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
4126 
4127 		inputAssemblyPrimitivesResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
4128 		inputAssemblyPrimitivesResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
4129 		inputAssemblyPrimitivesResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
4130 	}
4131 
4132 	//VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT
4133 	{
4134 		de::MovePtr<TestCaseGroup>	primary				(new TestCaseGroup(m_testCtx, "primary",			""));
4135 		de::MovePtr<TestCaseGroup>	secondary			(new TestCaseGroup(m_testCtx, "secondary",			""));
4136 		de::MovePtr<TestCaseGroup>	secondaryInherited	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4137 
4138 		de::MovePtr<TestCaseGroup>	primaryVertexOnly				(new TestCaseGroup(m_testCtx, "primary",			""));
4139 		de::MovePtr<TestCaseGroup>	secondaryVertexOnly				(new TestCaseGroup(m_testCtx, "secondary",			""));
4140 		de::MovePtr<TestCaseGroup>	secondaryInheritedVertexOnly	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4141 
4142 		de::MovePtr<TestCaseGroup>	primaryHostQueryReset				(new TestCaseGroup(m_testCtx, "primary",			""));
4143 		de::MovePtr<TestCaseGroup>	secondaryHostQueryReset				(new TestCaseGroup(m_testCtx, "secondary",			""));
4144 		de::MovePtr<TestCaseGroup>	secondaryInheritedHostQueryReset	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4145 
4146 		de::MovePtr<TestCaseGroup>	primaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "primary",			""));
4147 		de::MovePtr<TestCaseGroup>	secondaryResetBeforeCopy			(new TestCaseGroup(m_testCtx, "secondary",			""));
4148 		de::MovePtr<TestCaseGroup>	secondaryInheritedResetBeforeCopy	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4149 
4150 		for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4151 		{
4152 			for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++topologyNdx)
4153 			{
4154 				for (deUint32 i = 0; i < 4; ++i)
4155 				{
4156 					deBool query64Bits = (i & 1);
4157 					deBool dstOffset = (i & 2);
4158 					std::string prefix = bitPrefix(query64Bits, dstOffset);
4159 
4160 					// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4161 					if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4162 						continue;
4163 
4164 					primary->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4165 					secondary->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4166 					secondaryInherited->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4167 
4168 					primaryVertexOnly->addChild				(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4169 					secondaryVertexOnly->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4170 					secondaryInheritedVertexOnly->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_TRUE, dstOffset), sixRepeats));
4171 
4172 					primaryHostQueryReset->addChild				(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4173 					secondaryHostQueryReset->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4174 					secondaryInheritedHostQueryReset->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4175 
4176 					primaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4177 					secondaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4178 					secondaryInheritedResetBeforeCopy->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4179 				}
4180 			}
4181 		}
4182 
4183 		vertexShaderInvocations->addChild(primary.release());
4184 		vertexShaderInvocations->addChild(secondary.release());
4185 		vertexShaderInvocations->addChild(secondaryInherited.release());
4186 
4187 		vertexShaderInvocationsVertexOnly->addChild(primaryVertexOnly.release());
4188 		vertexShaderInvocationsVertexOnly->addChild(secondaryVertexOnly.release());
4189 		vertexShaderInvocationsVertexOnly->addChild(secondaryInheritedVertexOnly.release());
4190 
4191 		vertexShaderInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
4192 		vertexShaderInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
4193 		vertexShaderInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
4194 
4195 		vertexShaderInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
4196 		vertexShaderInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
4197 		vertexShaderInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
4198 	}
4199 
4200 	//VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT
4201 	{
4202 		de::MovePtr<TestCaseGroup>	primary				(new TestCaseGroup(m_testCtx, "primary",			""));
4203 		de::MovePtr<TestCaseGroup>	secondary			(new TestCaseGroup(m_testCtx, "secondary",			""));
4204 		de::MovePtr<TestCaseGroup>	secondaryInherited	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4205 
4206 		de::MovePtr<TestCaseGroup>	primaryHostQueryReset				(new TestCaseGroup(m_testCtx, "primary",			""));
4207 		de::MovePtr<TestCaseGroup>	secondaryHostQueryReset				(new TestCaseGroup(m_testCtx, "secondary",			""));
4208 		de::MovePtr<TestCaseGroup>	secondaryInheritedHostQueryReset	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4209 
4210 		de::MovePtr<TestCaseGroup>	primaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "primary",			""));
4211 		de::MovePtr<TestCaseGroup>	secondaryResetBeforeCopy			(new TestCaseGroup(m_testCtx, "secondary",			""));
4212 		de::MovePtr<TestCaseGroup>	secondaryInheritedResetBeforeCopy	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4213 
4214 		for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4215 		{
4216 			for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++topologyNdx)
4217 			{
4218 				for (deUint32 i = 0; i < 4; ++i)
4219 				{
4220 					deBool query64Bits = (i & 1);
4221 					deBool dstOffset = (i & 2);
4222 					std::string prefix = bitPrefix(query64Bits, dstOffset);
4223 
4224 					// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4225 					if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4226 						continue;
4227 
4228 					primary->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4229 					secondary->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4230 					secondaryInherited->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4231 
4232 					primaryHostQueryReset->addChild				(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4233 					secondaryHostQueryReset->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4234 					secondaryInheritedHostQueryReset->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4235 
4236 					primaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4237 					secondaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4238 					secondaryInheritedResetBeforeCopy->addChild	(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4239 				}
4240 			}
4241 		}
4242 
4243 		fragmentShaderInvocations->addChild(primary.release());
4244 		fragmentShaderInvocations->addChild(secondary.release());
4245 		fragmentShaderInvocations->addChild(secondaryInherited.release());
4246 
4247 		fragmentShaderInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
4248 		fragmentShaderInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
4249 		fragmentShaderInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
4250 
4251 		fragmentShaderInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
4252 		fragmentShaderInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
4253 		fragmentShaderInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
4254 	}
4255 
4256 	//VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT
4257 	{
4258 		de::MovePtr<TestCaseGroup>	primary				(new TestCaseGroup(m_testCtx, "primary",			""));
4259 		de::MovePtr<TestCaseGroup>	secondary			(new TestCaseGroup(m_testCtx, "secondary",			""));
4260 		de::MovePtr<TestCaseGroup>	secondaryInherited	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4261 
4262 		de::MovePtr<TestCaseGroup>	primaryHostQueryReset				(new TestCaseGroup(m_testCtx, "primary",			""));
4263 		de::MovePtr<TestCaseGroup>	secondaryHostQueryReset				(new TestCaseGroup(m_testCtx, "secondary",			""));
4264 		de::MovePtr<TestCaseGroup>	secondaryInheritedHostQueryReset	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4265 
4266 		de::MovePtr<TestCaseGroup>	primaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "primary",			""));
4267 		de::MovePtr<TestCaseGroup>	secondaryResetBeforeCopy			(new TestCaseGroup(m_testCtx, "secondary",			""));
4268 		de::MovePtr<TestCaseGroup>	secondaryInheritedResetBeforeCopy	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4269 
4270 		for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4271 		{
4272 			for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++topologyNdx)
4273 			{
4274 				for (deUint32 i = 0; i < 4; ++i)
4275 				{
4276 					deBool query64Bits = (i & 1);
4277 					deBool dstOffset = (i & 2);
4278 					std::string prefix = bitPrefix(query64Bits, dstOffset);
4279 
4280 					// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4281 					if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4282 						continue;
4283 
4284 					primary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4285 					secondary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4286 					secondaryInherited->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4287 
4288 					primaryHostQueryReset->addChild				(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4289 					secondaryHostQueryReset->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4290 					secondaryInheritedHostQueryReset->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4291 
4292 					primaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4293 					secondaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4294 					secondaryInheritedResetBeforeCopy->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4295 				}
4296 			}
4297 		}
4298 
4299 		geometryShaderInvocations->addChild(primary.release());
4300 		geometryShaderInvocations->addChild(secondary.release());
4301 		geometryShaderInvocations->addChild(secondaryInherited.release());
4302 
4303 		geometryShaderInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
4304 		geometryShaderInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
4305 		geometryShaderInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
4306 
4307 		geometryShaderInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
4308 		geometryShaderInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
4309 		geometryShaderInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
4310 	}
4311 
4312 	//VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT
4313 	{
4314 		de::MovePtr<TestCaseGroup>	primary				(new TestCaseGroup(m_testCtx, "primary",			""));
4315 		de::MovePtr<TestCaseGroup>	secondary			(new TestCaseGroup(m_testCtx, "secondary",			""));
4316 		de::MovePtr<TestCaseGroup>	secondaryInherited	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4317 
4318 		de::MovePtr<TestCaseGroup>	primaryHostQueryReset				(new TestCaseGroup(m_testCtx, "primary",			""));
4319 		de::MovePtr<TestCaseGroup>	secondaryHostQueryReset				(new TestCaseGroup(m_testCtx, "secondary",			""));
4320 		de::MovePtr<TestCaseGroup>	secondaryInheritedHostQueryReset	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4321 
4322 		de::MovePtr<TestCaseGroup>	primaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "primary",			""));
4323 		de::MovePtr<TestCaseGroup>	secondaryResetBeforeCopy			(new TestCaseGroup(m_testCtx, "secondary",			""));
4324 		de::MovePtr<TestCaseGroup>	secondaryInheritedResetBeforeCopy	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4325 
4326 		for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4327 		{
4328 			for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++topologyNdx)
4329 			{
4330 				for (deUint32 i = 0; i < 4; ++i)
4331 				{
4332 					deBool query64Bits = (i & 1);
4333 					deBool dstOffset = (i & 2);
4334 					std::string prefix = bitPrefix(query64Bits, dstOffset);
4335 
4336 					// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4337 					if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4338 						continue;
4339 
4340 					primary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4341 					secondary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4342 					secondaryInherited->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4343 
4344 					primaryHostQueryReset->addChild				(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4345 					secondaryHostQueryReset->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4346 					secondaryInheritedHostQueryReset->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4347 
4348 					primaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4349 					secondaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4350 					secondaryInheritedResetBeforeCopy->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4351 				}
4352 			}
4353 		}
4354 
4355 		geometryShaderPrimitives->addChild(primary.release());
4356 		geometryShaderPrimitives->addChild(secondary.release());
4357 		geometryShaderPrimitives->addChild(secondaryInherited.release());
4358 
4359 		geometryShaderPrimitivesHostQueryReset->addChild(primaryHostQueryReset.release());
4360 		geometryShaderPrimitivesHostQueryReset->addChild(secondaryHostQueryReset.release());
4361 		geometryShaderPrimitivesHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
4362 
4363 		geometryShaderPrimitivesResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
4364 		geometryShaderPrimitivesResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
4365 		geometryShaderPrimitivesResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
4366 	}
4367 
4368 	//VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT
4369 	{
4370 		de::MovePtr<TestCaseGroup>	primary				(new TestCaseGroup(m_testCtx, "primary",			""));
4371 		de::MovePtr<TestCaseGroup>	secondary			(new TestCaseGroup(m_testCtx, "secondary",			""));
4372 		de::MovePtr<TestCaseGroup>	secondaryInherited	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4373 
4374 		de::MovePtr<TestCaseGroup>	primaryHostQueryReset				(new TestCaseGroup(m_testCtx, "primary",			""));
4375 		de::MovePtr<TestCaseGroup>	secondaryHostQueryReset				(new TestCaseGroup(m_testCtx, "secondary",			""));
4376 		de::MovePtr<TestCaseGroup>	secondaryInheritedHostQueryReset	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4377 
4378 		de::MovePtr<TestCaseGroup>	primaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "primary",			""));
4379 		de::MovePtr<TestCaseGroup>	secondaryResetBeforeCopy			(new TestCaseGroup(m_testCtx, "secondary",			""));
4380 		de::MovePtr<TestCaseGroup>	secondaryInheritedResetBeforeCopy	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4381 
4382 		for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4383 		{
4384 			for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++topologyNdx)
4385 			{
4386 				for (deUint32 i = 0; i < 4; ++i)
4387 				{
4388 					deBool query64Bits = (i & 1);
4389 					deBool dstOffset = (i & 2);
4390 					std::string prefix = bitPrefix(query64Bits, dstOffset);
4391 
4392 					// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4393 					if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4394 						continue;
4395 
4396 					primary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4397 					secondary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4398 					secondaryInherited->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4399 
4400 					primaryHostQueryReset->addChild				(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4401 					secondaryHostQueryReset->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4402 					secondaryInheritedHostQueryReset->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4403 
4404 					primaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4405 					secondaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4406 					secondaryInheritedResetBeforeCopy->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4407 				}
4408 			}
4409 		}
4410 
4411 		clippingInvocations->addChild(primary.release());
4412 		clippingInvocations->addChild(secondary.release());
4413 		clippingInvocations->addChild(secondaryInherited.release());
4414 
4415 		clippingInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
4416 		clippingInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
4417 		clippingInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
4418 
4419 		clippingInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
4420 		clippingInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
4421 		clippingInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
4422 	}
4423 
4424 	//VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT
4425 	{
4426 		de::MovePtr<TestCaseGroup>	primary				(new TestCaseGroup(m_testCtx, "primary",			""));
4427 		de::MovePtr<TestCaseGroup>	secondary			(new TestCaseGroup(m_testCtx, "secondary",			""));
4428 		de::MovePtr<TestCaseGroup>	secondaryInherited	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4429 
4430 		de::MovePtr<TestCaseGroup>	primaryHostQueryReset				(new TestCaseGroup(m_testCtx, "primary",			""));
4431 		de::MovePtr<TestCaseGroup>	secondaryHostQueryReset				(new TestCaseGroup(m_testCtx, "secondary",			""));
4432 		de::MovePtr<TestCaseGroup>	secondaryInheritedHostQueryReset	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4433 
4434 		de::MovePtr<TestCaseGroup>	primaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "primary",			""));
4435 		de::MovePtr<TestCaseGroup>	secondaryResetBeforeCopy				(new TestCaseGroup(m_testCtx, "secondary",			""));
4436 		de::MovePtr<TestCaseGroup>	secondaryInheritedResetBeforeCopy	(new TestCaseGroup(m_testCtx, "secondary_inherited",""));
4437 
4438 		for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4439 		{
4440 			for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++topologyNdx)
4441 			{
4442 				for (deUint32 i = 0; i < 4; ++i)
4443 				{
4444 					deBool query64Bits = (i & 1);
4445 					deBool dstOffset = (i & 2);
4446 					std::string prefix = bitPrefix(query64Bits, dstOffset);
4447 
4448 					// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4449 					if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4450 						continue;
4451 
4452 					primary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4453 					secondary->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4454 					secondaryInherited->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4455 
4456 					primaryHostQueryReset->addChild				(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4457 					secondaryHostQueryReset->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4458 					secondaryInheritedHostQueryReset->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4459 
4460 					primaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>						(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4461 					secondaryResetBeforeCopy->addChild			(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4462 					secondaryInheritedResetBeforeCopy->addChild	(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4463 				}
4464 			}
4465 		}
4466 
4467 		clippingPrimitives->addChild(primary.release());
4468 		clippingPrimitives->addChild(secondary.release());
4469 		clippingPrimitives->addChild(secondaryInherited.release());
4470 
4471 		clippingPrimitivesHostQueryReset->addChild(primaryHostQueryReset.release());
4472 		clippingPrimitivesHostQueryReset->addChild(secondaryHostQueryReset.release());
4473 		clippingPrimitivesHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
4474 
4475 		clippingPrimitivesResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
4476 		clippingPrimitivesResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
4477 		clippingPrimitivesResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
4478 	}
4479 
4480 	//VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT
4481 	for (deUint32 copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
4482 	{
4483 		for (deUint32 i = 0; i < 4; ++i)
4484 		{
4485 			deBool query64Bits = (i & 1);
4486 			deBool dstOffset = (i & 2);
4487 			std::string prefix = bitPrefix(query64Bits, dstOffset);
4488 
4489 			// It makes no sense to use dstOffset with vkGetQueryPoolResults()
4490 			if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
4491 				continue;
4492 
4493 			tesControlPatches->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches",						"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4494 			tesControlPatches->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary",			"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4495 			tesControlPatches->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4496 
4497 			tesControlPatchesHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches",						"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4498 			tesControlPatchesHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary",			"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4499 			tesControlPatchesHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4500 
4501 			tesControlPatchesResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches",						"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4502 			tesControlPatchesResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary",			"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4503 			tesControlPatchesResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4504 
4505 			//VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT
4506 			tesEvaluationShaderInvocations->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>					 (m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations",						"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4507 			tesEvaluationShaderInvocations->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>		 (m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary",				"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4508 			tesEvaluationShaderInvocations->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4509 
4510 			tesEvaluationShaderInvocationsHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations",						"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4511 			tesEvaluationShaderInvocationsHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary",				"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4512 			tesEvaluationShaderInvocationsHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>	(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4513 
4514 			tesEvaluationShaderInvocationsResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>					(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations",						"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4515 			tesEvaluationShaderInvocationsResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>			(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary",				"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4516 			tesEvaluationShaderInvocationsResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(m_testCtx,	prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary_inherited",	"",	GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, DE_FALSE, dstOffset), sixRepeats));
4517 		}
4518 	}
4519 
4520 	// Multiple statistics query flags enabled
4521     {
4522 		VkQueryResultFlags	partialFlags[]		=	{ 0u, VK_QUERY_RESULT_PARTIAL_BIT };
4523 		const char* const	partialFlagsStr[]	=	{ "", "_partial" };
4524 		VkQueryResultFlags	waitFlags[]		=	{ 0u, VK_QUERY_RESULT_WAIT_BIT };
4525 		const char* const	waitFlagsStr[]	=	{ "", "_wait" };
4526 
4527 		const CopyType	copyTypes[]		=	{ COPY_TYPE_GET, COPY_TYPE_CMD, COPY_TYPE_CMD };
4528 		const char* const   copyTypesStr[]	=	{ "", "_cmdcopy", "_cmdcopy_dstoffset" };
4529 
4530 		const VkQueryPipelineStatisticFlags statisticsFlags =
4531 			VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT |
4532 			VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT;
4533 
4534 		for (deUint32 partialFlagsIdx = 0u; partialFlagsIdx < DE_LENGTH_OF_ARRAY(partialFlags); partialFlagsIdx++)
4535 		{
4536 			for (deUint32 waitFlagsIdx = 0u; waitFlagsIdx < DE_LENGTH_OF_ARRAY(waitFlags); waitFlagsIdx++)
4537 			{
4538 				for (deUint32 copyTypesIdx = 0u; copyTypesIdx < DE_LENGTH_OF_ARRAY(copyTypes); copyTypesIdx++)
4539 				{
4540 					deUint32 dstOffset = copyTypesIdx == 2u ? NUM_QUERY_STATISTICS * sizeof(deUint64) : 0u;
4541 					/* Avoid waiting infinite time for the queries, when one of them is not going to be issued in
4542 					 * the partial case.
4543 					 */
4544 					if ((deBool)(partialFlags[partialFlagsIdx] & VK_QUERY_RESULT_PARTIAL_BIT) &&
4545 						(deBool)(waitFlags[waitFlagsIdx] & VK_QUERY_RESULT_WAIT_BIT))
4546 						continue;
4547 
4548 					VkQueryResultFlags	queryFlags	= VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT | partialFlags[partialFlagsIdx] | waitFlags[waitFlagsIdx];
4549 					deUint32			queryCount	= partialFlagsIdx ? 2u : 1u;
4550 					{
4551 						std::ostringstream testName;
4552 						testName	<< "input_assembly_vertex_fragment"
4553 									<< partialFlagsStr[partialFlagsIdx]
4554 									<< waitFlagsStr[waitFlagsIdx]
4555 									<< copyTypesStr[copyTypesIdx];
4556 						GraphicBasicMultipleQueryTestInstance::ParametersGraphic param(statisticsFlags | VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, queryFlags, queryCount, DE_FALSE, copyTypes[copyTypesIdx], dstOffset);
4557 						vertexShaderMultipleQueries->addChild(new QueryPoolGraphicMultipleQueryStatisticsTest<VertexShaderMultipleQueryTestInstance>(m_testCtx, testName.str().c_str(), "", param));
4558 					}
4559 
4560 					{
4561 						// No fragment shader case
4562 						std::ostringstream testName;
4563 						testName	<< "input_assembly_vertex"
4564 									<< partialFlagsStr[partialFlagsIdx]
4565 									<< waitFlagsStr[waitFlagsIdx]
4566 									<< copyTypesStr[copyTypesIdx];
4567 						GraphicBasicMultipleQueryTestInstance::ParametersGraphic param(statisticsFlags | VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, queryFlags, queryCount, DE_TRUE, copyTypes[copyTypesIdx], dstOffset);
4568 						vertexShaderMultipleQueries->addChild(new QueryPoolGraphicMultipleQueryStatisticsTest<VertexShaderMultipleQueryTestInstance>(m_testCtx, testName.str().c_str(), "", param));
4569 					}
4570 				}
4571 			}
4572 		}
4573 	}
4574 
4575 	addChild(computeShaderInvocationsGroup.release());
4576 	addChild(inputAssemblyVertices.release());
4577 	addChild(inputAssemblyPrimitives.release());
4578 	addChild(vertexShaderInvocations.release());
4579 	addChild(fragmentShaderInvocations.release());
4580 	addChild(geometryShaderInvocations.release());
4581 	addChild(geometryShaderPrimitives.release());
4582 	addChild(clippingInvocations.release());
4583 	addChild(clippingPrimitives.release());
4584 	addChild(tesControlPatches.release());
4585 	addChild(tesEvaluationShaderInvocations.release());
4586 
4587 	vertexOnlyGroup->addChild(inputAssemblyVerticesVertexOnly.release());
4588 	vertexOnlyGroup->addChild(inputAssemblyPrimitivesVertexOnly.release());
4589 	vertexOnlyGroup->addChild(vertexShaderInvocationsVertexOnly.release());
4590 	addChild(vertexOnlyGroup.release());
4591 
4592 	hostQueryResetGroup->addChild(computeShaderInvocationsGroupHostQueryReset.release());
4593 	hostQueryResetGroup->addChild(inputAssemblyVerticesHostQueryReset.release());
4594 	hostQueryResetGroup->addChild(inputAssemblyPrimitivesHostQueryReset.release());
4595 	hostQueryResetGroup->addChild(vertexShaderInvocationsHostQueryReset.release());
4596 	hostQueryResetGroup->addChild(fragmentShaderInvocationsHostQueryReset.release());
4597 	hostQueryResetGroup->addChild(geometryShaderInvocationsHostQueryReset.release());
4598 	hostQueryResetGroup->addChild(geometryShaderPrimitivesHostQueryReset.release());
4599 	hostQueryResetGroup->addChild(clippingInvocationsHostQueryReset.release());
4600 	hostQueryResetGroup->addChild(clippingPrimitivesHostQueryReset.release());
4601 	hostQueryResetGroup->addChild(tesControlPatchesHostQueryReset.release());
4602 	hostQueryResetGroup->addChild(tesEvaluationShaderInvocationsHostQueryReset.release());
4603 	addChild(hostQueryResetGroup.release());
4604 
4605 	resetBeforeCopyGroup->addChild(computeShaderInvocationsGroupResetBeforeCopy.release());
4606 	resetBeforeCopyGroup->addChild(inputAssemblyVerticesResetBeforeCopy.release());
4607 	resetBeforeCopyGroup->addChild(inputAssemblyPrimitivesResetBeforeCopy.release());
4608 	resetBeforeCopyGroup->addChild(vertexShaderInvocationsResetBeforeCopy.release());
4609 	resetBeforeCopyGroup->addChild(fragmentShaderInvocationsResetBeforeCopy.release());
4610 	resetBeforeCopyGroup->addChild(geometryShaderInvocationsResetBeforeCopy.release());
4611 	resetBeforeCopyGroup->addChild(geometryShaderPrimitivesResetBeforeCopy.release());
4612 	resetBeforeCopyGroup->addChild(clippingInvocationsResetBeforeCopy.release());
4613 	resetBeforeCopyGroup->addChild(clippingPrimitivesResetBeforeCopy.release());
4614 	resetBeforeCopyGroup->addChild(tesControlPatchesResetBeforeCopy.release());
4615 	resetBeforeCopyGroup->addChild(tesEvaluationShaderInvocationsResetBeforeCopy.release());
4616 	addChild(resetBeforeCopyGroup.release());
4617 	addChild(vertexShaderMultipleQueries.release());
4618 }
4619 
4620 } //QueryPool
4621 } //vkt
4622