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