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 "vktCustomInstancesDevices.hpp"
31 #include "vkBuilderUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkObjUtil.hpp"
37 #ifdef CTS_USES_VULKANSC
38 #include "vkSafetyCriticalUtil.hpp"
39 #endif // CTS_USES_VULKANSC
40 #include "vkBarrierUtil.hpp"
41 #include "vkDeviceUtil.hpp"
42 
43 #include "deMath.h"
44 
45 #include "tcuTestLog.hpp"
46 #include "tcuResource.hpp"
47 #include "tcuImageCompare.hpp"
48 #include "vkImageUtil.hpp"
49 #include "tcuCommandLine.hpp"
50 #include "tcuRGBA.hpp"
51 #include "tcuStringTemplate.hpp"
52 #include "tcuMaybe.hpp"
53 #include "tcuTextureUtil.hpp"
54 
55 #include <vector>
56 #include <utility>
57 #include <algorithm>
58 
59 using std::pair;
60 using std::vector;
61 
62 namespace vkt
63 {
64 namespace QueryPool
65 {
66 namespace
67 {
68 
69 using namespace vk;
70 using namespace Draw;
71 
72 //Test parameters
73 enum
74 {
75     WIDTH  = 64,
76     HEIGHT = 64
77 };
78 
79 enum ResetType
80 {
81     RESET_TYPE_NORMAL = 0,
82     RESET_TYPE_HOST,
83     RESET_TYPE_BEFORE_COPY,
84     RESET_TYPE_AFTER_COPY,
85     RESET_TYPE_LAST
86 };
87 
88 enum CopyType
89 {
90     COPY_TYPE_GET = 0,
91     COPY_TYPE_CMD,
92 };
93 
94 enum StrideType
95 {
96     STRIDE_TYPE_VALID = 0,
97     STRIDE_TYPE_ZERO,
98 };
99 
100 enum ClearOperation
101 {
102     CLEAR_NOOP,
103     CLEAR_COLOR,
104     CLEAR_DEPTH
105 };
106 
107 constexpr uint32_t kTriangleVertices = 3u;
108 
inputTypeToGLString(const VkPrimitiveTopology & inputType)109 std::string inputTypeToGLString(const VkPrimitiveTopology &inputType)
110 {
111     switch (inputType)
112     {
113     case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
114         return "points";
115     case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
116     case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
117         return "lines";
118     case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
119     case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
120         return "lines_adjacency";
121     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
122     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
123     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
124         return "triangles";
125     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
126     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
127         return "triangles_adjacency";
128     default:
129         DE_ASSERT(false);
130         return "error";
131     }
132 }
133 
outputTypeToGLString(const VkPrimitiveTopology & outputType)134 std::string outputTypeToGLString(const VkPrimitiveTopology &outputType)
135 {
136     switch (outputType)
137     {
138     case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
139         return "points";
140     case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
141     case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
142     case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
143     case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
144         return "line_strip";
145     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
146     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
147     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
148     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
149     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
150         return "triangle_strip";
151     default:
152         DE_ASSERT(false);
153         return "error";
154     }
155 }
156 
findNonGraphicsQueueFamilyIndex(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)157 uint32_t findNonGraphicsQueueFamilyIndex(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
158 {
159     const VkQueueFlags mandatoryFlags = VK_QUEUE_COMPUTE_BIT;
160     const VkQueueFlags forbiddenFlags = VK_QUEUE_GRAPHICS_BIT;
161 
162     uint32_t qfIndex = findQueueFamilyIndexWithCaps(vki, physicalDevice, mandatoryFlags, forbiddenFlags);
163     return qfIndex;
164 }
165 
checkSupportForNonGraphicsQueueFamily(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)166 void checkSupportForNonGraphicsQueueFamily(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
167 {
168     findNonGraphicsQueueFamilyIndex(vki, physicalDevice);
169 }
170 
171 // Device helper: this is needed in some tests when we create custom devices.
172 class DeviceHelper
173 {
174 public:
~DeviceHelper()175     virtual ~DeviceHelper()
176     {
177     }
178     virtual const DeviceInterface &getDeviceInterface(void) const           = 0;
179     virtual VkDevice getDevice(void) const                                  = 0;
180     virtual uint32_t getQueueFamilyIndex(void) const                        = 0;
181     virtual VkQueue getQueue(void) const                                    = 0;
182     virtual Allocator &getAllocator(void) const                             = 0;
183     virtual const std::vector<std::string> &getDeviceExtensions(void) const = 0;
184 };
185 
186 // This one just reuses the default device from the context.
187 class ContextDeviceHelper : public DeviceHelper
188 {
189 public:
ContextDeviceHelper(Context & context)190     ContextDeviceHelper(Context &context)
191         : m_deviceInterface(context.getDeviceInterface())
192         , m_device(context.getDevice())
193         , m_queueFamilyIndex(context.getUniversalQueueFamilyIndex())
194         , m_queue(context.getUniversalQueue())
195         , m_allocator(context.getDefaultAllocator())
196         , m_extensions(context.getDeviceExtensions())
197     {
198     }
199 
~ContextDeviceHelper()200     virtual ~ContextDeviceHelper()
201     {
202     }
203 
getDeviceInterface(void) const204     const DeviceInterface &getDeviceInterface(void) const override
205     {
206         return m_deviceInterface;
207     }
getDevice(void) const208     VkDevice getDevice(void) const override
209     {
210         return m_device;
211     }
getQueueFamilyIndex(void) const212     uint32_t getQueueFamilyIndex(void) const override
213     {
214         return m_queueFamilyIndex;
215     }
getQueue(void) const216     VkQueue getQueue(void) const override
217     {
218         return m_queue;
219     }
getAllocator(void) const220     Allocator &getAllocator(void) const override
221     {
222         return m_allocator;
223     }
getDeviceExtensions(void) const224     const std::vector<std::string> &getDeviceExtensions(void) const override
225     {
226         return m_extensions;
227     }
228 
229 protected:
230     const DeviceInterface &m_deviceInterface;
231     const VkDevice m_device;
232     const uint32_t m_queueFamilyIndex;
233     const VkQueue m_queue;
234     Allocator &m_allocator;
235     std::vector<std::string> m_extensions;
236 };
237 
238 // This one creates a new device with a single compute-only queue.
239 class ComputeQueueDeviceHelper : public DeviceHelper
240 {
241 public:
ComputeQueueDeviceHelper(Context & context)242     ComputeQueueDeviceHelper(Context &context)
243     {
244 #ifdef CTS_USES_VULKANSC
245         m_customInstance          = createCustomInstanceFromContext(context);
246         VkInstance instance       = m_customInstance;
247         const auto &vki           = m_customInstance.getDriver();
248         const auto physicalDevice = chooseDevice(vki, instance, context.getTestContext().getCommandLine());
249 #else
250         VkInstance instance       = context.getInstance();
251         const auto &vki           = context.getInstanceInterface();
252         const auto physicalDevice = context.getPhysicalDevice();
253 #endif
254         const auto &vkp          = context.getPlatformInterface();
255         const auto queuePriority = 1.0f;
256 
257         // Queue index. Support for this type of queue needs to be checked first.
258         m_queueFamilyIndex = findNonGraphicsQueueFamilyIndex(vki, physicalDevice);
259 
260         // Create a universal queue that supports graphics and compute.
261         const VkDeviceQueueCreateInfo queueParams = {
262             VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
263             DE_NULL,                                    // const void* pNext;
264             0u,                                         // VkDeviceQueueCreateFlags flags;
265             m_queueFamilyIndex,                         // uint32_t queueFamilyIndex;
266             1u,                                         // uint32_t queueCount;
267             &queuePriority                              // const float* pQueuePriorities;
268         };
269 
270         // Enable all available base features except for robust buffer access.
271         // Enable host query reset if available.
272         // Enable portability features if available.
273         // Enable the same extensions as the context device.
274         const bool hostQueryResetSupport = (context.isDeviceFunctionalitySupported("VK_EXT_host_query_reset"));
275         const bool portabilitySupport    = (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"));
276 #ifdef CTS_USES_VULKANSC
277         const bool inVulkanSC = true;
278 #else
279         const bool inVulkanSC     = false;
280 #endif // CTS_USES_VULKANSC
281         const bool useFeatures2 = (hostQueryResetSupport || portabilitySupport || inVulkanSC);
282         VkPhysicalDeviceFeatures baseFeatures;
283         VkPhysicalDeviceFeatures2 features2                           = initVulkanStructure();
284         VkPhysicalDeviceHostQueryResetFeatures hostQueryResetFeatures = initVulkanStructure();
285 #ifndef CTS_USES_VULKANSC
286         VkPhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures = initVulkanStructure();
287 #endif // CTS_USES_VULKANSC
288         const auto addFeatures = makeStructChainAdder(&features2);
289 
290         if (useFeatures2)
291         {
292             if (hostQueryResetSupport)
293                 addFeatures(&hostQueryResetFeatures);
294 
295 #ifndef CTS_USES_VULKANSC
296             if (portabilitySupport)
297                 addFeatures(&portabilityFeatures);
298 #endif // CTS_USES_VULKANSC
299 
300             vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
301             features2.features.robustBufferAccess = VK_FALSE;
302         }
303         else
304         {
305             vki.getPhysicalDeviceFeatures(physicalDevice, &baseFeatures);
306             baseFeatures.robustBufferAccess = VK_FALSE;
307         }
308 
309         const auto creationExtensions = context.getDeviceCreationExtensions();
310 
311 #ifdef CTS_USES_VULKANSC
312         const auto &cmdLine                                    = context.getTestContext().getCommandLine();
313         VkDeviceObjectReservationCreateInfo memReservationInfo = cmdLine.isSubProcess() ?
314                                                                      context.getResourceInterface()->getStatMax() :
315                                                                      resetDeviceObjectReservationCreateInfo();
316 
317         addFeatures(&memReservationInfo);
318 
319         VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
320         addFeatures(&sc10Features);
321 
322         VkPipelineCacheCreateInfo pcCI;
323         std::vector<VkPipelinePoolSize> poolSizes;
324 
325         if (cmdLine.isSubProcess())
326         {
327             if (context.getResourceInterface()->getCacheDataSize() > 0)
328             {
329                 pcCI = {
330                     VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
331                     DE_NULL,                                      // const void* pNext;
332                     VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
333                         VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
334                     context.getResourceInterface()->getCacheDataSize(),       // uintptr_t initialDataSize;
335                     context.getResourceInterface()->getCacheData()            // const void* pInitialData;
336                 };
337                 memReservationInfo.pipelineCacheCreateInfoCount = 1;
338                 memReservationInfo.pPipelineCacheCreateInfos    = &pcCI;
339             }
340 
341             poolSizes = context.getResourceInterface()->getPipelinePoolSizes();
342             if (!poolSizes.empty())
343             {
344                 memReservationInfo.pipelinePoolSizeCount = de::sizeU32(poolSizes);
345                 memReservationInfo.pPipelinePoolSizes    = de::dataOrNull(poolSizes);
346             }
347         }
348 #endif // CTS_USES_VULKANSC
349 
350         const VkDeviceCreateInfo deviceCreateInfo = {
351             VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,     //sType;
352             (useFeatures2 ? &features2 : nullptr),    //pNext;
353             0u,                                       //flags
354             1u,                                       //queueRecordCount;
355             &queueParams,                             //pRequestedQueues;
356             0u,                                       //layerCount;
357             nullptr,                                  //ppEnabledLayerNames;
358             de::sizeU32(creationExtensions),          // uint32_t enabledExtensionCount;
359             de::dataOrNull(creationExtensions),       // const char* const* ppEnabledExtensionNames;
360             (useFeatures2 ? nullptr : &baseFeatures), //pEnabledFeatures;
361         };
362 
363         m_device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance,
364                                       vki, physicalDevice, &deviceCreateInfo);
365         m_vkd.reset(new DeviceDriver(vkp, instance, m_device.get(), context.getUsedApiVersion(),
366                                      context.getTestContext().getCommandLine()));
367         m_queue = getDeviceQueue(*m_vkd, *m_device, m_queueFamilyIndex, 0u);
368         m_allocator.reset(
369             new SimpleAllocator(*m_vkd, m_device.get(), getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
370     }
371 
~ComputeQueueDeviceHelper()372     virtual ~ComputeQueueDeviceHelper()
373     {
374     }
375 
getDeviceInterface(void) const376     const DeviceInterface &getDeviceInterface(void) const override
377     {
378         return *m_vkd;
379     }
getDevice(void) const380     VkDevice getDevice(void) const override
381     {
382         return m_device.get();
383     }
getQueueFamilyIndex(void) const384     uint32_t getQueueFamilyIndex(void) const override
385     {
386         return m_queueFamilyIndex;
387     }
getQueue(void) const388     VkQueue getQueue(void) const override
389     {
390         return m_queue;
391     }
getAllocator(void) const392     Allocator &getAllocator(void) const override
393     {
394         return *m_allocator;
395     }
getDeviceExtensions(void) const396     const std::vector<std::string> &getDeviceExtensions(void) const override
397     {
398         return m_extensions;
399     }
400 
401 protected:
402 #ifdef CTS_USES_VULKANSC
403     CustomInstance m_customInstance;
404 #endif
405     Move<VkDevice> m_device;
406     std::unique_ptr<DeviceDriver> m_vkd;
407     uint32_t m_queueFamilyIndex;
408     VkQueue m_queue;
409     std::unique_ptr<SimpleAllocator> m_allocator;
410     std::vector<std::string> m_extensions;
411 };
412 
413 std::unique_ptr<DeviceHelper> g_computeQueueDeviceHelper;
414 std::unique_ptr<DeviceHelper> g_contextDeviceHelper;
415 
getDeviceHelper(Context & context,bool computeQueue)416 DeviceHelper &getDeviceHelper(Context &context, bool computeQueue)
417 {
418     if (computeQueue)
419     {
420         if (!g_computeQueueDeviceHelper)
421             g_computeQueueDeviceHelper.reset(new ComputeQueueDeviceHelper(context));
422         return *g_computeQueueDeviceHelper;
423     }
424 
425     if (!g_contextDeviceHelper)
426         g_contextDeviceHelper.reset(new ContextDeviceHelper(context));
427     return *g_contextDeviceHelper;
428 }
429 
destroyDeviceHelpers()430 void destroyDeviceHelpers()
431 {
432     // Destroy singleton objects
433     g_computeQueueDeviceHelper.reset(nullptr);
434     g_contextDeviceHelper.reset(nullptr);
435 }
436 
437 using Pair32                        = pair<uint32_t, uint32_t>;
438 using Pair64                        = pair<uint64_t, uint64_t>;
439 using ResultsVector                 = vector<uint64_t>;
440 using ResultsVectorWithAvailability = vector<Pair64>;
441 
442 // Get query pool results as a vector. Note results are always converted to
443 // uint64_t, but the actual vkGetQueryPoolResults call will use the 64-bits flag
444 // or not depending on your preferences.
GetQueryPoolResultsVector(ResultsVector & output,const DeviceInterface & vk,vk::VkDevice device,vk::VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkQueryResultFlags flags)445 vk::VkResult GetQueryPoolResultsVector(ResultsVector &output, const DeviceInterface &vk, vk::VkDevice device,
446                                        vk::VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
447                                        VkQueryResultFlags flags)
448 {
449     if (flags & vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
450         TCU_THROW(InternalError, "Availability flag passed when expecting results as ResultsVector");
451 
452     vk::VkResult result;
453     output.resize(queryCount);
454 
455     if (flags & vk::VK_QUERY_RESULT_64_BIT)
456     {
457         constexpr size_t stride = sizeof(ResultsVector::value_type);
458         const size_t totalSize  = stride * output.size();
459         result =
460             vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, output.data(), stride, flags);
461     }
462     else
463     {
464         using IntermediateVector = vector<uint32_t>;
465 
466         IntermediateVector intermediate(queryCount);
467 
468         // Try to preserve existing data if possible.
469         std::transform(begin(output), end(output), begin(intermediate),
470                        [](uint64_t v) { return static_cast<uint32_t>(v); });
471 
472         constexpr size_t stride = sizeof(decltype(intermediate)::value_type);
473         const size_t totalSize  = stride * intermediate.size();
474 
475         // Get and copy results.
476         result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, intermediate.data(),
477                                         stride, flags);
478         std::copy(begin(intermediate), end(intermediate), begin(output));
479     }
480 
481     return result;
482 }
483 
484 // Same as the normal GetQueryPoolResultsVector but returning the availability
485 // bit associated to each query in addition to the query value.
GetQueryPoolResultsVector(ResultsVectorWithAvailability & output,const DeviceInterface & vk,vk::VkDevice device,vk::VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkQueryResultFlags flags)486 vk::VkResult GetQueryPoolResultsVector(ResultsVectorWithAvailability &output, const DeviceInterface &vk,
487                                        vk::VkDevice device, vk::VkQueryPool queryPool, uint32_t firstQuery,
488                                        uint32_t queryCount, VkQueryResultFlags flags)
489 {
490     flags |= vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
491 
492     vk::VkResult result;
493     output.resize(queryCount);
494 
495     if (flags & vk::VK_QUERY_RESULT_64_BIT)
496     {
497         constexpr size_t stride = sizeof(ResultsVectorWithAvailability::value_type);
498         const size_t totalSize  = stride * output.size();
499         result =
500             vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, output.data(), stride, flags);
501     }
502     else
503     {
504         using IntermediateVector = vector<Pair32>;
505 
506         IntermediateVector intermediate(queryCount);
507 
508         // Try to preserve existing output data if possible.
509         std::transform(begin(output), end(output), begin(intermediate),
510                        [](const Pair64 &p) {
511                            return Pair32{static_cast<uint32_t>(p.first), static_cast<uint32_t>(p.second)};
512                        });
513 
514         constexpr size_t stride = sizeof(decltype(intermediate)::value_type);
515         const size_t totalSize  = stride * intermediate.size();
516 
517         // Get and copy.
518         result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, intermediate.data(),
519                                         stride, flags);
520         std::transform(begin(intermediate), end(intermediate), begin(output),
521                        [](const Pair32 &p) {
522                            return Pair64{p.first, p.second};
523                        });
524     }
525 
526     return result;
527 }
528 
529 // Get query pool results as a vector. Note results are always converted to
530 // uint64_t, but the actual vkCmdCopyQueryPoolResults call will use the 64-bits flag
531 // or not depending on your preferences.
cmdCopyQueryPoolResultsVector(ResultsVector & output,const DeviceInterface & vk,vk::VkDevice device,const vk::Allocation & allocation,uint32_t queryCount,VkQueryResultFlags flags,bool dstOffset)532 void cmdCopyQueryPoolResultsVector(ResultsVector &output, const DeviceInterface &vk, vk::VkDevice device,
533                                    const vk::Allocation &allocation, uint32_t queryCount, VkQueryResultFlags flags,
534                                    bool dstOffset)
535 {
536     if (flags & vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
537         TCU_THROW(InternalError, "Availability flag passed when expecting results as ResultsVector");
538 
539     output.resize(queryCount);
540 
541     void *allocationData = allocation.getHostPtr();
542     vk::invalidateAlloc(vk, device, allocation);
543 
544     if (flags & vk::VK_QUERY_RESULT_64_BIT)
545     {
546         constexpr size_t stride = sizeof(ResultsVector::value_type);
547         const size_t totalSize  = stride * output.size();
548         const uint32_t offset   = dstOffset ? 1u : 0u;
549         deMemcpy(output.data(), (reinterpret_cast<ResultsVector::value_type *>(allocationData) + offset), totalSize);
550     }
551     else
552     {
553         using IntermediateVector = vector<uint32_t>;
554 
555         IntermediateVector intermediate(queryCount);
556 
557         // Try to preserve existing data if possible.
558         std::transform(begin(output), end(output), begin(intermediate),
559                        [](uint64_t v) { return static_cast<uint32_t>(v); });
560 
561         constexpr size_t stride = sizeof(decltype(intermediate)::value_type);
562         const size_t totalSize  = stride * intermediate.size();
563         const uint32_t offset   = dstOffset ? 1u : 0u;
564         // Get and copy results.
565         deMemcpy(intermediate.data(), (reinterpret_cast<decltype(intermediate)::value_type *>(allocationData) + offset),
566                  totalSize);
567         std::copy(begin(intermediate), end(intermediate), begin(output));
568     }
569 }
570 
571 // Same as the normal cmdCopyQueryPoolResultsVector but returning the availability
572 // bit associated to each query in addition to the query value.
cmdCopyQueryPoolResultsVector(ResultsVectorWithAvailability & output,const DeviceInterface & vk,vk::VkDevice device,const vk::Allocation & allocation,uint32_t queryCount,VkQueryResultFlags flags,bool dstOffset)573 void cmdCopyQueryPoolResultsVector(ResultsVectorWithAvailability &output, const DeviceInterface &vk,
574                                    vk::VkDevice device, const vk::Allocation &allocation, uint32_t queryCount,
575                                    VkQueryResultFlags flags, bool dstOffset)
576 {
577     flags |= vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
578 
579     output.resize(queryCount);
580 
581     void *allocationData = allocation.getHostPtr();
582     vk::invalidateAlloc(vk, device, allocation);
583 
584     if (flags & vk::VK_QUERY_RESULT_64_BIT)
585     {
586         constexpr size_t stride = sizeof(ResultsVectorWithAvailability::value_type);
587         const size_t totalSize  = stride * output.size();
588         const uint32_t offset   = dstOffset ? 1u : 0u;
589         deMemcpy(output.data(),
590                  (reinterpret_cast<ResultsVectorWithAvailability::value_type *>(allocationData) + offset), totalSize);
591     }
592     else
593     {
594         using IntermediateVector = vector<Pair32>;
595 
596         IntermediateVector intermediate(queryCount);
597 
598         // Try to preserve existing output data if possible.
599         std::transform(begin(output), end(output), begin(intermediate),
600                        [](const Pair64 &p) {
601                            return Pair32{static_cast<uint32_t>(p.first), static_cast<uint32_t>(p.second)};
602                        });
603 
604         constexpr size_t stride = sizeof(decltype(intermediate)::value_type);
605         const size_t totalSize  = stride * intermediate.size();
606         const uint32_t offset   = dstOffset ? 1u : 0u;
607 
608         // Get and copy.
609         deMemcpy(intermediate.data(), (reinterpret_cast<decltype(intermediate)::value_type *>(allocationData) + offset),
610                  totalSize);
611         std::transform(begin(intermediate), end(intermediate), begin(output),
612                        [](const Pair32 &p) {
613                            return Pair64{p.first, p.second};
614                        });
615     }
616 }
617 
618 // Generic parameters structure.
619 struct GenericParameters
620 {
621     ResetType resetType;
622     CopyType copyType;
623     bool query64Bits;
624     bool dstOffset;
625     StrideType strideType;
626 
GenericParametersvkt::QueryPool::__anon6b4348560111::GenericParameters627     GenericParameters(ResetType resetType_, CopyType copyType_, bool query64Bits_, bool dstOffset_,
628                       StrideType strideType_)
629         : resetType{resetType_}
630         , copyType{copyType_}
631         , query64Bits{query64Bits_}
632         , dstOffset{dstOffset_}
633         , strideType{strideType_}
634     {
635     }
636 
querySizeFlagsvkt::QueryPool::__anon6b4348560111::GenericParameters637     VkQueryResultFlags querySizeFlags() const
638     {
639         return (query64Bits ? static_cast<VkQueryResultFlags>(vk::VK_QUERY_RESULT_64_BIT) : 0u);
640     }
641 };
642 
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)643 void beginSecondaryCommandBuffer(
644     const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkQueryPipelineStatisticFlags queryFlags,
645     const VkRenderPass renderPass = (VkRenderPass)0u, const VkFramebuffer framebuffer = (VkFramebuffer)0u,
646     const VkCommandBufferUsageFlags bufferUsageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)
647 {
648     const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = {
649         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
650         DE_NULL,
651         renderPass,              // renderPass
652         0u,                      // subpass
653         framebuffer,             // framebuffer
654         VK_FALSE,                // occlusionQueryEnable
655         (VkQueryControlFlags)0u, // queryFlags
656         queryFlags,              // pipelineStatistics
657     };
658 
659     const VkCommandBufferBeginInfo info = {
660         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
661         DE_NULL,                                     // const void* pNext;
662         bufferUsageFlags,                            // VkCommandBufferUsageFlags flags;
663         &secCmdBufInheritInfo,                       // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
664     };
665     VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
666 }
667 
makeQueryPool(const DeviceInterface & vk,const VkDevice device,uint32_t queryCount,VkQueryPipelineStatisticFlags statisticFlags)668 Move<VkQueryPool> makeQueryPool(const DeviceInterface &vk, const VkDevice device, uint32_t queryCount,
669                                 VkQueryPipelineStatisticFlags statisticFlags)
670 {
671     const VkQueryPoolCreateInfo queryPoolCreateInfo = {
672         VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType                    sType
673         DE_NULL,                                  // const void*                        pNext
674         (VkQueryPoolCreateFlags)0,                // VkQueryPoolCreateFlags            flags
675         VK_QUERY_TYPE_PIPELINE_STATISTICS,        // VkQueryType                        queryType
676         queryCount,                               // uint32_t                            entryCount
677         statisticFlags,                           // VkQueryPipelineStatisticFlags    pipelineStatistics
678     };
679     return createQueryPool(vk, device, &queryPoolCreateInfo);
680 }
681 
calculatePearsonCorrelation(const std::vector<uint64_t> & x,const ResultsVector & y)682 double calculatePearsonCorrelation(const std::vector<uint64_t> &x, const ResultsVector &y)
683 {
684     // This function calculates Pearson correlation coefficient ( https://en.wikipedia.org/wiki/Pearson_correlation_coefficient )
685     // Two statistical variables are linear ( == fully corellated ) when fabs( Pearson corelation coefficient ) == 1
686     // Two statistical variables are independent when pearson corelation coefficient == 0
687     // If fabs( Pearson coefficient ) is > 0.8 then these two variables are almost linear
688 
689     DE_ASSERT(x.size() == y.size());
690     DE_ASSERT(x.size() > 1);
691 
692     // calculate mean values
693     double xMean = 0.0, yMean = 0.0;
694     for (uint32_t i = 0; i < x.size(); ++i)
695     {
696         xMean += static_cast<double>(x[i]);
697         yMean += static_cast<double>(y[i]);
698     }
699     xMean /= static_cast<double>(x.size());
700     yMean /= static_cast<double>(x.size());
701 
702     // calculate standard deviations
703     double xS = 0.0, yS = 0.0;
704     for (uint32_t i = 0; i < x.size(); ++i)
705     {
706         double xv = static_cast<double>(x[i]) - xMean;
707         double yv = static_cast<double>(y[i]) - yMean;
708 
709         xS += xv * xv;
710         yS += yv * yv;
711     }
712     xS = sqrt(xS / static_cast<double>(x.size() - 1));
713     yS = sqrt(yS / static_cast<double>(x.size() - 1));
714 
715     // calculate Pearson coefficient
716     double pearson = 0.0;
717     for (uint32_t i = 0; i < x.size(); ++i)
718     {
719         double xv = (static_cast<double>(x[i]) - xMean) / xS;
720         double yv = (static_cast<double>(y[i]) - yMean) / yS;
721         pearson += xv * yv;
722     }
723 
724     return pearson / static_cast<double>(x.size() - 1);
725 }
726 
calculatePearsonCorrelation(const std::vector<uint64_t> & x,const ResultsVectorWithAvailability & ya)727 double calculatePearsonCorrelation(const std::vector<uint64_t> &x, const ResultsVectorWithAvailability &ya)
728 {
729     ResultsVector y;
730     for (const auto &elt : ya)
731         y.push_back(elt.first);
732     return calculatePearsonCorrelation(x, y);
733 }
734 
735 using BufferPtr = de::SharedPtr<Buffer>;
736 
clearBuffer(const DeviceInterface & vk,const VkDevice device,const BufferPtr buffer,const VkDeviceSize bufferSizeBytes)737 void clearBuffer(const DeviceInterface &vk, const VkDevice device, const BufferPtr buffer,
738                  const VkDeviceSize bufferSizeBytes)
739 {
740     const std::vector<uint8_t> data((size_t)bufferSizeBytes, 0u);
741     const Allocation &allocation = buffer->getBoundMemory();
742     void *allocationData         = allocation.getHostPtr();
743     invalidateAlloc(vk, device, allocation);
744     deMemcpy(allocationData, &data[0], (size_t)bufferSizeBytes);
745     flushAlloc(vk, device, allocation);
746 }
747 
748 class StatisticQueryTestInstance : public TestInstance
749 {
750 public:
751     StatisticQueryTestInstance(Context &context, uint32_t queryCount, bool dstOffset, bool useComputeQueue);
752 
753 protected:
754     struct ValueAndAvailability
755     {
756         uint64_t value;
757         uint64_t availability;
758     };
759 
760     VkDeviceSize m_resetBufferSize;
761     BufferPtr m_resetBuffer;
762     bool dstOffset;
763     const bool m_useComputeQueue;
764 
765     virtual void checkExtensions(bool hostResetQueryEnabled);
766     BufferPtr createResetBuffer(void) const;
767     void fillResetBuffer(const BufferPtr &buffer) const;
768     tcu::TestStatus verifyUnavailable();
769 };
770 
createResetBuffer(void) const771 BufferPtr StatisticQueryTestInstance::createResetBuffer(void) const
772 {
773     const auto &deviceHelper = getDeviceHelper(m_context, m_useComputeQueue);
774 
775     return Buffer::createAndAlloc(deviceHelper.getDeviceInterface(), deviceHelper.getDevice(),
776                                   BufferCreateInfo(m_resetBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
777                                   deviceHelper.getAllocator(), vk::MemoryRequirement::HostVisible);
778 }
779 
fillResetBuffer(const BufferPtr & buffer) const780 void StatisticQueryTestInstance::fillResetBuffer(const BufferPtr &buffer) const
781 {
782     const auto &deviceHelper = getDeviceHelper(m_context, m_useComputeQueue);
783 
784     const vk::Allocation &allocation = buffer->getBoundMemory();
785     void *allocationData             = allocation.getHostPtr();
786     deMemset(allocationData, 0xff, static_cast<size_t>(m_resetBufferSize));
787     flushAlloc(deviceHelper.getDeviceInterface(), deviceHelper.getDevice(), allocation);
788 }
789 
StatisticQueryTestInstance(Context & context,uint32_t queryCount,bool dstOffset_,bool useComputeQueue)790 StatisticQueryTestInstance::StatisticQueryTestInstance(Context &context, uint32_t queryCount, bool dstOffset_,
791                                                        bool useComputeQueue)
792     : TestInstance(context)
793     , m_resetBufferSize((queryCount + (dstOffset_ ? 1u : 0u)) * sizeof(ValueAndAvailability))
794     , m_resetBuffer()
795     , dstOffset(dstOffset_)
796     , m_useComputeQueue(useComputeQueue)
797 {
798     m_resetBuffer = createResetBuffer();
799     fillResetBuffer(m_resetBuffer);
800 }
801 
checkExtensions(bool hostResetQueryEnabled)802 void StatisticQueryTestInstance::checkExtensions(bool hostResetQueryEnabled)
803 {
804     if (!m_context.getDeviceFeatures().pipelineStatisticsQuery)
805         throw tcu::NotSupportedError("Pipeline statistics queries are not supported");
806 
807     if (hostResetQueryEnabled == true)
808     {
809         // Check VK_EXT_host_query_reset is supported
810         m_context.requireDeviceFunctionality("VK_EXT_host_query_reset");
811         if (m_context.getHostQueryResetFeatures().hostQueryReset == VK_FALSE)
812             throw tcu::NotSupportedError(
813                 std::string("Implementation doesn't support resetting queries from the host").c_str());
814     }
815 }
816 
verifyUnavailable()817 tcu::TestStatus StatisticQueryTestInstance::verifyUnavailable()
818 {
819     const auto &deviceHelper         = getDeviceHelper(m_context, m_useComputeQueue);
820     const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
821     const void *allocationData       = allocation.getHostPtr();
822     uint32_t size                    = dstOffset ? 2 : 1;
823     std::vector<ValueAndAvailability> va;
824     va.resize(size);
825 
826     vk::invalidateAlloc(deviceHelper.getDeviceInterface(), deviceHelper.getDevice(), allocation);
827     deMemcpy(va.data(), allocationData, size * sizeof(ValueAndAvailability));
828 
829     bool failed = false;
830     for (uint32_t idx = 0u; idx < size; idx++)
831     {
832         if (dstOffset && idx == 0)
833         {
834             // Check that the contents between 0 and dstOffset were not overwritten.
835             failed |= va[idx].availability != 0xfffffffffffffffful || va[idx].value != 0xfffffffffffffffful;
836             continue;
837         }
838 
839         failed |= va[idx].availability != 0;
840     }
841 
842     return failed ? tcu::TestStatus::fail("Availability bit nonzero after resetting query or dstOffset wrong values") :
843                     tcu::TestStatus::pass("Pass");
844 }
845 
846 class ComputeInvocationsTestInstance : public StatisticQueryTestInstance
847 {
848 public:
849     struct ParametersCompute : public GenericParameters
850     {
ParametersComputevkt::QueryPool::__anon6b4348560111::ComputeInvocationsTestInstance::ParametersCompute851         ParametersCompute(const tcu::UVec3 &localSize_, const tcu::UVec3 &groupSize_, const std::string &shaderName_,
852                           ResetType resetType_, CopyType copyType_, bool query64Bits_, bool dstOffset_,
853                           StrideType strideType_, bool useComputeQueue_)
854             : GenericParameters{resetType_, copyType_, query64Bits_, dstOffset_, strideType_}
855             , localSize(localSize_)
856             , groupSize(groupSize_)
857             , shaderName(shaderName_)
858             , useComputeQueue(useComputeQueue_)
859         {
860         }
861 
862         tcu::UVec3 localSize;
863         tcu::UVec3 groupSize;
864         std::string shaderName;
865         const bool useComputeQueue;
866     };
867     ComputeInvocationsTestInstance(Context &context, const std::vector<ParametersCompute> &parameters);
868     tcu::TestStatus iterate(void);
869 
870 protected:
871     virtual tcu::TestStatus executeTest(const VkCommandPool &cmdPool, const VkPipelineLayout pipelineLayout,
872                                         const VkDescriptorSet &descriptorSet, const BufferPtr buffer,
873                                         const VkDeviceSize bufferSizeBytes);
getComputeExecution(const ParametersCompute & parm) const874     uint32_t getComputeExecution(const ParametersCompute &parm) const
875     {
876         return parm.localSize.x() * parm.localSize.y() * parm.localSize.z() * parm.groupSize.x() * parm.groupSize.y() *
877                parm.groupSize.z();
878     }
879     const std::vector<ParametersCompute> &m_parameters;
880 };
881 
ComputeInvocationsTestInstance(Context & context,const std::vector<ParametersCompute> & parameters)882 ComputeInvocationsTestInstance::ComputeInvocationsTestInstance(Context &context,
883                                                                const std::vector<ParametersCompute> &parameters)
884     : StatisticQueryTestInstance(context, 1u, parameters[0].dstOffset, parameters[0].useComputeQueue)
885     , m_parameters(parameters)
886 {
887 }
888 
iterate(void)889 tcu::TestStatus ComputeInvocationsTestInstance::iterate(void)
890 {
891     // These should have the same value throughout the whole vector.
892     const bool hostQueryReset = ((m_parameters[0].resetType == RESET_TYPE_HOST) ? true : false);
893 
894     checkExtensions(hostQueryReset);
895 
896     const auto &deviceHelper  = getDeviceHelper(m_context, m_useComputeQueue);
897     const DeviceInterface &vk = deviceHelper.getDeviceInterface();
898     const VkDevice device     = deviceHelper.getDevice();
899     uint32_t maxSize          = 0u;
900 
901     for (size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
902         maxSize = deMaxu32(maxSize, getComputeExecution(m_parameters[parametersNdx]));
903 
904     const VkDeviceSize bufferSizeBytes = static_cast<VkDeviceSize>(
905         deAlignSize(static_cast<size_t>(sizeof(uint32_t) * maxSize),
906                     static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
907     BufferPtr buffer =
908         Buffer::createAndAlloc(vk, device, BufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
909                                deviceHelper.getAllocator(), MemoryRequirement::HostVisible);
910 
911     const Unique<VkDescriptorSetLayout> descriptorSetLayout(
912         DescriptorSetLayoutBuilder()
913             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
914             .build(vk, device));
915 
916     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
917 
918     const Unique<VkDescriptorPool> descriptorPool(
919         DescriptorPoolBuilder()
920             .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
921             .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
922 
923     const VkDescriptorSetAllocateInfo allocateParams = {
924         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
925         DE_NULL,                                        // const void* pNext;
926         *descriptorPool,                                // VkDescriptorPool descriptorPool;
927         1u,                                             // uint32_t setLayoutCount;
928         &(*descriptorSetLayout),                        // const VkDescriptorSetLayout* pSetLayouts;
929     };
930 
931     const Unique<VkDescriptorSet> descriptorSet(allocateDescriptorSet(vk, device, &allocateParams));
932     const VkDescriptorBufferInfo descriptorInfo = {
933         buffer->object(), //VkBuffer buffer;
934         0ull,             //VkDeviceSize offset;
935         bufferSizeBytes,  //VkDeviceSize range;
936     };
937 
938     DescriptorSetUpdateBuilder()
939         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
940                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
941         .update(vk, device);
942 
943     const CmdPoolCreateInfo cmdPoolCreateInfo(deviceHelper.getQueueFamilyIndex());
944     const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolCreateInfo));
945 
946     return executeTest(*cmdPool, *pipelineLayout, *descriptorSet, buffer, bufferSizeBytes);
947 }
948 
executeTest(const VkCommandPool & cmdPool,const VkPipelineLayout pipelineLayout,const VkDescriptorSet & descriptorSet,const BufferPtr buffer,const VkDeviceSize bufferSizeBytes)949 tcu::TestStatus ComputeInvocationsTestInstance::executeTest(const VkCommandPool &cmdPool,
950                                                             const VkPipelineLayout pipelineLayout,
951                                                             const VkDescriptorSet &descriptorSet,
952                                                             const BufferPtr buffer, const VkDeviceSize bufferSizeBytes)
953 {
954     const auto &deviceHelper                         = getDeviceHelper(m_context, m_useComputeQueue);
955     const DeviceInterface &vk                        = deviceHelper.getDeviceInterface();
956     const VkDevice device                            = deviceHelper.getDevice();
957     const VkQueue queue                              = deviceHelper.getQueue();
958     const VkBufferMemoryBarrier computeFinishBarrier = {
959         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType sType;
960         DE_NULL,                                                // const void* pNext;
961         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
962         VK_ACCESS_HOST_READ_BIT,                                // VkAccessFlags dstAccessMask;
963         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t srcQueueFamilyIndex;
964         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t destQueueFamilyIndex;
965         buffer->object(),                                       // VkBuffer buffer;
966         0ull,                                                   // VkDeviceSize offset;
967         bufferSizeBytes,                                        // VkDeviceSize size;
968     };
969 
970     for (size_t parametersNdx = 0u; parametersNdx < m_parameters.size(); ++parametersNdx)
971     {
972         clearBuffer(vk, device, buffer, bufferSizeBytes);
973         const Unique<VkShaderModule> shaderModule(
974             createShaderModule(vk, device, m_context.getBinaryCollection().get(m_parameters[parametersNdx].shaderName),
975                                (VkShaderModuleCreateFlags)0u));
976 
977         const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = {
978             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
979             DE_NULL,                                             // const void* pNext;
980             (VkPipelineShaderStageCreateFlags)0u,                // VkPipelineShaderStageCreateFlags flags;
981             VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits stage;
982             *shaderModule,                                       // VkShaderModule module;
983             "main",                                              // const char* pName;
984             DE_NULL,                                             // const VkSpecializationInfo* pSpecializationInfo;
985         };
986 
987         const VkComputePipelineCreateInfo pipelineCreateInfo = {
988             VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
989             DE_NULL,                                        // const void* pNext;
990             (VkPipelineCreateFlags)0u,                      // VkPipelineCreateFlags flags;
991             pipelineShaderStageParams,                      // VkPipelineShaderStageCreateInfo stage;
992             pipelineLayout,                                 // VkPipelineLayout layout;
993             DE_NULL,                                        // VkPipeline basePipelineHandle;
994             0,                                              // int32_t basePipelineIndex;
995         };
996         const Unique<VkPipeline> pipeline(createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo));
997 
998         const Unique<VkCommandBuffer> cmdBuffer(
999             allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1000         const Unique<VkQueryPool> queryPool(
1001             makeQueryPool(vk, device, 1u, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT));
1002 
1003         beginCommandBuffer(vk, *cmdBuffer);
1004         if (m_parameters[0].resetType != RESET_TYPE_HOST)
1005             vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, 1u);
1006 
1007         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
1008         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u,
1009                                  DE_NULL);
1010 
1011         vk.cmdBeginQuery(*cmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
1012         vk.cmdDispatch(*cmdBuffer, m_parameters[parametersNdx].groupSize.x(), m_parameters[parametersNdx].groupSize.y(),
1013                        m_parameters[parametersNdx].groupSize.z());
1014         vk.cmdEndQuery(*cmdBuffer, *queryPool, 0u);
1015 
1016         if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY || m_parameters[0].resetType == RESET_TYPE_AFTER_COPY ||
1017             m_parameters[0].copyType == COPY_TYPE_CMD)
1018         {
1019             VkDeviceSize stride          = m_parameters[0].querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
1020             vk::VkQueryResultFlags flags = m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
1021 
1022             if (m_parameters[0].resetType == RESET_TYPE_HOST)
1023             {
1024                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1025                 stride *= 2u;
1026             }
1027 
1028             if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY)
1029             {
1030                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, 1u);
1031                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1032                 stride = sizeof(ValueAndAvailability);
1033             }
1034 
1035             VkDeviceSize dstOffsetQuery = (m_parameters[0].dstOffset) ? stride : 0;
1036             VkDeviceSize copyStride     = stride;
1037 
1038             if (m_parameters[0].strideType == STRIDE_TYPE_ZERO)
1039                 copyStride = 0u;
1040 
1041             vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, 1u, m_resetBuffer->object(), dstOffsetQuery,
1042                                        copyStride, flags);
1043 
1044             if (m_parameters[0].resetType == RESET_TYPE_AFTER_COPY)
1045                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, 1u);
1046 
1047             const VkBufferMemoryBarrier barrier = {
1048                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
1049                 DE_NULL,                                 //  const void* pNext;
1050                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
1051                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
1052                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
1053                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
1054                 m_resetBuffer->object(),                 //  VkBuffer buffer;
1055                 0u,                                      //  VkDeviceSize offset;
1056                 1u * stride + dstOffsetQuery,            //  VkDeviceSize size;
1057             };
1058             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1059                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
1060                                   (const VkImageMemoryBarrier *)DE_NULL);
1061         }
1062 
1063         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1064                               (VkDependencyFlags)0u, 0u, (const VkMemoryBarrier *)DE_NULL, 1u, &computeFinishBarrier,
1065                               0u, (const VkImageMemoryBarrier *)DE_NULL);
1066 
1067         endCommandBuffer(vk, *cmdBuffer);
1068 
1069         m_context.getTestContext().getLog()
1070             << tcu::TestLog::Message
1071             << "Compute shader invocations: " << getComputeExecution(m_parameters[parametersNdx])
1072             << tcu::TestLog::EndMessage;
1073 
1074         if (m_parameters[0].resetType == RESET_TYPE_HOST)
1075             vk.resetQueryPool(device, *queryPool, 0u, 1u);
1076 
1077         // Wait for completion
1078         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1079 
1080         // Validate the results
1081         const Allocation &bufferAllocation = buffer->getBoundMemory();
1082         invalidateAlloc(vk, device, bufferAllocation);
1083 
1084         if (m_parameters[0].resetType == RESET_TYPE_NORMAL || m_parameters[0].resetType == RESET_TYPE_AFTER_COPY)
1085         {
1086             ResultsVector data;
1087 
1088             if (m_parameters[0].copyType == COPY_TYPE_CMD)
1089             {
1090                 const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
1091                 cmdCopyQueryPoolResultsVector(data, vk, device, allocation, 1u,
1092                                               (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags()),
1093                                               m_parameters[0].dstOffset);
1094             }
1095             else
1096             {
1097                 VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u,
1098                                                    (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags())));
1099             }
1100 
1101             if (getComputeExecution(m_parameters[parametersNdx]) != data[0])
1102                 return tcu::TestStatus::fail("QueryPoolResults incorrect");
1103         }
1104         else if (m_parameters[0].resetType == RESET_TYPE_HOST)
1105         {
1106             ResultsVectorWithAvailability data;
1107 
1108             if (m_parameters[0].copyType == COPY_TYPE_CMD)
1109             {
1110                 const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
1111                 cmdCopyQueryPoolResultsVector(data, vk, device, allocation, 1u,
1112                                               (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() |
1113                                                VK_QUERY_RESULT_WITH_AVAILABILITY_BIT),
1114                                               m_parameters[0].dstOffset);
1115             }
1116             else
1117             {
1118                 VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u,
1119                                                    (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() |
1120                                                     VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
1121             }
1122 
1123             if (getComputeExecution(m_parameters[parametersNdx]) != data[0].first || data[0].second == 0)
1124                 return tcu::TestStatus::fail("QueryPoolResults incorrect");
1125 
1126             uint64_t temp = data[0].first;
1127 
1128             vk.resetQueryPool(device, *queryPool, 0, 1u);
1129             vk::VkResult res =
1130                 GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u,
1131                                           (m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
1132             /* From Vulkan spec:
1133              *
1134              * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
1135              * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
1136              * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
1137              */
1138             if (res != vk::VK_NOT_READY || data[0].first != temp || data[0].second != 0u)
1139                 return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
1140         }
1141         else
1142         {
1143             // With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
1144             return verifyUnavailable();
1145         }
1146 
1147         const uint32_t *bufferPtr = static_cast<uint32_t *>(bufferAllocation.getHostPtr());
1148         for (uint32_t ndx = 0u; ndx < getComputeExecution(m_parameters[parametersNdx]); ++ndx)
1149         {
1150             if (bufferPtr[ndx] != ndx)
1151                 return tcu::TestStatus::fail("Compute shader didn't write data to the buffer");
1152         }
1153     }
1154     return tcu::TestStatus::pass("Pass");
1155 }
1156 
1157 class ComputeInvocationsSecondaryTestInstance : public ComputeInvocationsTestInstance
1158 {
1159 public:
1160     ComputeInvocationsSecondaryTestInstance(Context &context, const std::vector<ParametersCompute> &parameters);
1161 
1162 protected:
1163     tcu::TestStatus executeTest(const VkCommandPool &cmdPool, const VkPipelineLayout pipelineLayout,
1164                                 const VkDescriptorSet &descriptorSet, const BufferPtr buffer,
1165                                 const VkDeviceSize bufferSizeBytes);
1166     virtual tcu::TestStatus checkResult(const BufferPtr buffer, const VkQueryPool queryPool);
1167 };
1168 
ComputeInvocationsSecondaryTestInstance(Context & context,const std::vector<ParametersCompute> & parameters)1169 ComputeInvocationsSecondaryTestInstance::ComputeInvocationsSecondaryTestInstance(
1170     Context &context, const std::vector<ParametersCompute> &parameters)
1171     : ComputeInvocationsTestInstance(context, parameters)
1172 {
1173 }
1174 
executeTest(const VkCommandPool & cmdPool,const VkPipelineLayout pipelineLayout,const VkDescriptorSet & descriptorSet,const BufferPtr buffer,const VkDeviceSize bufferSizeBytes)1175 tcu::TestStatus ComputeInvocationsSecondaryTestInstance::executeTest(const VkCommandPool &cmdPool,
1176                                                                      const VkPipelineLayout pipelineLayout,
1177                                                                      const VkDescriptorSet &descriptorSet,
1178                                                                      const BufferPtr buffer,
1179                                                                      const VkDeviceSize bufferSizeBytes)
1180 {
1181     typedef de::SharedPtr<Unique<VkShaderModule>> VkShaderModuleSp;
1182     typedef de::SharedPtr<Unique<VkPipeline>> VkPipelineSp;
1183 
1184     const auto &deviceHelper  = getDeviceHelper(m_context, m_useComputeQueue);
1185     const DeviceInterface &vk = deviceHelper.getDeviceInterface();
1186     const VkDevice device     = deviceHelper.getDevice();
1187     const VkQueue queue       = deviceHelper.getQueue();
1188 
1189     const VkBufferMemoryBarrier computeShaderWriteBarrier = {
1190         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType sType;
1191         DE_NULL,                                                // const void* pNext;
1192         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1193         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1194         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t srcQueueFamilyIndex;
1195         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t destQueueFamilyIndex;
1196         buffer->object(),                                       // VkBuffer buffer;
1197         0ull,                                                   // VkDeviceSize offset;
1198         bufferSizeBytes,                                        // VkDeviceSize size;
1199     };
1200 
1201     const VkBufferMemoryBarrier computeFinishBarrier = {
1202         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType sType;
1203         DE_NULL,                                                // const void* pNext;
1204         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1205         VK_ACCESS_HOST_READ_BIT,                                // VkAccessFlags dstAccessMask;
1206         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t srcQueueFamilyIndex;
1207         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t destQueueFamilyIndex;
1208         buffer->object(),                                       // VkBuffer buffer;
1209         0ull,                                                   // VkDeviceSize offset;
1210         bufferSizeBytes,                                        // VkDeviceSize size;
1211     };
1212 
1213     std::vector<VkShaderModuleSp> shaderModule;
1214     std::vector<VkPipelineSp> pipeline;
1215     for (size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
1216     {
1217         shaderModule.push_back(VkShaderModuleSp(new Unique<VkShaderModule>(
1218             createShaderModule(vk, device, m_context.getBinaryCollection().get(m_parameters[parametersNdx].shaderName),
1219                                (VkShaderModuleCreateFlags)0u))));
1220         const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = {
1221             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1222             DE_NULL,                                             // const void* pNext;
1223             0u,                                                  // VkPipelineShaderStageCreateFlags flags;
1224             VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits stage;
1225             shaderModule.back().get()->get(),                    // VkShaderModule module;
1226             "main",                                              // const char* pName;
1227             DE_NULL,                                             // const VkSpecializationInfo* pSpecializationInfo;
1228         };
1229 
1230         const VkComputePipelineCreateInfo pipelineCreateInfo = {
1231             VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1232             DE_NULL,                                        // const void* pNext;
1233             0u,                                             // VkPipelineCreateFlags flags;
1234             pipelineShaderStageParams,                      // VkPipelineShaderStageCreateInfo stage;
1235             pipelineLayout,                                 // VkPipelineLayout layout;
1236             DE_NULL,                                        // VkPipeline basePipelineHandle;
1237             0,                                              // int32_t basePipelineIndex;
1238         };
1239         pipeline.push_back(
1240             VkPipelineSp(new Unique<VkPipeline>(createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo))));
1241     }
1242 
1243     const Unique<VkCommandBuffer> primaryCmdBuffer(
1244         allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1245     const Unique<VkCommandBuffer> secondaryCmdBuffer(
1246         allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY));
1247 
1248     const Unique<VkQueryPool> queryPool(
1249         makeQueryPool(vk, device, 1u, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT));
1250 
1251     clearBuffer(vk, device, buffer, bufferSizeBytes);
1252     beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT);
1253     vk.cmdBindDescriptorSets(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u,
1254                              &descriptorSet, 0u, DE_NULL);
1255     if (m_parameters[0].resetType != RESET_TYPE_HOST)
1256         vk.cmdResetQueryPool(*secondaryCmdBuffer, *queryPool, 0u, 1u);
1257     vk.cmdBeginQuery(*secondaryCmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
1258     for (size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
1259     {
1260         vk.cmdBindPipeline(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline[parametersNdx].get()->get());
1261         vk.cmdDispatch(*secondaryCmdBuffer, m_parameters[parametersNdx].groupSize.x(),
1262                        m_parameters[parametersNdx].groupSize.y(), m_parameters[parametersNdx].groupSize.z());
1263 
1264         vk.cmdPipelineBarrier(*secondaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
1265                               VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0u, 0u,
1266                               (const VkMemoryBarrier *)DE_NULL, 1u, &computeShaderWriteBarrier, 0u,
1267                               (const VkImageMemoryBarrier *)DE_NULL);
1268     }
1269     vk.cmdEndQuery(*secondaryCmdBuffer, *queryPool, 0u);
1270 
1271     if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY || m_parameters[0].resetType == RESET_TYPE_AFTER_COPY ||
1272         m_parameters[0].copyType == COPY_TYPE_CMD)
1273     {
1274         VkDeviceSize stride          = m_parameters[0].querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
1275         vk::VkQueryResultFlags flags = m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
1276 
1277         if (m_parameters[0].resetType == RESET_TYPE_HOST)
1278         {
1279             flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1280             stride *= 2u;
1281         }
1282 
1283         if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY)
1284         {
1285             vk.cmdResetQueryPool(*secondaryCmdBuffer, *queryPool, 0u, 1u);
1286             flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1287             stride = sizeof(ValueAndAvailability);
1288         }
1289 
1290         VkDeviceSize dstOffsetQuery = (m_parameters[0].dstOffset) ? stride : 0;
1291         VkDeviceSize copyStride     = stride;
1292         if (m_parameters[0].strideType == STRIDE_TYPE_ZERO)
1293             copyStride = 0u;
1294 
1295         vk.cmdCopyQueryPoolResults(*secondaryCmdBuffer, *queryPool, 0, 1u, m_resetBuffer->object(), dstOffsetQuery,
1296                                    copyStride, flags);
1297 
1298         if (m_parameters[0].resetType == RESET_TYPE_AFTER_COPY)
1299             vk.cmdResetQueryPool(*secondaryCmdBuffer, *queryPool, 0u, 1u);
1300 
1301         const VkBufferMemoryBarrier barrier = {
1302             VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
1303             DE_NULL,                                 //  const void* pNext;
1304             VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
1305             VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
1306             VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
1307             VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
1308             m_resetBuffer->object(),                 //  VkBuffer buffer;
1309             0u,                                      //  VkDeviceSize offset;
1310             1u * stride + dstOffsetQuery,            //  VkDeviceSize size;
1311         };
1312         vk.cmdPipelineBarrier(*secondaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1313                               (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
1314                               (const VkImageMemoryBarrier *)DE_NULL);
1315     }
1316 
1317     endCommandBuffer(vk, *secondaryCmdBuffer);
1318 
1319     beginCommandBuffer(vk, *primaryCmdBuffer);
1320     vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &secondaryCmdBuffer.get());
1321 
1322     vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1323                           (VkDependencyFlags)0u, 0u, (const VkMemoryBarrier *)DE_NULL, 1u, &computeFinishBarrier, 0u,
1324                           (const VkImageMemoryBarrier *)DE_NULL);
1325 
1326     endCommandBuffer(vk, *primaryCmdBuffer);
1327 
1328     // Secondary buffer is emitted only once, so it is safe to reset the query pool here.
1329     if (m_parameters[0].resetType == RESET_TYPE_HOST)
1330         vk.resetQueryPool(device, *queryPool, 0u, 1u);
1331 
1332     // Wait for completion
1333     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
1334     return checkResult(buffer, *queryPool);
1335 }
1336 
checkResult(const BufferPtr buffer,const VkQueryPool queryPool)1337 tcu::TestStatus ComputeInvocationsSecondaryTestInstance::checkResult(const BufferPtr buffer,
1338                                                                      const VkQueryPool queryPool)
1339 {
1340     const auto &deviceHelper  = getDeviceHelper(m_context, m_useComputeQueue);
1341     const DeviceInterface &vk = deviceHelper.getDeviceInterface();
1342     const VkDevice device     = deviceHelper.getDevice();
1343     {
1344         uint64_t expected = 0u;
1345         for (size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
1346             expected += getComputeExecution(m_parameters[parametersNdx]);
1347 
1348         if (m_parameters[0].resetType == RESET_TYPE_NORMAL || m_parameters[0].resetType == RESET_TYPE_AFTER_COPY)
1349         {
1350             ResultsVector results;
1351             if (m_parameters[0].copyType == COPY_TYPE_CMD)
1352             {
1353                 const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
1354                 cmdCopyQueryPoolResultsVector(results, vk, device, allocation, 1u,
1355                                               (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags()),
1356                                               m_parameters[0].dstOffset);
1357             }
1358             else
1359             {
1360                 VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u,
1361                                                    (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags())));
1362             }
1363 
1364             if (expected != results[0])
1365                 return tcu::TestStatus::fail("QueryPoolResults incorrect");
1366         }
1367         else if (m_parameters[0].resetType == RESET_TYPE_HOST)
1368         {
1369             ResultsVectorWithAvailability results;
1370 
1371             if (m_parameters[0].copyType == COPY_TYPE_CMD)
1372             {
1373                 const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
1374                 cmdCopyQueryPoolResultsVector(results, vk, device, allocation, 1u,
1375                                               (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() |
1376                                                VK_QUERY_RESULT_WITH_AVAILABILITY_BIT),
1377                                               m_parameters[0].dstOffset);
1378             }
1379             else
1380             {
1381                 VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u,
1382                                                    (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() |
1383                                                     VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
1384             }
1385 
1386             if (expected != results[0].first || results[0].second == 0u)
1387                 return tcu::TestStatus::fail("QueryPoolResults incorrect");
1388 
1389             uint64_t temp = results[0].first;
1390 
1391             vk.resetQueryPool(device, queryPool, 0u, 1u);
1392             vk::VkResult res =
1393                 GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u,
1394                                           (m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
1395             /* From Vulkan spec:
1396              *
1397              * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
1398              * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
1399              * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
1400              */
1401             if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0u)
1402                 return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
1403         }
1404         else
1405         {
1406             // With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
1407             return verifyUnavailable();
1408         }
1409     }
1410 
1411     {
1412         // Validate the results
1413         const Allocation &bufferAllocation = buffer->getBoundMemory();
1414         invalidateAlloc(vk, device, bufferAllocation);
1415         const uint32_t *bufferPtr = static_cast<uint32_t *>(bufferAllocation.getHostPtr());
1416         uint32_t minSize          = ~0u;
1417         for (size_t parametersNdx = 0; parametersNdx < m_parameters.size(); ++parametersNdx)
1418             minSize = deMinu32(minSize, getComputeExecution(m_parameters[parametersNdx]));
1419         for (uint32_t ndx = 0u; ndx < minSize; ++ndx)
1420         {
1421             if (bufferPtr[ndx] != ndx * m_parameters.size())
1422                 return tcu::TestStatus::fail("Compute shader didn't write data to the buffer");
1423         }
1424     }
1425     return tcu::TestStatus::pass("Pass");
1426 }
1427 
1428 class ComputeInvocationsSecondaryInheritedTestInstance : public ComputeInvocationsSecondaryTestInstance
1429 {
1430 public:
1431     ComputeInvocationsSecondaryInheritedTestInstance(Context &context,
1432                                                      const std::vector<ParametersCompute> &parameters);
1433 
1434 protected:
1435     virtual void checkExtensions(bool hostResetQueryEnabled);
1436 
1437     tcu::TestStatus executeTest(const VkCommandPool &cmdPool, const VkPipelineLayout pipelineLayout,
1438                                 const VkDescriptorSet &descriptorSet, const BufferPtr buffer,
1439                                 const VkDeviceSize bufferSizeBytes);
1440 };
1441 
ComputeInvocationsSecondaryInheritedTestInstance(Context & context,const std::vector<ParametersCompute> & parameters)1442 ComputeInvocationsSecondaryInheritedTestInstance::ComputeInvocationsSecondaryInheritedTestInstance(
1443     Context &context, const std::vector<ParametersCompute> &parameters)
1444     : ComputeInvocationsSecondaryTestInstance(context, parameters)
1445 {
1446 }
1447 
checkExtensions(bool hostResetQueryEnabled)1448 void ComputeInvocationsSecondaryInheritedTestInstance::checkExtensions(bool hostResetQueryEnabled)
1449 {
1450     StatisticQueryTestInstance::checkExtensions(hostResetQueryEnabled);
1451     if (!m_context.getDeviceFeatures().inheritedQueries)
1452         throw tcu::NotSupportedError("Inherited queries are not supported");
1453 }
1454 
executeTest(const VkCommandPool & cmdPool,const VkPipelineLayout pipelineLayout,const VkDescriptorSet & descriptorSet,const BufferPtr buffer,const VkDeviceSize bufferSizeBytes)1455 tcu::TestStatus ComputeInvocationsSecondaryInheritedTestInstance::executeTest(const VkCommandPool &cmdPool,
1456                                                                               const VkPipelineLayout pipelineLayout,
1457                                                                               const VkDescriptorSet &descriptorSet,
1458                                                                               const BufferPtr buffer,
1459                                                                               const VkDeviceSize bufferSizeBytes)
1460 {
1461     typedef de::SharedPtr<Unique<VkShaderModule>> VkShaderModuleSp;
1462     typedef de::SharedPtr<Unique<VkPipeline>> VkPipelineSp;
1463 
1464     const auto &deviceHelper  = getDeviceHelper(m_context, m_useComputeQueue);
1465     const DeviceInterface &vk = deviceHelper.getDeviceInterface();
1466     const VkDevice device     = deviceHelper.getDevice();
1467     const VkQueue queue       = deviceHelper.getQueue();
1468 
1469     const VkBufferMemoryBarrier computeShaderWriteBarrier = {
1470         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType sType;
1471         DE_NULL,                                                // const void* pNext;
1472         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1473         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1474         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t srcQueueFamilyIndex;
1475         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t destQueueFamilyIndex;
1476         buffer->object(),                                       // VkBuffer buffer;
1477         0ull,                                                   // VkDeviceSize offset;
1478         bufferSizeBytes,                                        // VkDeviceSize size;
1479     };
1480 
1481     const VkBufferMemoryBarrier computeFinishBarrier = {
1482         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType sType;
1483         DE_NULL,                                                // const void* pNext;
1484         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1485         VK_ACCESS_HOST_READ_BIT,                                // VkAccessFlags dstAccessMask;
1486         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t srcQueueFamilyIndex;
1487         VK_QUEUE_FAMILY_IGNORED,                                // uint32_t destQueueFamilyIndex;
1488         buffer->object(),                                       // VkBuffer buffer;
1489         0ull,                                                   // VkDeviceSize offset;
1490         bufferSizeBytes,                                        // VkDeviceSize size;
1491     };
1492 
1493     std::vector<VkShaderModuleSp> shaderModule;
1494     std::vector<VkPipelineSp> pipeline;
1495     for (size_t parametersNdx = 0u; parametersNdx < m_parameters.size(); ++parametersNdx)
1496     {
1497         shaderModule.push_back(VkShaderModuleSp(new Unique<VkShaderModule>(
1498             createShaderModule(vk, device, m_context.getBinaryCollection().get(m_parameters[parametersNdx].shaderName),
1499                                (VkShaderModuleCreateFlags)0u))));
1500         const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = {
1501             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1502             DE_NULL,                                             // const void* pNext;
1503             0u,                                                  // VkPipelineShaderStageCreateFlags flags;
1504             VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits stage;
1505             shaderModule.back().get()->get(),                    // VkShaderModule module;
1506             "main",                                              // const char* pName;
1507             DE_NULL,                                             // const VkSpecializationInfo* pSpecializationInfo;
1508         };
1509 
1510         const VkComputePipelineCreateInfo pipelineCreateInfo = {
1511             VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1512             DE_NULL,                                        // const void* pNext;
1513             0u,                                             // VkPipelineCreateFlags flags;
1514             pipelineShaderStageParams,                      // VkPipelineShaderStageCreateInfo stage;
1515             pipelineLayout,                                 // VkPipelineLayout layout;
1516             DE_NULL,                                        // VkPipeline basePipelineHandle;
1517             0,                                              // int32_t basePipelineIndex;
1518         };
1519         pipeline.push_back(
1520             VkPipelineSp(new Unique<VkPipeline>(createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo))));
1521     }
1522 
1523     const Unique<VkCommandBuffer> primaryCmdBuffer(
1524         allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1525     const Unique<VkCommandBuffer> secondaryCmdBuffer(
1526         allocateCommandBuffer(vk, device, cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY));
1527 
1528     const Unique<VkQueryPool> queryPool(
1529         makeQueryPool(vk, device, 1u, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT));
1530 
1531     clearBuffer(vk, device, buffer, bufferSizeBytes);
1532     beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT);
1533     vk.cmdBindDescriptorSets(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u,
1534                              &descriptorSet, 0u, DE_NULL);
1535     for (size_t parametersNdx = 1; parametersNdx < m_parameters.size(); ++parametersNdx)
1536     {
1537         vk.cmdBindPipeline(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline[parametersNdx].get()->get());
1538         vk.cmdDispatch(*secondaryCmdBuffer, m_parameters[parametersNdx].groupSize.x(),
1539                        m_parameters[parametersNdx].groupSize.y(), m_parameters[parametersNdx].groupSize.z());
1540 
1541         vk.cmdPipelineBarrier(*secondaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
1542                               VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0u, 0u,
1543                               (const VkMemoryBarrier *)DE_NULL, 1u, &computeShaderWriteBarrier, 0u,
1544                               (const VkImageMemoryBarrier *)DE_NULL);
1545     }
1546     endCommandBuffer(vk, *secondaryCmdBuffer);
1547 
1548     beginCommandBuffer(vk, *primaryCmdBuffer);
1549     if (m_parameters[0].resetType != RESET_TYPE_HOST)
1550         vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, 1u);
1551     vk.cmdBindDescriptorSets(*primaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet,
1552                              0u, DE_NULL);
1553     vk.cmdBindPipeline(*primaryCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline[0].get()->get());
1554 
1555     vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
1556     vk.cmdDispatch(*primaryCmdBuffer, m_parameters[0].groupSize.x(), m_parameters[0].groupSize.y(),
1557                    m_parameters[0].groupSize.z());
1558 
1559     vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
1560                           (VkDependencyFlags)0u, 0u, (const VkMemoryBarrier *)DE_NULL, 1u, &computeShaderWriteBarrier,
1561                           0u, (const VkImageMemoryBarrier *)DE_NULL);
1562 
1563     vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &secondaryCmdBuffer.get());
1564 
1565     vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1566                           (VkDependencyFlags)0u, 0u, (const VkMemoryBarrier *)DE_NULL, 1u, &computeFinishBarrier, 0u,
1567                           (const VkImageMemoryBarrier *)DE_NULL);
1568 
1569     vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, 0u);
1570 
1571     if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY || m_parameters[0].resetType == RESET_TYPE_AFTER_COPY ||
1572         m_parameters[0].copyType == COPY_TYPE_CMD)
1573     {
1574         VkDeviceSize stride          = m_parameters[0].querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
1575         vk::VkQueryResultFlags flags = m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
1576 
1577         if (m_parameters[0].resetType == RESET_TYPE_HOST)
1578         {
1579             flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1580             stride *= 2u;
1581         }
1582 
1583         if (m_parameters[0].resetType == RESET_TYPE_BEFORE_COPY)
1584         {
1585             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, 1u);
1586             flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
1587             stride = sizeof(ValueAndAvailability);
1588         }
1589 
1590         VkDeviceSize dstOffsetQuery = (m_parameters[0].dstOffset) ? stride : 0;
1591         VkDeviceSize copyStride     = stride;
1592         if (m_parameters[0].strideType == STRIDE_TYPE_ZERO)
1593             copyStride = 0u;
1594 
1595         vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, 1u, m_resetBuffer->object(), dstOffsetQuery,
1596                                    copyStride, flags);
1597 
1598         if (m_parameters[0].resetType == RESET_TYPE_AFTER_COPY)
1599             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, 1u);
1600 
1601         const VkBufferMemoryBarrier barrier = {
1602             VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
1603             DE_NULL,                                 //  const void* pNext;
1604             VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
1605             VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
1606             VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
1607             VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
1608             m_resetBuffer->object(),                 //  VkBuffer buffer;
1609             0u,                                      //  VkDeviceSize offset;
1610             1u * stride + dstOffsetQuery,            //  VkDeviceSize size;
1611         };
1612         vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1613                               (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
1614                               (const VkImageMemoryBarrier *)DE_NULL);
1615     }
1616 
1617     endCommandBuffer(vk, *primaryCmdBuffer);
1618 
1619     if (m_parameters[0].resetType == RESET_TYPE_HOST)
1620         vk.resetQueryPool(device, *queryPool, 0u, 1u);
1621 
1622     // Wait for completion
1623     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
1624     return checkResult(buffer, *queryPool);
1625 }
1626 
1627 class GraphicBasicTestInstance : public StatisticQueryTestInstance
1628 {
1629 public:
1630     struct VertexData
1631     {
VertexDatavkt::QueryPool::__anon6b4348560111::GraphicBasicTestInstance::VertexData1632         VertexData(const tcu::Vec4 position_, const tcu::Vec4 color_) : position(position_), color(color_)
1633         {
1634         }
1635         tcu::Vec4 position;
1636         tcu::Vec4 color;
1637     };
1638 
1639     struct ParametersGraphic : public GenericParameters
1640     {
ParametersGraphicvkt::QueryPool::__anon6b4348560111::GraphicBasicTestInstance::ParametersGraphic1641         ParametersGraphic(const VkQueryPipelineStatisticFlags queryStatisticFlags_,
1642                           const VkPrimitiveTopology primitiveTopology_, const ResetType resetType_,
1643                           const CopyType copyType_, const bool query64Bits_, const bool vertexOnlyPipe_ = false,
1644                           const bool dstOffset_ = false, const ClearOperation clearOp_ = CLEAR_NOOP,
1645                           const bool noColorAttachments_ = false, const StrideType strideType_ = STRIDE_TYPE_VALID,
1646                           const bool hasTess_ = false)
1647             : GenericParameters{resetType_, copyType_, query64Bits_, dstOffset_, strideType_}
1648             , queryStatisticFlags(queryStatisticFlags_)
1649             , primitiveTopology(primitiveTopology_)
1650             , vertexOnlyPipe(vertexOnlyPipe_)
1651             , clearOp(clearOp_)
1652             , noColorAttachments(noColorAttachments_)
1653             , hasTess(hasTess_)
1654         {
1655         }
1656 
1657         VkQueryPipelineStatisticFlags queryStatisticFlags;
1658         VkPrimitiveTopology primitiveTopology;
1659         bool vertexOnlyPipe;
1660         ClearOperation clearOp;
1661         bool noColorAttachments;
1662         bool hasTess;
1663     };
1664     GraphicBasicTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
1665                              const ParametersGraphic &parametersGraphic, const std::vector<uint64_t> &drawRepeats);
1666     tcu::TestStatus iterate(void);
1667 
1668 protected:
1669     BufferPtr creatAndFillVertexBuffer(void);
1670     virtual void createPipeline(void) = 0;
1671     void commandClearAttachment(const vk::DeviceInterface &vk, const vk::VkCommandBuffer commandBuffer);
1672     void creatColorAttachmentAndRenderPass(void);
1673     bool checkImage(void);
1674     virtual tcu::TestStatus executeTest(void)                  = 0;
1675     virtual tcu::TestStatus checkResult(VkQueryPool queryPool) = 0;
1676     virtual void draw(VkCommandBuffer cmdBuffer)               = 0;
1677 
1678     const VkFormat m_colorAttachmentFormat;
1679     de::SharedPtr<Image> m_colorAttachmentImage;
1680     de::SharedPtr<Image> m_depthImage;
1681     Move<VkImageView> m_attachmentView;
1682     Move<VkImageView> m_depthView;
1683     Move<VkRenderPass> m_renderPass;
1684     Move<VkFramebuffer> m_framebuffer;
1685     Move<VkPipeline> m_pipeline;
1686     Move<VkPipelineLayout> m_pipelineLayout;
1687     const std::vector<VertexData> &m_data;
1688     const ParametersGraphic &m_parametersGraphic;
1689     std::vector<uint64_t> m_drawRepeats;
1690 };
1691 
GraphicBasicTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)1692 GraphicBasicTestInstance::GraphicBasicTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
1693                                                    const ParametersGraphic &parametersGraphic,
1694                                                    const std::vector<uint64_t> &drawRepeats)
1695     : StatisticQueryTestInstance(context, static_cast<uint32_t>(drawRepeats.size()), parametersGraphic.dstOffset, false)
1696     , m_colorAttachmentFormat(VK_FORMAT_R8G8B8A8_UNORM)
1697     , m_data(data)
1698     , m_parametersGraphic(parametersGraphic)
1699     , m_drawRepeats(drawRepeats)
1700 {
1701 }
1702 
iterate(void)1703 tcu::TestStatus GraphicBasicTestInstance::iterate(void)
1704 {
1705     checkExtensions((m_parametersGraphic.resetType == RESET_TYPE_HOST) ? true : false);
1706     creatColorAttachmentAndRenderPass();
1707     createPipeline();
1708     return executeTest();
1709 }
1710 
creatAndFillVertexBuffer(void)1711 BufferPtr GraphicBasicTestInstance::creatAndFillVertexBuffer(void)
1712 {
1713     const DeviceInterface &vk = m_context.getDeviceInterface();
1714     const VkDevice device     = m_context.getDevice();
1715 
1716     const VkDeviceSize dataSize = static_cast<VkDeviceSize>(
1717         deAlignSize(static_cast<size_t>(m_data.size() * sizeof(VertexData)),
1718                     static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
1719 
1720     BufferPtr vertexBuffer =
1721         Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
1722                                m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
1723 
1724     uint8_t *ptr = reinterpret_cast<uint8_t *>(vertexBuffer->getBoundMemory().getHostPtr());
1725     deMemcpy(ptr, &m_data[0], static_cast<size_t>(m_data.size() * sizeof(VertexData)));
1726 
1727     flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(),
1728                            vertexBuffer->getBoundMemory().getOffset(), dataSize);
1729     return vertexBuffer;
1730 }
1731 
commandClearAttachment(const vk::DeviceInterface & vk,const vk::VkCommandBuffer commandBuffer)1732 void GraphicBasicTestInstance::commandClearAttachment(const vk::DeviceInterface &vk,
1733                                                       const vk::VkCommandBuffer commandBuffer)
1734 {
1735     const vk::VkOffset2D offset = vk::makeOffset2D(0, 0);
1736     const vk::VkExtent2D extent = vk::makeExtent2D(WIDTH, HEIGHT);
1737 
1738     const vk::VkClearAttachment attachment = {
1739         m_parametersGraphic.clearOp == CLEAR_COLOR ?
1740             (vk::VkImageAspectFlags)vk::VK_IMAGE_ASPECT_COLOR_BIT :
1741             (vk::VkImageAspectFlags)vk::VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
1742         m_parametersGraphic.clearOp == CLEAR_COLOR ? 0u : 1u,      // uint32_t colorAttachment;
1743         m_parametersGraphic.clearOp == CLEAR_COLOR ?
1744             vk::makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)) :
1745             vk::makeClearValueDepthStencil(0.0f, 0u) // VkClearValue clearValue;
1746     };
1747 
1748     const vk::VkClearRect rect = {
1749         {offset, extent}, // VkRect2D rect;
1750         0u,               // uint32_t baseArrayLayer;
1751         1u,               // uint32_t layerCount;
1752     };
1753 
1754     vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1755 }
1756 
creatColorAttachmentAndRenderPass(void)1757 void GraphicBasicTestInstance::creatColorAttachmentAndRenderPass(void)
1758 {
1759     const DeviceInterface &vk = m_context.getDeviceInterface();
1760     const VkDevice device     = m_context.getDevice();
1761 
1762     VkExtent3D imageExtent = {
1763         WIDTH,  // width;
1764         HEIGHT, // height;
1765         1u      // depth;
1766     };
1767 
1768     if (!m_parametersGraphic.noColorAttachments)
1769     {
1770 
1771         const ImageCreateInfo colorImageCreateInfo(
1772             VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT,
1773             VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1774 
1775         m_colorAttachmentImage =
1776             Image::createAndAlloc(vk, device, colorImageCreateInfo, m_context.getDefaultAllocator(),
1777                                   m_context.getUniversalQueueFamilyIndex());
1778 
1779         const ImageViewCreateInfo attachmentViewInfo(m_colorAttachmentImage->object(), VK_IMAGE_VIEW_TYPE_2D,
1780                                                      m_colorAttachmentFormat);
1781         m_attachmentView = createImageView(vk, device, &attachmentViewInfo);
1782     }
1783 
1784     ImageCreateInfo depthImageCreateInfo(vk::VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM, imageExtent, 1, 1,
1785                                          vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
1786                                          vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
1787     m_depthImage = Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(),
1788                                          m_context.getUniversalQueueFamilyIndex());
1789 
1790     // Construct a depth  view from depth image
1791     const ImageViewCreateInfo depthViewInfo(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM);
1792     m_depthView = vk::createImageView(vk, device, &depthViewInfo);
1793 
1794     // Renderpass and Framebuffer
1795     if (m_parametersGraphic.noColorAttachments)
1796     {
1797         RenderPassCreateInfo renderPassCreateInfo;
1798 
1799         renderPassCreateInfo.addAttachment(
1800             AttachmentDescription(VK_FORMAT_D16_UNORM,                                    // format
1801                                   vk::VK_SAMPLE_COUNT_1_BIT,                              // samples
1802                                   vk::VK_ATTACHMENT_LOAD_OP_CLEAR,                        // loadOp
1803                                   vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // storeOp
1804                                   vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // stencilLoadOp
1805                                   vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // stencilLoadOp
1806                                   vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // initialLauout
1807                                   vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); // finalLayout
1808 
1809         const VkAttachmentReference depthAttachmentReference = {
1810             0u,                                                  // attachment
1811             vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // layout
1812         };
1813 
1814         renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1815                                                            0,                                   // flags
1816                                                            0,                                   // inputCount
1817                                                            DE_NULL,                             // pInputAttachments
1818                                                            0,                                   // colorCount
1819                                                            DE_NULL,                             // pColorAttachments
1820                                                            DE_NULL,                             // pResolveAttachments
1821                                                            depthAttachmentReference, // depthStencilAttachment
1822                                                            0,                        // preserveCount
1823                                                            DE_NULL));                // preserveAttachments
1824         m_renderPass = vk::createRenderPass(vk, device, &renderPassCreateInfo);
1825 
1826         std::vector<vk::VkImageView> attachments(1);
1827         attachments[0] = *m_depthView;
1828 
1829         FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
1830         m_framebuffer = vk::createFramebuffer(vk, device, &framebufferCreateInfo);
1831     }
1832     else
1833     {
1834         RenderPassCreateInfo renderPassCreateInfo;
1835         renderPassCreateInfo.addAttachment(
1836             AttachmentDescription(m_colorAttachmentFormat,                    // format
1837                                   VK_SAMPLE_COUNT_1_BIT,                      // samples
1838                                   VK_ATTACHMENT_LOAD_OP_CLEAR,                // loadOp
1839                                   VK_ATTACHMENT_STORE_OP_STORE,               // storeOp
1840                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,            // stencilLoadOp
1841                                   VK_ATTACHMENT_STORE_OP_STORE,               // stencilLoadOp
1842                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,   // initialLauout
1843                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); // finalLayout
1844 
1845         renderPassCreateInfo.addAttachment(
1846             AttachmentDescription(VK_FORMAT_D16_UNORM,                                    // format
1847                                   vk::VK_SAMPLE_COUNT_1_BIT,                              // samples
1848                                   vk::VK_ATTACHMENT_LOAD_OP_CLEAR,                        // loadOp
1849                                   vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // storeOp
1850                                   vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // stencilLoadOp
1851                                   vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // stencilLoadOp
1852                                   vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // initialLauout
1853                                   vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); // finalLayout
1854 
1855         const VkAttachmentReference colorAttachmentReference = {
1856             0u,                                      // attachment
1857             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
1858         };
1859 
1860         const VkAttachmentReference depthAttachmentReference = {
1861             1u,                                                  // attachment
1862             vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // layout
1863         };
1864 
1865         const VkSubpassDescription subpass = {
1866             (VkSubpassDescriptionFlags)0,    //VkSubpassDescriptionFlags flags;
1867             VK_PIPELINE_BIND_POINT_GRAPHICS, //VkPipelineBindPoint pipelineBindPoint;
1868             0u,                              //uint32_t inputAttachmentCount;
1869             DE_NULL,                         //const VkAttachmentReference* pInputAttachments;
1870             1u,                              //uint32_t colorAttachmentCount;
1871             &colorAttachmentReference,       //const VkAttachmentReference* pColorAttachments;
1872             DE_NULL,                         //const VkAttachmentReference* pResolveAttachments;
1873             &depthAttachmentReference,       //const VkAttachmentReference* pDepthStencilAttachment;
1874             0u,                              //uint32_t preserveAttachmentCount;
1875             DE_NULL,                         //const uint32_t* pPreserveAttachments;
1876         };
1877 
1878         renderPassCreateInfo.addSubpass(subpass);
1879         m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
1880 
1881         std::vector<vk::VkImageView> attachments(2);
1882         attachments[0] = *m_attachmentView;
1883         attachments[1] = *m_depthView;
1884 
1885         FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
1886         m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
1887     }
1888 }
1889 
checkImage(void)1890 bool GraphicBasicTestInstance::checkImage(void)
1891 {
1892     if (m_parametersGraphic.vertexOnlyPipe)
1893         return true;
1894 
1895     const VkQueue queue         = m_context.getUniversalQueue();
1896     const VkOffset3D zeroOffset = {0, 0, 0};
1897     const tcu::ConstPixelBufferAccess renderedFrame =
1898         m_colorAttachmentImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_GENERAL, zeroOffset,
1899                                             WIDTH, HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
1900     int colorNdx = 0;
1901     tcu::Texture2D referenceFrame(mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
1902     referenceFrame.allocLevel(0);
1903 
1904     for (int y = 0; y < HEIGHT / 2; ++y)
1905         for (int x = 0; x < WIDTH / 2; ++x)
1906             referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1907 
1908     colorNdx += 4;
1909     for (int y = HEIGHT / 2; y < HEIGHT; ++y)
1910         for (int x = 0; x < WIDTH / 2; ++x)
1911             referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1912 
1913     colorNdx += 4;
1914     for (int y = 0; y < HEIGHT / 2; ++y)
1915         for (int x = WIDTH / 2; x < WIDTH; ++x)
1916             referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1917 
1918     colorNdx += 4;
1919     for (int y = HEIGHT / 2; y < HEIGHT; ++y)
1920         for (int x = WIDTH / 2; x < WIDTH; ++x)
1921             referenceFrame.getLevel(0).setPixel(m_data[colorNdx].color, x, y);
1922 
1923     return tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result",
1924                                       referenceFrame.getLevel(0), renderedFrame, tcu::Vec4(0.01f),
1925                                       tcu::COMPARE_LOG_ON_ERROR);
1926 }
1927 
1928 class VertexShaderTestInstance : public GraphicBasicTestInstance
1929 {
1930 public:
1931     VertexShaderTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
1932                              const ParametersGraphic &parametersGraphic, const std::vector<uint64_t> &drawRepeats);
1933 
1934 protected:
1935     virtual void createPipeline(void);
1936     virtual tcu::TestStatus executeTest(void);
1937     virtual tcu::TestStatus checkResult(VkQueryPool queryPool);
1938     void draw(VkCommandBuffer cmdBuffer);
1939 };
1940 
VertexShaderTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)1941 VertexShaderTestInstance::VertexShaderTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
1942                                                    const ParametersGraphic &parametersGraphic,
1943                                                    const std::vector<uint64_t> &drawRepeats)
1944     : GraphicBasicTestInstance(context, data, parametersGraphic, drawRepeats)
1945 {
1946 }
1947 
createPipeline(void)1948 void VertexShaderTestInstance::createPipeline(void)
1949 {
1950     const DeviceInterface &vk = m_context.getDeviceInterface();
1951     const VkDevice device     = m_context.getDevice();
1952 
1953     switch (m_parametersGraphic.primitiveTopology)
1954     {
1955     case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
1956     case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
1957     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
1958     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
1959         if (!m_context.getDeviceFeatures().geometryShader)
1960             throw tcu::NotSupportedError("Geometry shader are not supported");
1961         break;
1962     default:
1963         break;
1964     }
1965 
1966     // Pipeline
1967     Unique<VkShaderModule> vs(createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), 0));
1968     Move<VkShaderModule> fs;
1969 
1970     if (!m_parametersGraphic.vertexOnlyPipe)
1971         fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), 0);
1972 
1973     const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
1974 
1975     const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
1976     m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
1977 
1978     const VkVertexInputBindingDescription vertexInputBindingDescription = {
1979         0,                                         // binding;
1980         static_cast<uint32_t>(sizeof(VertexData)), // stride;
1981         VK_VERTEX_INPUT_RATE_VERTEX                // inputRate
1982     };
1983 
1984     const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
1985         {0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u}, // VertexElementData::position
1986         {1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, static_cast<uint32_t>(sizeof(tcu::Vec4))}, // VertexElementData::color
1987     };
1988 
1989     const VkPipelineVertexInputStateCreateInfo vf_info = {
1990         // sType;
1991         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // pNext;
1992         NULL,                                                      // flags;
1993         0u,                                                        // vertexBindingDescriptionCount;
1994         1u,                                                        // pVertexBindingDescriptions;
1995         &vertexInputBindingDescription,                            // vertexAttributeDescriptionCount;
1996         2u,                                                        // pVertexAttributeDescriptions;
1997         vertexInputAttributeDescriptions};
1998 
1999     PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
2000     pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
2001     if (!m_parametersGraphic.vertexOnlyPipe)
2002         pipelineCreateInfo.addShader(
2003             PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
2004     pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
2005     pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_parametersGraphic.primitiveTopology));
2006     pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
2007 
2008     const VkViewport viewport = makeViewport(WIDTH, HEIGHT);
2009     const VkRect2D scissor    = makeRect2D(WIDTH, HEIGHT);
2010     pipelineCreateInfo.addState(
2011         PipelineCreateInfo::ViewportState(1u, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
2012     pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
2013     pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
2014     pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
2015     pipelineCreateInfo.addState(vf_info);
2016     m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
2017 }
2018 
executeTest(void)2019 tcu::TestStatus VertexShaderTestInstance::executeTest(void)
2020 {
2021     const DeviceInterface &vk       = m_context.getDeviceInterface();
2022     const VkDevice device           = m_context.getDevice();
2023     const VkQueue queue             = m_context.getUniversalQueue();
2024     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2025 
2026     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
2027     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
2028     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
2029     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2030 
2031     const VkDeviceSize vertexBufferOffset = 0u;
2032     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
2033     const VkBuffer vertexBuffer           = vertexBufferSp->object();
2034 
2035     const Unique<VkCommandBuffer> cmdBuffer(
2036         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2037 
2038     beginCommandBuffer(vk, *cmdBuffer);
2039     {
2040         std::vector<VkClearValue> renderPassClearValues(2);
2041         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2042 
2043         if (!m_parametersGraphic.noColorAttachments)
2044             initialTransitionColor2DImage(
2045                 vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2046                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2047         initialTransitionDepth2DImage(
2048             vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2049             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
2050             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2051 
2052         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2053             vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2054 
2055         beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
2056                         (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0]);
2057 
2058         for (uint32_t i = 0; i < queryCount; ++i)
2059         {
2060             vk.cmdBeginQuery(*cmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
2061             vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
2062             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2063 
2064             for (uint64_t j = 0; j < m_drawRepeats[i]; ++j)
2065                 draw(*cmdBuffer);
2066 
2067             commandClearAttachment(vk, *cmdBuffer);
2068             vk.cmdEndQuery(*cmdBuffer, *queryPool, i);
2069         }
2070 
2071         endRenderPass(vk, *cmdBuffer);
2072 
2073         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
2074             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2075         {
2076             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
2077             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2078 
2079             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2080             {
2081                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2082                 stride *= 2u;
2083             }
2084 
2085             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2086             {
2087                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2088                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2089                 stride = sizeof(ValueAndAvailability);
2090             }
2091 
2092             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2093             vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery,
2094                                        stride, flags);
2095 
2096             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
2097                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2098 
2099             const VkBufferMemoryBarrier barrier = {
2100                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
2101                 DE_NULL,                                 //  const void* pNext;
2102                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
2103                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
2104                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
2105                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
2106                 m_resetBuffer->object(),                 //  VkBuffer buffer;
2107                 0u,                                      //  VkDeviceSize offset;
2108                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
2109             };
2110             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2111                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
2112                                   (const VkImageMemoryBarrier *)DE_NULL);
2113         }
2114 
2115         if (!m_parametersGraphic.noColorAttachments)
2116             transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
2117                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2118                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2119                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2120     }
2121     endCommandBuffer(vk, *cmdBuffer);
2122 
2123     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2124         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2125 
2126     // Wait for completion
2127     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2128     return checkResult(*queryPool);
2129 }
2130 
checkResult(VkQueryPool queryPool)2131 tcu::TestStatus VertexShaderTestInstance::checkResult(VkQueryPool queryPool)
2132 {
2133     const DeviceInterface &vk = m_context.getDeviceInterface();
2134     const VkDevice device     = m_context.getDevice();
2135     uint64_t expectedMin      = 0u;
2136 
2137     switch (m_parametersGraphic.queryStatisticFlags)
2138     {
2139     case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT:
2140         expectedMin = 16u;
2141         break;
2142     case VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT:
2143         expectedMin = m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST             ? 15u :
2144                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY  ? 8u :
2145                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ? 14u :
2146                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ? 6u :
2147                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY ?
2148                                                                                                                     8u :
2149                                                                                                                     16u;
2150         break;
2151     case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT:
2152         expectedMin = m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST                ? 16u :
2153                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST                 ? 8u :
2154                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP                ? 15u :
2155                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST             ? 5u :
2156                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP            ? 8u :
2157                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN              ? 14u :
2158                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY  ? 4u :
2159                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ? 13u :
2160                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ? 2u :
2161                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY ?
2162                                                                                                                     6u :
2163                                                                                                                     0u;
2164         break;
2165     case VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT:
2166         expectedMin =
2167             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST                    ? 9u :
2168             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST                     ? 192u :
2169             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP                    ? 448u :
2170             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST                 ? 2016u :
2171             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP                ? 4096u :
2172             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN                  ? 10208u :
2173             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY      ? 128u :
2174             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY     ? 416u :
2175             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY  ? 992u :
2176             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY ? 3072u :
2177                                                                                                            0u;
2178         break;
2179     default:
2180         DE_FATAL("Unexpected type of statistics query");
2181         break;
2182     }
2183 
2184     const uint32_t queryCount = static_cast<uint32_t>(m_drawRepeats.size());
2185 
2186     if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL || m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
2187     {
2188         ResultsVector results(queryCount, 0u);
2189 
2190         if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2191         {
2192             const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
2193             cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount,
2194                                           (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags()),
2195                                           m_parametersGraphic.dstOffset);
2196         }
2197         else
2198         {
2199             VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
2200                                                (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
2201         }
2202 
2203         if (results[0] < expectedMin)
2204             return tcu::TestStatus::fail("QueryPoolResults incorrect");
2205         if (queryCount > 1)
2206         {
2207             double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2208             if (fabs(pearson) < 0.8)
2209                 return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2210         }
2211     }
2212     else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2213     {
2214         ResultsVectorWithAvailability results(queryCount, pair<uint64_t, uint64_t>(0u, 0u));
2215 
2216         if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2217         {
2218             const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
2219             cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount,
2220                                           (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() |
2221                                            VK_QUERY_RESULT_WITH_AVAILABILITY_BIT),
2222                                           m_parametersGraphic.dstOffset);
2223         }
2224         else
2225         {
2226             VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
2227                                                (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() |
2228                                                 VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
2229         }
2230 
2231         if (results[0].first < expectedMin || results[0].second == 0)
2232             return tcu::TestStatus::fail("QueryPoolResults incorrect");
2233 
2234         if (queryCount > 1)
2235         {
2236             double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2237             if (fabs(pearson) < 0.8)
2238                 return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2239         }
2240 
2241         uint64_t temp = results[0].first;
2242 
2243         vk.resetQueryPool(device, queryPool, 0, queryCount);
2244         vk::VkResult res =
2245             GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
2246                                       (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
2247         /* From Vulkan spec:
2248          *
2249          * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
2250          * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
2251          * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
2252          */
2253         if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0)
2254             return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
2255     }
2256     else
2257     {
2258         // With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
2259         return verifyUnavailable();
2260     }
2261 
2262     // Don't need to check the result image when clearing operations are executed.
2263     if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP &&
2264         m_parametersGraphic.clearOp == CLEAR_NOOP && !m_parametersGraphic.noColorAttachments && !checkImage())
2265         return tcu::TestStatus::fail("Result image doesn't match expected image.");
2266 
2267     return tcu::TestStatus::pass("Pass");
2268 }
2269 
draw(VkCommandBuffer cmdBuffer)2270 void VertexShaderTestInstance::draw(VkCommandBuffer cmdBuffer)
2271 {
2272     const DeviceInterface &vk = m_context.getDeviceInterface();
2273     switch (m_parametersGraphic.primitiveTopology)
2274     {
2275     case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
2276     case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
2277     case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
2278     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2279     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2280     case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
2281     case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
2282     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
2283     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
2284         vk.cmdDraw(cmdBuffer, 16u, 1u, 0u, 0u);
2285         break;
2286     case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2287         vk.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
2288         vk.cmdDraw(cmdBuffer, 4u, 1u, 4u, 1u);
2289         vk.cmdDraw(cmdBuffer, 4u, 1u, 8u, 2u);
2290         vk.cmdDraw(cmdBuffer, 4u, 1u, 12u, 3u);
2291         break;
2292     default:
2293         DE_ASSERT(0);
2294         break;
2295     }
2296 }
2297 
2298 class VertexShaderSecondaryTestInstance : public VertexShaderTestInstance
2299 {
2300 public:
2301     VertexShaderSecondaryTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
2302                                       const ParametersGraphic &parametersGraphic,
2303                                       const std::vector<uint64_t> &drawRepeats);
2304 
2305 protected:
2306     virtual tcu::TestStatus executeTest(void);
2307 };
2308 
VertexShaderSecondaryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)2309 VertexShaderSecondaryTestInstance::VertexShaderSecondaryTestInstance(vkt::Context &context,
2310                                                                      const std::vector<VertexData> &data,
2311                                                                      const ParametersGraphic &parametersGraphic,
2312                                                                      const std::vector<uint64_t> &drawRepeats)
2313     : VertexShaderTestInstance(context, data, parametersGraphic, drawRepeats)
2314 {
2315 }
2316 
2317 typedef de::SharedPtr<vk::Unique<VkCommandBuffer>> VkCommandBufferSp;
2318 
executeTest(void)2319 tcu::TestStatus VertexShaderSecondaryTestInstance::executeTest(void)
2320 {
2321     const DeviceInterface &vk       = m_context.getDeviceInterface();
2322     const VkDevice device           = m_context.getDevice();
2323     const VkQueue queue             = m_context.getUniversalQueue();
2324     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2325 
2326     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
2327     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
2328     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
2329     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2330 
2331     const VkDeviceSize vertexBufferOffset = 0u;
2332     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
2333     const VkBuffer vertexBuffer           = vertexBufferSp->object();
2334 
2335     const Unique<VkCommandBuffer> primaryCmdBuffer(
2336         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2337     std::vector<VkCommandBufferSp> secondaryCmdBuffers(queryCount);
2338 
2339     for (uint32_t i = 0; i < queryCount; ++i)
2340         secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(
2341             allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
2342 
2343     for (uint32_t i = 0; i < queryCount; ++i)
2344     {
2345         beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags,
2346                                     *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2347         vk.cmdBeginQuery(secondaryCmdBuffers[i]->get(), *queryPool, i, (VkQueryControlFlags)0u);
2348         vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2349         vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2350         for (uint32_t j = 0; j < m_drawRepeats[i]; ++j)
2351             draw(secondaryCmdBuffers[i]->get());
2352         commandClearAttachment(vk, secondaryCmdBuffers[i]->get());
2353         vk.cmdEndQuery(secondaryCmdBuffers[i]->get(), *queryPool, i);
2354         endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
2355     }
2356 
2357     beginCommandBuffer(vk, *primaryCmdBuffer);
2358     {
2359         std::vector<VkClearValue> renderPassClearValues(2);
2360         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2361 
2362         if (!m_parametersGraphic.noColorAttachments)
2363             initialTransitionColor2DImage(
2364                 vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2365                 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2366 
2367         initialTransitionDepth2DImage(
2368             vk, *primaryCmdBuffer, m_depthImage->object(), vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2369             vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
2370             vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2371 
2372         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2373             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2374 
2375         beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
2376                         (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0],
2377                         VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
2378         for (uint32_t i = 0; i < queryCount; ++i)
2379             vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
2380         endRenderPass(vk, *primaryCmdBuffer);
2381 
2382         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
2383             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2384         {
2385             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
2386             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2387 
2388             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2389             {
2390                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2391                 stride *= 2u;
2392             }
2393 
2394             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2395             {
2396                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2397                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2398                 stride = sizeof(ValueAndAvailability);
2399             }
2400 
2401             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2402             vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(),
2403                                        dstOffsetQuery, stride, flags);
2404 
2405             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
2406                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2407 
2408             const VkBufferMemoryBarrier barrier = {
2409                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
2410                 DE_NULL,                                 //  const void* pNext;
2411                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
2412                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
2413                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
2414                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
2415                 m_resetBuffer->object(),                 //  VkBuffer buffer;
2416                 0u,                                      //  VkDeviceSize offset;
2417                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
2418             };
2419             vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2420                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
2421                                   (const VkImageMemoryBarrier *)DE_NULL);
2422         }
2423 
2424         if (!m_parametersGraphic.noColorAttachments)
2425             transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
2426                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2427                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2428                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2429     }
2430     endCommandBuffer(vk, *primaryCmdBuffer);
2431 
2432     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2433         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2434 
2435     // Wait for completion
2436     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
2437     return checkResult(*queryPool);
2438 }
2439 
2440 class VertexShaderSecondaryInheritedTestInstance : public VertexShaderTestInstance
2441 {
2442 public:
2443     VertexShaderSecondaryInheritedTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
2444                                                const ParametersGraphic &parametersGraphic,
2445                                                const std::vector<uint64_t> &drawRepeats);
2446 
2447 protected:
2448     virtual void checkExtensions(bool hostQueryResetEnabled);
2449     virtual tcu::TestStatus executeTest(void);
2450 };
2451 
VertexShaderSecondaryInheritedTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)2452 VertexShaderSecondaryInheritedTestInstance::VertexShaderSecondaryInheritedTestInstance(
2453     vkt::Context &context, const std::vector<VertexData> &data, const ParametersGraphic &parametersGraphic,
2454     const std::vector<uint64_t> &drawRepeats)
2455     : VertexShaderTestInstance(context, data, parametersGraphic, drawRepeats)
2456 {
2457 }
2458 
checkExtensions(bool hostQueryResetEnabled)2459 void VertexShaderSecondaryInheritedTestInstance::checkExtensions(bool hostQueryResetEnabled)
2460 {
2461     StatisticQueryTestInstance::checkExtensions(hostQueryResetEnabled);
2462     if (!m_context.getDeviceFeatures().inheritedQueries)
2463         throw tcu::NotSupportedError("Inherited queries are not supported");
2464 }
2465 
executeTest(void)2466 tcu::TestStatus VertexShaderSecondaryInheritedTestInstance::executeTest(void)
2467 {
2468     const DeviceInterface &vk       = m_context.getDeviceInterface();
2469     const VkDevice device           = m_context.getDevice();
2470     const VkQueue queue             = m_context.getUniversalQueue();
2471     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2472 
2473     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
2474     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
2475     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
2476     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2477 
2478     const VkDeviceSize vertexBufferOffset = 0u;
2479     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
2480     const VkBuffer vertexBuffer           = vertexBufferSp->object();
2481 
2482     const Unique<VkCommandBuffer> primaryCmdBuffer(
2483         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2484     std::vector<VkCommandBufferSp> secondaryCmdBuffers(queryCount);
2485 
2486     for (uint32_t i = 0; i < queryCount; ++i)
2487         secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(
2488             allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
2489 
2490     for (uint32_t i = 0; i < queryCount; ++i)
2491     {
2492         beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags,
2493                                     *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2494         vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2495         vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2496         for (uint32_t j = 0; j < m_drawRepeats[i]; ++j)
2497             draw(secondaryCmdBuffers[i]->get());
2498         endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
2499     }
2500 
2501     beginCommandBuffer(vk, *primaryCmdBuffer);
2502     {
2503         std::vector<VkClearValue> renderPassClearValues(2);
2504         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2505 
2506         if (!m_parametersGraphic.noColorAttachments)
2507             initialTransitionColor2DImage(
2508                 vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2509                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2510         initialTransitionDepth2DImage(
2511             vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2512             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
2513             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2514 
2515         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2516             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2517 
2518         for (uint32_t i = 0; i < queryCount; ++i)
2519         {
2520             vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
2521             beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
2522                             (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0],
2523                             VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
2524             vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
2525             endRenderPass(vk, *primaryCmdBuffer);
2526             vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, i);
2527         }
2528 
2529         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
2530             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2531         {
2532             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
2533             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2534 
2535             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2536             {
2537                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2538                 stride *= 2u;
2539             }
2540 
2541             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2542             {
2543                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2544                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2545                 stride = sizeof(ValueAndAvailability);
2546             }
2547 
2548             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2549             vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(),
2550                                        dstOffsetQuery, stride, flags);
2551 
2552             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
2553                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
2554 
2555             const VkBufferMemoryBarrier barrier = {
2556                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
2557                 DE_NULL,                                 //  const void* pNext;
2558                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
2559                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
2560                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
2561                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
2562                 m_resetBuffer->object(),                 //  VkBuffer buffer;
2563                 0u,                                      //  VkDeviceSize offset;
2564                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
2565             };
2566             vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2567                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
2568                                   (const VkImageMemoryBarrier *)DE_NULL);
2569         }
2570 
2571         if (!m_parametersGraphic.noColorAttachments)
2572             transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
2573                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2574                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2575                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2576     }
2577     endCommandBuffer(vk, *primaryCmdBuffer);
2578 
2579     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2580         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2581 
2582     // Wait for completion
2583     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
2584     return checkResult(*queryPool);
2585 }
2586 
2587 class GeometryShaderTestInstance : public GraphicBasicTestInstance
2588 {
2589 public:
2590     GeometryShaderTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
2591                                const ParametersGraphic &parametersGraphic, const std::vector<uint64_t> &drawRepeats);
2592 
2593 protected:
2594     virtual void checkExtensions(bool hostQueryResetEnabled);
2595     virtual void createPipeline(void);
2596     virtual tcu::TestStatus executeTest(void);
2597     tcu::TestStatus checkResult(VkQueryPool queryPool);
2598     void draw(VkCommandBuffer cmdBuffer);
2599 };
2600 
GeometryShaderTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)2601 GeometryShaderTestInstance::GeometryShaderTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
2602                                                        const ParametersGraphic &parametersGraphic,
2603                                                        const std::vector<uint64_t> &drawRepeats)
2604     : GraphicBasicTestInstance(context, data, parametersGraphic, drawRepeats)
2605 {
2606 }
2607 
checkExtensions(bool hostQueryResetEnabled)2608 void GeometryShaderTestInstance::checkExtensions(bool hostQueryResetEnabled)
2609 {
2610     StatisticQueryTestInstance::checkExtensions(hostQueryResetEnabled);
2611     if (!m_context.getDeviceFeatures().geometryShader)
2612         throw tcu::NotSupportedError("Geometry shader are not supported");
2613 }
2614 
createPipeline(void)2615 void GeometryShaderTestInstance::createPipeline(void)
2616 {
2617     const DeviceInterface &vk       = m_context.getDeviceInterface();
2618     const VkDevice device           = m_context.getDevice();
2619     const VkBool32 useGeomPointSize = m_context.getDeviceFeatures().shaderTessellationAndGeometryPointSize &&
2620                                       (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
2621 
2622     // Pipeline
2623     Unique<VkShaderModule> vs(
2624         createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), (VkShaderModuleCreateFlags)0));
2625     Unique<VkShaderModule> gs(createShaderModule(
2626         vk, device, m_context.getBinaryCollection().get(useGeomPointSize ? "geometry_point_size" : "geometry"),
2627         (VkShaderModuleCreateFlags)0));
2628     Unique<VkShaderModule> fs(
2629         createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), (VkShaderModuleCreateFlags)0));
2630 
2631     const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
2632 
2633     const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
2634     m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
2635 
2636     const VkVertexInputBindingDescription vertexInputBindingDescription = {
2637         0u,                                        // binding;
2638         static_cast<uint32_t>(sizeof(VertexData)), // stride;
2639         VK_VERTEX_INPUT_RATE_VERTEX                // inputRate
2640     };
2641 
2642     const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
2643         {0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u}, // VertexElementData::position
2644         {1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, static_cast<uint32_t>(sizeof(tcu::Vec4))}, // VertexElementData::color
2645     };
2646 
2647     const VkPipelineVertexInputStateCreateInfo vf_info = {
2648         // sType;
2649         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // pNext;
2650         NULL,                                                      // flags;
2651         0u,                                                        // vertexBindingDescriptionCount;
2652         1,                                                         // pVertexBindingDescriptions;
2653         &vertexInputBindingDescription,                            // vertexAttributeDescriptionCount;
2654         2,                                                         // pVertexAttributeDescriptions;
2655         vertexInputAttributeDescriptions};
2656 
2657     PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
2658     pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
2659     pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*gs, "main", VK_SHADER_STAGE_GEOMETRY_BIT));
2660     pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
2661     pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_parametersGraphic.primitiveTopology));
2662     pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
2663 
2664     const VkViewport viewport = makeViewport(WIDTH, HEIGHT);
2665     const VkRect2D scissor    = makeRect2D(WIDTH, HEIGHT);
2666 
2667     pipelineCreateInfo.addState(
2668         PipelineCreateInfo::ViewportState(1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
2669 
2670     if (m_context.getDeviceFeatures().depthBounds)
2671         pipelineCreateInfo.addState(
2672             PipelineCreateInfo::DepthStencilState(true, true, VK_COMPARE_OP_GREATER_OR_EQUAL, true));
2673     else
2674         pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
2675 
2676     pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState(false));
2677     pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
2678     pipelineCreateInfo.addState(vf_info);
2679     m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
2680 }
2681 
executeTest(void)2682 tcu::TestStatus GeometryShaderTestInstance::executeTest(void)
2683 {
2684     const DeviceInterface &vk       = m_context.getDeviceInterface();
2685     const VkDevice device           = m_context.getDevice();
2686     const VkQueue queue             = m_context.getUniversalQueue();
2687     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2688 
2689     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
2690     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
2691     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
2692     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2693 
2694     const VkDeviceSize vertexBufferOffset = 0u;
2695     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
2696     const VkBuffer vertexBuffer           = vertexBufferSp->object();
2697 
2698     const Unique<VkCommandBuffer> cmdBuffer(
2699         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2700 
2701     beginCommandBuffer(vk, *cmdBuffer);
2702     {
2703         std::vector<VkClearValue> renderPassClearValues(2);
2704         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2705 
2706         if (!m_parametersGraphic.noColorAttachments)
2707             initialTransitionColor2DImage(
2708                 vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2709                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2710 
2711         initialTransitionDepth2DImage(
2712             vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2713             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
2714             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2715 
2716         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
2717             vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2718 
2719         beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
2720                         (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0]);
2721 
2722         for (uint32_t i = 0; i < queryCount; ++i)
2723         {
2724             vk.cmdBeginQuery(*cmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
2725             vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
2726             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2727 
2728             for (uint64_t j = 0; j < m_drawRepeats[i]; ++j)
2729                 draw(*cmdBuffer);
2730 
2731             vk.cmdEndQuery(*cmdBuffer, *queryPool, i);
2732         }
2733 
2734         endRenderPass(vk, *cmdBuffer);
2735 
2736         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
2737             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
2738         {
2739             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
2740             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
2741 
2742             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2743             {
2744                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2745                 stride *= 2u;
2746             }
2747 
2748             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
2749             {
2750                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2751                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
2752                 stride = sizeof(ValueAndAvailability);
2753             }
2754 
2755             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
2756             vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery,
2757                                        stride, flags);
2758 
2759             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
2760                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
2761 
2762             const VkBufferMemoryBarrier barrier = {
2763                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
2764                 DE_NULL,                                 //  const void* pNext;
2765                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
2766                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
2767                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
2768                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
2769                 m_resetBuffer->object(),                 //  VkBuffer buffer;
2770                 0u,                                      //  VkDeviceSize offset;
2771                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
2772             };
2773             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2774                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
2775                                   (const VkImageMemoryBarrier *)DE_NULL);
2776         }
2777 
2778         if (!m_parametersGraphic.noColorAttachments)
2779             transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
2780                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2781                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2782                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2783     }
2784     endCommandBuffer(vk, *cmdBuffer);
2785 
2786     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2787         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
2788 
2789     // Wait for completion
2790     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2791     return checkResult(*queryPool);
2792 }
2793 
checkResult(VkQueryPool queryPool)2794 tcu::TestStatus GeometryShaderTestInstance::checkResult(VkQueryPool queryPool)
2795 {
2796     const DeviceInterface &vk = m_context.getDeviceInterface();
2797     const VkDevice device     = m_context.getDevice();
2798     uint64_t expectedMin      = 0u;
2799 
2800     switch (m_parametersGraphic.queryStatisticFlags)
2801     {
2802     case VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT:
2803         expectedMin = m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST                ? 16u :
2804                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST                 ? 8u :
2805                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP                ? 15u :
2806                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST             ? 4u :
2807                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP            ? 4u :
2808                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN              ? 14u :
2809                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY  ? 4u :
2810                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ? 13u :
2811                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ? 2u :
2812                       m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY ?
2813                                                                                                                     6u :
2814                                                                                                                     0u;
2815         break;
2816     case VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT:
2817     case VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT:
2818     case VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT:
2819         expectedMin =
2820             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST                    ? 112u :
2821             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST                     ? 32u :
2822             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP                    ? 60u :
2823             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST                 ? 8u :
2824             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP                ? 8u :
2825             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN                  ? 28u :
2826             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY      ? 16u :
2827             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY     ? 52u :
2828             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY  ? 4u :
2829             m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY ? 12u :
2830                                                                                                            0u;
2831         break;
2832     default:
2833         DE_FATAL("Unexpected type of statistics query");
2834         break;
2835     }
2836 
2837     const uint32_t queryCount = static_cast<uint32_t>(m_drawRepeats.size());
2838 
2839     if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL || m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
2840     {
2841         ResultsVector results(queryCount, 0u);
2842 
2843         if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2844         {
2845             const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
2846             cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount,
2847                                           (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags()),
2848                                           m_parametersGraphic.dstOffset);
2849         }
2850         else
2851         {
2852             VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
2853                                                (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
2854         }
2855 
2856         if (results[0] < expectedMin)
2857             return tcu::TestStatus::fail("QueryPoolResults incorrect");
2858         if (queryCount > 1)
2859         {
2860             double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2861             if (fabs(pearson) < 0.8)
2862                 return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2863         }
2864     }
2865     else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
2866     {
2867         ResultsVectorWithAvailability results(queryCount, pair<uint64_t, uint64_t>(0u, 0u));
2868         if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
2869         {
2870             const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
2871             cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount,
2872                                           (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() |
2873                                            VK_QUERY_RESULT_WITH_AVAILABILITY_BIT),
2874                                           m_parametersGraphic.dstOffset);
2875         }
2876         else
2877         {
2878             VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
2879                                                (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() |
2880                                                 VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
2881         }
2882 
2883         if (results[0].first < expectedMin || results[0].second == 0u)
2884             return tcu::TestStatus::fail("QueryPoolResults incorrect");
2885 
2886         if (queryCount > 1)
2887         {
2888             double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
2889             if (fabs(pearson) < 0.8)
2890                 return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
2891         }
2892 
2893         uint64_t temp = results[0].first;
2894 
2895         vk.resetQueryPool(device, queryPool, 0, queryCount);
2896         vk::VkResult res =
2897             GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
2898                                       (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
2899         /* From Vulkan spec:
2900          *
2901          * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
2902          * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
2903          * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
2904          */
2905         if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0u)
2906             return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
2907     }
2908     else
2909     {
2910         // With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
2911         return verifyUnavailable();
2912     }
2913 
2914     if ((m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST ||
2915          m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) &&
2916         !checkImage())
2917         return tcu::TestStatus::fail("Result image doesn't match expected image.");
2918 
2919     return tcu::TestStatus::pass("Pass");
2920 }
2921 
draw(VkCommandBuffer cmdBuffer)2922 void GeometryShaderTestInstance::draw(VkCommandBuffer cmdBuffer)
2923 {
2924     const DeviceInterface &vk = m_context.getDeviceInterface();
2925     if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
2926         m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
2927     {
2928         vk.cmdDraw(cmdBuffer, 3u, 1u, 0u, 1u);
2929         vk.cmdDraw(cmdBuffer, 3u, 1u, 4u, 1u);
2930         vk.cmdDraw(cmdBuffer, 3u, 1u, 8u, 2u);
2931         vk.cmdDraw(cmdBuffer, 3u, 1u, 12u, 3u);
2932     }
2933     else
2934     {
2935         vk.cmdDraw(cmdBuffer, 16u, 1u, 0u, 0u);
2936     }
2937 }
2938 
2939 class GeometryShaderSecondaryTestInstance : public GeometryShaderTestInstance
2940 {
2941 public:
2942     GeometryShaderSecondaryTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
2943                                         const ParametersGraphic &parametersGraphic,
2944                                         const std::vector<uint64_t> &drawRepeats);
2945 
2946 protected:
2947     virtual tcu::TestStatus executeTest(void);
2948 };
2949 
GeometryShaderSecondaryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)2950 GeometryShaderSecondaryTestInstance::GeometryShaderSecondaryTestInstance(vkt::Context &context,
2951                                                                          const std::vector<VertexData> &data,
2952                                                                          const ParametersGraphic &parametersGraphic,
2953                                                                          const std::vector<uint64_t> &drawRepeats)
2954     : GeometryShaderTestInstance(context, data, parametersGraphic, drawRepeats)
2955 {
2956 }
2957 
executeTest(void)2958 tcu::TestStatus GeometryShaderSecondaryTestInstance::executeTest(void)
2959 {
2960     const DeviceInterface &vk       = m_context.getDeviceInterface();
2961     const VkDevice device           = m_context.getDevice();
2962     const VkQueue queue             = m_context.getUniversalQueue();
2963     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2964 
2965     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
2966     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
2967     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
2968     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
2969 
2970     const VkDeviceSize vertexBufferOffset = 0;
2971     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
2972     const VkBuffer vertexBuffer           = vertexBufferSp->object();
2973 
2974     const Unique<VkCommandBuffer> primaryCmdBuffer(
2975         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2976     std::vector<VkCommandBufferSp> secondaryCmdBuffers(queryCount);
2977 
2978     for (uint32_t i = 0; i < queryCount; ++i)
2979         secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(
2980             allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
2981 
2982     for (uint32_t i = 0; i < queryCount; ++i)
2983     {
2984         beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags,
2985                                     *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
2986         vk.cmdBeginQuery(secondaryCmdBuffers[i]->get(), *queryPool, i, (VkQueryControlFlags)0u);
2987         vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2988         vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
2989         for (uint32_t j = 0; j < m_drawRepeats[i]; ++j)
2990             draw(secondaryCmdBuffers[i]->get());
2991         vk.cmdEndQuery(secondaryCmdBuffers[i]->get(), *queryPool, i);
2992         endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
2993     }
2994 
2995     beginCommandBuffer(vk, *primaryCmdBuffer);
2996     {
2997         std::vector<VkClearValue> renderPassClearValues(2);
2998         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
2999 
3000         if (!m_parametersGraphic.noColorAttachments)
3001             initialTransitionColor2DImage(
3002                 vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3003                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
3004 
3005         initialTransitionDepth2DImage(
3006             vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3007             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
3008             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3009 
3010         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
3011             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3012         beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
3013                         (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0],
3014                         VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
3015         for (uint32_t i = 0; i < queryCount; ++i)
3016             vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
3017         endRenderPass(vk, *primaryCmdBuffer);
3018 
3019         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
3020             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
3021         {
3022             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
3023             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
3024 
3025             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3026             {
3027                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3028                 stride *= 2u;
3029             }
3030 
3031             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
3032             {
3033                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3034                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3035                 stride = sizeof(ValueAndAvailability);
3036             }
3037 
3038             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
3039             vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(),
3040                                        dstOffsetQuery, stride, flags);
3041 
3042             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
3043                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3044 
3045             const VkBufferMemoryBarrier barrier = {
3046                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
3047                 DE_NULL,                                 //  const void* pNext;
3048                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
3049                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
3050                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
3051                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
3052                 m_resetBuffer->object(),                 //  VkBuffer buffer;
3053                 0u,                                      //  VkDeviceSize offset;
3054                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
3055             };
3056             vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
3057                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
3058                                   (const VkImageMemoryBarrier *)DE_NULL);
3059         }
3060 
3061         if (!m_parametersGraphic.noColorAttachments)
3062             transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
3063                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
3064                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3065                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3066     }
3067     endCommandBuffer(vk, *primaryCmdBuffer);
3068 
3069     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3070         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
3071 
3072     // Wait for completion
3073     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
3074     return checkResult(*queryPool);
3075 }
3076 
3077 class GeometryShaderSecondaryInheritedTestInstance : public GeometryShaderTestInstance
3078 {
3079 public:
3080     GeometryShaderSecondaryInheritedTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
3081                                                  const ParametersGraphic &parametersGraphic,
3082                                                  const std::vector<uint64_t> &drawRepeats);
3083 
3084 protected:
3085     virtual void checkExtensions(bool hostQueryResetEnabled);
3086     virtual tcu::TestStatus executeTest(void);
3087 };
3088 
GeometryShaderSecondaryInheritedTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)3089 GeometryShaderSecondaryInheritedTestInstance::GeometryShaderSecondaryInheritedTestInstance(
3090     vkt::Context &context, const std::vector<VertexData> &data, const ParametersGraphic &parametersGraphic,
3091     const std::vector<uint64_t> &drawRepeats)
3092     : GeometryShaderTestInstance(context, data, parametersGraphic, drawRepeats)
3093 {
3094 }
3095 
checkExtensions(bool hostQueryResetEnabled)3096 void GeometryShaderSecondaryInheritedTestInstance::checkExtensions(bool hostQueryResetEnabled)
3097 {
3098     GeometryShaderTestInstance::checkExtensions(hostQueryResetEnabled);
3099     if (!m_context.getDeviceFeatures().inheritedQueries)
3100         throw tcu::NotSupportedError("Inherited queries are not supported");
3101 }
3102 
executeTest(void)3103 tcu::TestStatus GeometryShaderSecondaryInheritedTestInstance::executeTest(void)
3104 {
3105     const DeviceInterface &vk       = m_context.getDeviceInterface();
3106     const VkDevice device           = m_context.getDevice();
3107     const VkQueue queue             = m_context.getUniversalQueue();
3108     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3109 
3110     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
3111     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
3112     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
3113     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
3114 
3115     const VkDeviceSize vertexBufferOffset = 0u;
3116     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
3117     const VkBuffer vertexBuffer           = vertexBufferSp->object();
3118 
3119     const Unique<VkCommandBuffer> primaryCmdBuffer(
3120         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3121     std::vector<VkCommandBufferSp> secondaryCmdBuffers(queryCount);
3122 
3123     for (uint32_t i = 0; i < queryCount; ++i)
3124         secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(
3125             allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
3126 
3127     for (uint32_t i = 0; i < queryCount; ++i)
3128     {
3129         beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags,
3130                                     *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
3131         vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3132         vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
3133         for (uint32_t j = 0; j < m_drawRepeats[i]; ++j)
3134             draw(secondaryCmdBuffers[i]->get());
3135         endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
3136     }
3137 
3138     beginCommandBuffer(vk, *primaryCmdBuffer);
3139     {
3140         std::vector<VkClearValue> renderPassClearValues(2);
3141         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
3142 
3143         if (!m_parametersGraphic.noColorAttachments)
3144             initialTransitionColor2DImage(
3145                 vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3146                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
3147 
3148         initialTransitionDepth2DImage(
3149             vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3150             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
3151             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3152 
3153         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
3154             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3155 
3156         for (uint32_t i = 0; i < queryCount; ++i)
3157         {
3158             vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
3159             beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
3160                             (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0],
3161                             VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
3162             vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
3163             endRenderPass(vk, *primaryCmdBuffer);
3164             vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, i);
3165         }
3166 
3167         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
3168             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
3169         {
3170             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
3171             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
3172 
3173             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3174             {
3175                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3176                 stride *= 2u;
3177             }
3178 
3179             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
3180             {
3181                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3182                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3183                 stride = sizeof(ValueAndAvailability);
3184             }
3185 
3186             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
3187             vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(),
3188                                        dstOffsetQuery, stride, flags);
3189 
3190             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
3191                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3192 
3193             const VkBufferMemoryBarrier barrier = {
3194                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
3195                 DE_NULL,                                 //  const void* pNext;
3196                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
3197                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
3198                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
3199                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
3200                 m_resetBuffer->object(),                 //  VkBuffer buffer;
3201                 0u,                                      //  VkDeviceSize offset;
3202                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
3203             };
3204             vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
3205                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
3206                                   (const VkImageMemoryBarrier *)DE_NULL);
3207         }
3208 
3209         if (!m_parametersGraphic.noColorAttachments)
3210             transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
3211                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
3212                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3213                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3214     }
3215     endCommandBuffer(vk, *primaryCmdBuffer);
3216 
3217     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3218         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
3219 
3220     // Wait for completion
3221     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
3222     return checkResult(*queryPool);
3223 }
3224 
3225 class TessellationShaderTestInstance : public GraphicBasicTestInstance
3226 {
3227 public:
3228     TessellationShaderTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
3229                                    const ParametersGraphic &parametersGraphic,
3230                                    const std::vector<uint64_t> &drawRepeats);
3231 
3232 protected:
3233     virtual void checkExtensions(bool hostQueryResetEnabled);
3234     virtual void createPipeline(void);
3235     virtual tcu::TestStatus executeTest(void);
3236     virtual tcu::TestStatus checkResult(VkQueryPool queryPool);
3237     void draw(VkCommandBuffer cmdBuffer);
3238 };
3239 
TessellationShaderTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)3240 TessellationShaderTestInstance::TessellationShaderTestInstance(vkt::Context &context,
3241                                                                const std::vector<VertexData> &data,
3242                                                                const ParametersGraphic &parametersGraphic,
3243                                                                const std::vector<uint64_t> &drawRepeats)
3244     : GraphicBasicTestInstance(context, data, parametersGraphic, drawRepeats)
3245 {
3246 }
3247 
checkExtensions(bool hostQueryResetEnabled)3248 void TessellationShaderTestInstance::checkExtensions(bool hostQueryResetEnabled)
3249 {
3250     StatisticQueryTestInstance::checkExtensions(hostQueryResetEnabled);
3251     if (!m_context.getDeviceFeatures().tessellationShader)
3252         throw tcu::NotSupportedError("Tessellation shader are not supported");
3253 }
3254 
createPipeline(void)3255 void TessellationShaderTestInstance::createPipeline(void)
3256 {
3257     const DeviceInterface &vk = m_context.getDeviceInterface();
3258     const VkDevice device     = m_context.getDevice();
3259 
3260     // Pipeline
3261     Unique<VkShaderModule> vs(
3262         createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), (VkShaderModuleCreateFlags)0));
3263     Unique<VkShaderModule> tc(createShaderModule(
3264         vk, device, m_context.getBinaryCollection().get("tessellation_control"), (VkShaderModuleCreateFlags)0));
3265     Unique<VkShaderModule> te(createShaderModule(
3266         vk, device, m_context.getBinaryCollection().get("tessellation_evaluation"), (VkShaderModuleCreateFlags)0));
3267     Unique<VkShaderModule> fs(
3268         createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), (VkShaderModuleCreateFlags)0));
3269 
3270     const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
3271 
3272     const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
3273     m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
3274 
3275     const VkVertexInputBindingDescription vertexInputBindingDescription = {
3276         0u,                                        // binding;
3277         static_cast<uint32_t>(sizeof(VertexData)), // stride;
3278         VK_VERTEX_INPUT_RATE_VERTEX                // inputRate
3279     };
3280 
3281     const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
3282         {0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u}, // VertexElementData::position
3283         {1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, static_cast<uint32_t>(sizeof(tcu::Vec4))}, // VertexElementData::color
3284     };
3285 
3286     const VkPipelineVertexInputStateCreateInfo vf_info = {
3287         // sType;
3288         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // pNext;
3289         NULL,                                                      // flags;
3290         0u,                                                        // vertexBindingDescriptionCount;
3291         1u,                                                        // pVertexBindingDescriptions;
3292         &vertexInputBindingDescription,                            // vertexAttributeDescriptionCount;
3293         2u,                                                        // pVertexAttributeDescriptions;
3294         vertexInputAttributeDescriptions};
3295 
3296     PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
3297     pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
3298     pipelineCreateInfo.addShader(
3299         PipelineCreateInfo::PipelineShaderStage(*tc, "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3300     pipelineCreateInfo.addShader(
3301         PipelineCreateInfo::PipelineShaderStage(*te, "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
3302     pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
3303     pipelineCreateInfo.addState(PipelineCreateInfo::TessellationState(4));
3304     pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST));
3305     pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
3306 
3307     const VkViewport viewport = makeViewport(WIDTH, HEIGHT);
3308     const VkRect2D scissor    = makeRect2D(WIDTH, HEIGHT);
3309 
3310     pipelineCreateInfo.addState(
3311         PipelineCreateInfo::ViewportState(1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
3312     pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
3313     pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
3314     pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
3315     pipelineCreateInfo.addState(vf_info);
3316     m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
3317 }
3318 
executeTest(void)3319 tcu::TestStatus TessellationShaderTestInstance::executeTest(void)
3320 {
3321     const DeviceInterface &vk       = m_context.getDeviceInterface();
3322     const VkDevice device           = m_context.getDevice();
3323     const VkQueue queue             = m_context.getUniversalQueue();
3324     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3325 
3326     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
3327     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
3328     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
3329     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
3330 
3331     const VkDeviceSize vertexBufferOffset = 0u;
3332     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
3333     const VkBuffer vertexBuffer           = vertexBufferSp->object();
3334 
3335     const Unique<VkCommandBuffer> cmdBuffer(
3336         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3337 
3338     beginCommandBuffer(vk, *cmdBuffer);
3339     {
3340         std::vector<VkClearValue> renderPassClearValues(2);
3341         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
3342 
3343         if (!m_parametersGraphic.noColorAttachments)
3344             initialTransitionColor2DImage(
3345                 vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3346                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
3347 
3348         initialTransitionDepth2DImage(
3349             vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3350             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
3351             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3352 
3353         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
3354             vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
3355 
3356         beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
3357                         (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0]);
3358 
3359         for (uint32_t i = 0; i < queryCount; ++i)
3360         {
3361             vk.cmdBeginQuery(*cmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
3362             vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
3363             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3364 
3365             for (uint64_t j = 0; j < m_drawRepeats[i]; ++j)
3366                 draw(*cmdBuffer);
3367 
3368             vk.cmdEndQuery(*cmdBuffer, *queryPool, i);
3369         }
3370 
3371         endRenderPass(vk, *cmdBuffer);
3372 
3373         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
3374             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
3375         {
3376             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
3377             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
3378 
3379             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3380             {
3381                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3382                 stride *= 2u;
3383             }
3384 
3385             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
3386             {
3387                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
3388                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3389                 stride = sizeof(ValueAndAvailability);
3390             }
3391 
3392             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
3393             vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(), dstOffsetQuery,
3394                                        stride, flags);
3395 
3396             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
3397                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, queryCount);
3398 
3399             const VkBufferMemoryBarrier barrier = {
3400                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
3401                 DE_NULL,                                 //  const void* pNext;
3402                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
3403                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
3404                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
3405                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
3406                 m_resetBuffer->object(),                 //  VkBuffer buffer;
3407                 0u,                                      //  VkDeviceSize offset;
3408                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
3409             };
3410             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
3411                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
3412                                   (const VkImageMemoryBarrier *)DE_NULL);
3413         }
3414 
3415         if (!m_parametersGraphic.noColorAttachments)
3416             transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
3417                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
3418                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3419                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3420     }
3421     endCommandBuffer(vk, *cmdBuffer);
3422 
3423     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3424         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
3425 
3426     // Wait for completion
3427     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
3428     return checkResult(*queryPool);
3429 }
3430 
checkResult(VkQueryPool queryPool)3431 tcu::TestStatus TessellationShaderTestInstance::checkResult(VkQueryPool queryPool)
3432 {
3433     const DeviceInterface &vk = m_context.getDeviceInterface();
3434     const VkDevice device     = m_context.getDevice();
3435     uint64_t expectedMin      = 0u;
3436 
3437     switch (m_parametersGraphic.queryStatisticFlags)
3438     {
3439     case VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT:
3440         expectedMin = 4u;
3441         break;
3442     case VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT:
3443         expectedMin = 100u;
3444         break;
3445     default:
3446         DE_FATAL("Unexpected type of statistics query");
3447         break;
3448     }
3449 
3450     const uint32_t queryCount = static_cast<uint32_t>(m_drawRepeats.size());
3451 
3452     if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL || m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
3453     {
3454         ResultsVector results(queryCount, 0u);
3455         if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
3456         {
3457             const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
3458             cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount,
3459                                           (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags()),
3460                                           m_parametersGraphic.dstOffset);
3461         }
3462         else
3463         {
3464             VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
3465                                                (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
3466         }
3467 
3468         if (results[0] < expectedMin)
3469             return tcu::TestStatus::fail("QueryPoolResults incorrect");
3470         if (queryCount > 1)
3471         {
3472             double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
3473             if (fabs(pearson) < 0.8)
3474                 return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
3475         }
3476 
3477         if (!m_parametersGraphic.noColorAttachments && !checkImage())
3478             return tcu::TestStatus::fail("Result image doesn't match expected image.");
3479     }
3480     else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3481     {
3482         ResultsVectorWithAvailability results(queryCount, pair<uint64_t, uint64_t>(0u, 0u));
3483         if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
3484         {
3485             const vk::Allocation &allocation = m_resetBuffer->getBoundMemory();
3486             cmdCopyQueryPoolResultsVector(results, vk, device, allocation, queryCount,
3487                                           (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() |
3488                                            VK_QUERY_RESULT_WITH_AVAILABILITY_BIT),
3489                                           m_parametersGraphic.dstOffset);
3490         }
3491         else
3492         {
3493             VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
3494                                                (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() |
3495                                                 VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
3496         }
3497 
3498         if (results[0].first < expectedMin || results[0].second == 0u)
3499             return tcu::TestStatus::fail("QueryPoolResults incorrect");
3500 
3501         if (queryCount > 1)
3502         {
3503             double pearson = calculatePearsonCorrelation(m_drawRepeats, results);
3504             if (fabs(pearson) < 0.8)
3505                 return tcu::TestStatus::fail("QueryPoolResults are nonlinear");
3506         }
3507 
3508         uint64_t temp = results[0].first;
3509 
3510         vk.resetQueryPool(device, queryPool, 0, queryCount);
3511         vk::VkResult res =
3512             GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount,
3513                                       (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
3514         /* From Vulkan spec:
3515          *
3516          * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
3517          * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
3518          * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
3519          */
3520         if (res != vk::VK_NOT_READY || results[0].first != temp || results[0].second != 0u)
3521             return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
3522     }
3523     else
3524     {
3525         // With RESET_TYPE_BEFORE_COPY, we only need to verify the result after the copy include an availability bit set as zero.
3526         return verifyUnavailable();
3527     }
3528     return tcu::TestStatus::pass("Pass");
3529 }
3530 
draw(VkCommandBuffer cmdBuffer)3531 void TessellationShaderTestInstance::draw(VkCommandBuffer cmdBuffer)
3532 {
3533     const DeviceInterface &vk = m_context.getDeviceInterface();
3534     vk.cmdDraw(cmdBuffer, static_cast<uint32_t>(m_data.size()), 1u, 0u, 0u);
3535 }
3536 
3537 class TessellationShaderSecondrayTestInstance : public TessellationShaderTestInstance
3538 {
3539 public:
3540     TessellationShaderSecondrayTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
3541                                             const ParametersGraphic &parametersGraphic,
3542                                             const std::vector<uint64_t> &drawRepeats);
3543 
3544 protected:
3545     virtual tcu::TestStatus executeTest(void);
3546 };
3547 
TessellationShaderSecondrayTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)3548 TessellationShaderSecondrayTestInstance::TessellationShaderSecondrayTestInstance(
3549     vkt::Context &context, const std::vector<VertexData> &data, const ParametersGraphic &parametersGraphic,
3550     const std::vector<uint64_t> &drawRepeats)
3551     : TessellationShaderTestInstance(context, data, parametersGraphic, drawRepeats)
3552 {
3553 }
3554 
executeTest(void)3555 tcu::TestStatus TessellationShaderSecondrayTestInstance::executeTest(void)
3556 {
3557     const DeviceInterface &vk       = m_context.getDeviceInterface();
3558     const VkDevice device           = m_context.getDevice();
3559     const VkQueue queue             = m_context.getUniversalQueue();
3560     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3561 
3562     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
3563     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
3564     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
3565     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
3566 
3567     const VkDeviceSize vertexBufferOffset = 0u;
3568     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
3569     const VkBuffer vertexBuffer           = vertexBufferSp->object();
3570 
3571     const Unique<VkCommandBuffer> primaryCmdBuffer(
3572         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3573     std::vector<VkCommandBufferSp> secondaryCmdBuffers(queryCount);
3574 
3575     for (uint32_t i = 0; i < queryCount; ++i)
3576         secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(
3577             allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
3578 
3579     for (uint32_t i = 0; i < queryCount; ++i)
3580     {
3581         beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags,
3582                                     *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
3583         vk.cmdBeginQuery(secondaryCmdBuffers[i]->get(), *queryPool, i, (VkQueryControlFlags)0u);
3584         vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3585         vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
3586         for (uint32_t j = 0; j < m_drawRepeats[i]; ++j)
3587             draw(secondaryCmdBuffers[i]->get());
3588         vk.cmdEndQuery(secondaryCmdBuffers[i]->get(), *queryPool, i);
3589         endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
3590     }
3591 
3592     beginCommandBuffer(vk, *primaryCmdBuffer);
3593     {
3594         std::vector<VkClearValue> renderPassClearValues(2);
3595         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
3596 
3597         if (!m_parametersGraphic.noColorAttachments)
3598             initialTransitionColor2DImage(
3599                 vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3600                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
3601 
3602         initialTransitionDepth2DImage(
3603             vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3604             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
3605             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3606 
3607         vk.cmdBindVertexBuffers(*primaryCmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
3608         vk.cmdBindPipeline(*primaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3609 
3610         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
3611             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3612 
3613         beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
3614                         (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0],
3615                         VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
3616         for (uint32_t i = 0; i < queryCount; ++i)
3617             vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
3618         endRenderPass(vk, *primaryCmdBuffer);
3619 
3620         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
3621             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
3622         {
3623             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
3624             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
3625             uint32_t queryCountTess      = queryCount;
3626 
3627             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3628             {
3629                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3630                 stride *= 2u;
3631             }
3632 
3633             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
3634             {
3635                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3636                 flags          = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3637                 stride         = sizeof(ValueAndAvailability);
3638                 queryCountTess = 1u;
3639             }
3640 
3641             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
3642             vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCountTess, m_resetBuffer->object(),
3643                                        dstOffsetQuery, stride, flags);
3644 
3645             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
3646                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3647 
3648             const VkBufferMemoryBarrier barrier = {
3649                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,  //  VkStructureType sType;
3650                 DE_NULL,                                  //  const void* pNext;
3651                 VK_ACCESS_TRANSFER_WRITE_BIT,             //  VkAccessFlags srcAccessMask;
3652                 VK_ACCESS_HOST_READ_BIT,                  //  VkAccessFlags dstAccessMask;
3653                 VK_QUEUE_FAMILY_IGNORED,                  //  uint32_t srcQueueFamilyIndex;
3654                 VK_QUEUE_FAMILY_IGNORED,                  //  uint32_t destQueueFamilyIndex;
3655                 m_resetBuffer->object(),                  //  VkBuffer buffer;
3656                 0u,                                       //  VkDeviceSize offset;
3657                 queryCountTess * stride + dstOffsetQuery, //  VkDeviceSize size;
3658             };
3659             vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
3660                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
3661                                   (const VkImageMemoryBarrier *)DE_NULL);
3662         }
3663 
3664         if (!m_parametersGraphic.noColorAttachments)
3665             transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
3666                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
3667                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3668                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3669     }
3670     endCommandBuffer(vk, *primaryCmdBuffer);
3671 
3672     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3673         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
3674 
3675     // Wait for completion
3676     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
3677     return checkResult(*queryPool);
3678 }
3679 
3680 class TessellationShaderSecondrayInheritedTestInstance : public TessellationShaderTestInstance
3681 {
3682 public:
3683     TessellationShaderSecondrayInheritedTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
3684                                                      const ParametersGraphic &parametersGraphic,
3685                                                      const std::vector<uint64_t> &drawRepeats);
3686 
3687 protected:
3688     virtual void checkExtensions(bool hostQueryResetEnabled);
3689     virtual tcu::TestStatus executeTest(void);
3690 };
3691 
TessellationShaderSecondrayInheritedTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic,const std::vector<uint64_t> & drawRepeats)3692 TessellationShaderSecondrayInheritedTestInstance::TessellationShaderSecondrayInheritedTestInstance(
3693     vkt::Context &context, const std::vector<VertexData> &data, const ParametersGraphic &parametersGraphic,
3694     const std::vector<uint64_t> &drawRepeats)
3695     : TessellationShaderTestInstance(context, data, parametersGraphic, drawRepeats)
3696 {
3697 }
3698 
checkExtensions(bool hostQueryResetEnabled)3699 void TessellationShaderSecondrayInheritedTestInstance::checkExtensions(bool hostQueryResetEnabled)
3700 {
3701     TessellationShaderTestInstance::checkExtensions(hostQueryResetEnabled);
3702     if (!m_context.getDeviceFeatures().inheritedQueries)
3703         throw tcu::NotSupportedError("Inherited queries are not supported");
3704 }
3705 
executeTest(void)3706 tcu::TestStatus TessellationShaderSecondrayInheritedTestInstance::executeTest(void)
3707 {
3708     const DeviceInterface &vk       = m_context.getDeviceInterface();
3709     const VkDevice device           = m_context.getDevice();
3710     const VkQueue queue             = m_context.getUniversalQueue();
3711     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3712 
3713     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
3714     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
3715     const uint32_t queryCount         = static_cast<uint32_t>(m_drawRepeats.size());
3716     const Unique<VkQueryPool> queryPool(makeQueryPool(vk, device, queryCount, m_parametersGraphic.queryStatisticFlags));
3717 
3718     const VkDeviceSize vertexBufferOffset = 0u;
3719     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
3720     const VkBuffer vertexBuffer           = vertexBufferSp->object();
3721 
3722     const Unique<VkCommandBuffer> primaryCmdBuffer(
3723         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3724     std::vector<VkCommandBufferSp> secondaryCmdBuffers(queryCount);
3725 
3726     for (uint32_t i = 0; i < queryCount; ++i)
3727         secondaryCmdBuffers[i] = VkCommandBufferSp(new vk::Unique<VkCommandBuffer>(
3728             allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
3729 
3730     for (uint32_t i = 0; i < queryCount; ++i)
3731     {
3732         beginSecondaryCommandBuffer(vk, secondaryCmdBuffers[i]->get(), m_parametersGraphic.queryStatisticFlags,
3733                                     *m_renderPass, *m_framebuffer, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
3734         vk.cmdBindPipeline(secondaryCmdBuffers[i]->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
3735         vk.cmdBindVertexBuffers(secondaryCmdBuffers[i]->get(), 0u, 1u, &vertexBuffer, &vertexBufferOffset);
3736         for (uint32_t j = 0; j < m_drawRepeats[i]; ++j)
3737             draw(secondaryCmdBuffers[i]->get());
3738         endCommandBuffer(vk, secondaryCmdBuffers[i]->get());
3739     }
3740 
3741     beginCommandBuffer(vk, *primaryCmdBuffer);
3742     {
3743         std::vector<VkClearValue> renderPassClearValues(2);
3744         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
3745 
3746         if (!m_parametersGraphic.noColorAttachments)
3747             initialTransitionColor2DImage(
3748                 vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3749                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
3750 
3751         initialTransitionDepth2DImage(
3752             vk, *primaryCmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3753             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
3754             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3755 
3756         if (m_parametersGraphic.resetType != RESET_TYPE_HOST)
3757             vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3758 
3759         for (uint32_t i = 0; i < queryCount; ++i)
3760         {
3761             vk.cmdBeginQuery(*primaryCmdBuffer, *queryPool, i, (VkQueryControlFlags)0u);
3762             beginRenderPass(vk, *primaryCmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
3763                             (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0],
3764                             VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
3765             vk.cmdExecuteCommands(*primaryCmdBuffer, 1u, &(secondaryCmdBuffers[i]->get()));
3766             endRenderPass(vk, *primaryCmdBuffer);
3767             vk.cmdEndQuery(*primaryCmdBuffer, *queryPool, i);
3768         }
3769 
3770         if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY ||
3771             m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY || m_parametersGraphic.copyType == COPY_TYPE_CMD)
3772         {
3773             VkDeviceSize stride          = m_parametersGraphic.querySizeFlags() ? sizeof(uint64_t) : sizeof(uint32_t);
3774             vk::VkQueryResultFlags flags = m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WAIT_BIT;
3775 
3776             if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3777             {
3778                 flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3779                 stride *= 2u;
3780             }
3781 
3782             if (m_parametersGraphic.resetType == RESET_TYPE_BEFORE_COPY)
3783             {
3784                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3785                 flags  = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
3786                 stride = sizeof(ValueAndAvailability);
3787             }
3788 
3789             VkDeviceSize dstOffsetQuery = (m_parametersGraphic.dstOffset) ? stride : 0;
3790             vk.cmdCopyQueryPoolResults(*primaryCmdBuffer, *queryPool, 0, queryCount, m_resetBuffer->object(),
3791                                        dstOffsetQuery, stride, flags);
3792 
3793             if (m_parametersGraphic.resetType == RESET_TYPE_AFTER_COPY)
3794                 vk.cmdResetQueryPool(*primaryCmdBuffer, *queryPool, 0u, queryCount);
3795 
3796             const VkBufferMemoryBarrier barrier = {
3797                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
3798                 DE_NULL,                                 //  const void* pNext;
3799                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
3800                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
3801                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
3802                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
3803                 m_resetBuffer->object(),                 //  VkBuffer buffer;
3804                 0u,                                      //  VkDeviceSize offset;
3805                 queryCount * stride + dstOffsetQuery,    //  VkDeviceSize size;
3806             };
3807             vk.cmdPipelineBarrier(*primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
3808                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
3809                                   (const VkImageMemoryBarrier *)DE_NULL);
3810         }
3811 
3812         if (!m_parametersGraphic.noColorAttachments)
3813             transition2DImage(vk, *primaryCmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
3814                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
3815                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3816                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3817     }
3818     endCommandBuffer(vk, *primaryCmdBuffer);
3819 
3820     if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
3821         vk.resetQueryPool(device, *queryPool, 0u, queryCount);
3822 
3823     // Wait for completion
3824     submitCommandsAndWait(vk, device, queue, *primaryCmdBuffer);
3825     return checkResult(*queryPool);
3826 }
3827 
3828 template <class Instance>
3829 class QueryPoolComputeStatsTest : public TestCase
3830 {
3831 public:
QueryPoolComputeStatsTest(tcu::TestContext & context,const std::string & name,const ResetType resetType,const CopyType copyType,bool query64Bits,const bool useComputeQueue,bool dstOffset=false,const StrideType strideType=STRIDE_TYPE_VALID)3832     QueryPoolComputeStatsTest(tcu::TestContext &context, const std::string &name, const ResetType resetType,
3833                               const CopyType copyType, bool query64Bits, const bool useComputeQueue,
3834                               bool dstOffset = false, const StrideType strideType = STRIDE_TYPE_VALID)
3835         : TestCase(context, name.c_str())
3836         , m_useComputeQueue(useComputeQueue)
3837     {
3838         const tcu::UVec3 localSize[] = {
3839             tcu::UVec3(2u, 2u, 2u),
3840             tcu::UVec3(1u, 1u, 1u),
3841             tcu::UVec3(WIDTH / (7u * 3u), 7u, 3u),
3842         };
3843 
3844         const tcu::UVec3 groupSize[] = {
3845             tcu::UVec3(2u, 2u, 2u),
3846             tcu::UVec3(WIDTH / (7u * 3u), 7u, 3u),
3847             tcu::UVec3(1u, 1u, 1u),
3848         };
3849 
3850         DE_ASSERT(DE_LENGTH_OF_ARRAY(localSize) == DE_LENGTH_OF_ARRAY(groupSize));
3851 
3852         for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(localSize); ++shaderNdx)
3853         {
3854             std::ostringstream shaderName;
3855             shaderName << "compute_" << shaderNdx;
3856             const ComputeInvocationsTestInstance::ParametersCompute parameters(
3857                 localSize[shaderNdx], groupSize[shaderNdx], shaderName.str(), resetType, copyType, query64Bits,
3858                 dstOffset, strideType, m_useComputeQueue);
3859             m_parameters.push_back(parameters);
3860         }
3861     }
3862 
createInstance(vkt::Context & context) const3863     vkt::TestInstance *createInstance(vkt::Context &context) const override
3864     {
3865         return new Instance(context, m_parameters);
3866     }
3867 
checkSupport(Context & context) const3868     void checkSupport(Context &context) const override
3869     {
3870         if (m_useComputeQueue)
3871         {
3872             const auto &vki           = context.getInstanceInterface();
3873             const auto physicalDevice = context.getPhysicalDevice();
3874 
3875             checkSupportForNonGraphicsQueueFamily(vki, physicalDevice);
3876         }
3877     }
3878 
initPrograms(SourceCollections & sourceCollections) const3879     void initPrograms(SourceCollections &sourceCollections) const override
3880     {
3881         std::ostringstream source;
3882         source << "layout(binding = 0) writeonly buffer Output {\n"
3883                << "    uint values[];\n"
3884                << "} sb_out;\n\n"
3885                << "void main (void) {\n"
3886                << "    uvec3 indexUvec3 = uvec3 (gl_GlobalInvocationID.x,\n"
3887                << "                              gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x,\n"
3888                << "                              gl_GlobalInvocationID.z * gl_NumWorkGroups.x * gl_NumWorkGroups.y * "
3889                   "gl_WorkGroupSize.x * gl_WorkGroupSize.y);\n"
3890                << "    uint index = indexUvec3.x + indexUvec3.y + indexUvec3.z;\n"
3891                << "    sb_out.values[index] += index;\n"
3892                << "}\n";
3893 
3894         for (size_t shaderNdx = 0; shaderNdx < m_parameters.size(); ++shaderNdx)
3895         {
3896             std::ostringstream src;
3897             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3898                 << "layout (local_size_x = " << m_parameters[shaderNdx].localSize.x()
3899                 << ", local_size_y = " << m_parameters[shaderNdx].localSize.y()
3900                 << ", local_size_z = " << m_parameters[shaderNdx].localSize.z() << ") in;\n"
3901                 << source.str();
3902             sourceCollections.glslSources.add(m_parameters[shaderNdx].shaderName) << glu::ComputeSource(src.str());
3903         }
3904     }
3905 
3906 private:
3907     std::vector<ComputeInvocationsTestInstance::ParametersCompute> m_parameters;
3908     const bool m_useComputeQueue;
3909 };
3910 
3911 template <class Instance>
3912 class QueryPoolGraphicStatisticsTest : public TestCase
3913 {
3914 public:
QueryPoolGraphicStatisticsTest(tcu::TestContext & context,const std::string & name,const GraphicBasicTestInstance::ParametersGraphic parametersGraphic,const std::vector<uint64_t> & drawRepeats)3915     QueryPoolGraphicStatisticsTest(tcu::TestContext &context, const std::string &name,
3916                                    const GraphicBasicTestInstance::ParametersGraphic parametersGraphic,
3917                                    const std::vector<uint64_t> &drawRepeats)
3918         : TestCase(context, name.c_str())
3919         , m_parametersGraphic(parametersGraphic)
3920         , m_drawRepeats(drawRepeats)
3921     {
3922         m_data.push_back(
3923             GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3924         m_data.push_back(
3925             GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3926         m_data.push_back(
3927             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3928         m_data.push_back(
3929             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::red().toVec()));
3930 
3931         m_data.push_back(
3932             GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3933         m_data.push_back(
3934             GraphicBasicTestInstance::VertexData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3935         m_data.push_back(
3936             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3937         m_data.push_back(
3938             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
3939 
3940         m_data.push_back(
3941             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3942         m_data.push_back(
3943             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3944         m_data.push_back(
3945             GraphicBasicTestInstance::VertexData(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3946         m_data.push_back(
3947             GraphicBasicTestInstance::VertexData(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
3948 
3949         m_data.push_back(
3950             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3951         m_data.push_back(
3952             GraphicBasicTestInstance::VertexData(tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3953         m_data.push_back(
3954             GraphicBasicTestInstance::VertexData(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3955         m_data.push_back(
3956             GraphicBasicTestInstance::VertexData(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::gray().toVec()));
3957     }
3958 
checkSupport(vkt::Context & context) const3959     void checkSupport(vkt::Context &context) const
3960     {
3961 #ifndef CTS_USES_VULKANSC
3962         if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
3963             context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
3964             !context.getPortabilitySubsetFeatures().triangleFans)
3965         {
3966             TCU_THROW(NotSupportedError,
3967                       "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
3968         }
3969 #else
3970         DE_UNREF(context);
3971 #endif // CTS_USES_VULKANSC
3972     }
3973 
createInstance(vkt::Context & context) const3974     vkt::TestInstance *createInstance(vkt::Context &context) const
3975     {
3976         return new Instance(context, m_data, m_parametersGraphic, m_drawRepeats);
3977     }
3978 
initPrograms(SourceCollections & sourceCollections) const3979     void initPrograms(SourceCollections &sourceCollections) const
3980     {
3981         { // Vertex Shader
3982             std::ostringstream source;
3983             source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3984                    << "layout(location = 0) in highp vec4 in_position;\n"
3985                    << "layout(location = 1) in vec4 in_color;\n"
3986                    << "layout(location = 0) out vec4 out_color;\n"
3987                    << "void main (void)\n"
3988                    << "{\n"
3989                    << "    gl_PointSize = 1.0;\n"
3990                    << "    gl_Position = in_position;\n"
3991                    << "    out_color = in_color;\n"
3992                    << "}\n";
3993             sourceCollections.glslSources.add("vertex") << glu::VertexSource(source.str());
3994         }
3995 
3996         if (m_parametersGraphic.hasTess)
3997         { // Tessellation control & evaluation
3998             std::ostringstream source_tc;
3999             source_tc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4000                       << "#extension GL_EXT_tessellation_shader : require\n"
4001                       << "layout(vertices = 4) out;\n"
4002                       << "layout(location = 0) in vec4 in_color[];\n"
4003                       << "layout(location = 0) out vec4 out_color[];\n"
4004                       << "\n"
4005                       << "void main (void)\n"
4006                       << "{\n"
4007                       << "    if( gl_InvocationID == 0 )\n"
4008                       << "    {\n"
4009                       << "        gl_TessLevelInner[0] = 4.0f;\n"
4010                       << "        gl_TessLevelInner[1] = 4.0f;\n"
4011                       << "        gl_TessLevelOuter[0] = 4.0f;\n"
4012                       << "        gl_TessLevelOuter[1] = 4.0f;\n"
4013                       << "        gl_TessLevelOuter[2] = 4.0f;\n"
4014                       << "        gl_TessLevelOuter[3] = 4.0f;\n"
4015                       << "    }\n"
4016                       << "    out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
4017                       << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
4018                       << "}\n";
4019             sourceCollections.glslSources.add("tessellation_control")
4020                 << glu::TessellationControlSource(source_tc.str());
4021 
4022             std::ostringstream source_te;
4023             source_te
4024                 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4025                 << "#extension GL_EXT_tessellation_shader : require\n"
4026                 << "layout( quads, equal_spacing, ccw ) in;\n"
4027                 << "layout(location = 0) in vec4 in_color[];\n"
4028                 << "layout(location = 0) out vec4 out_color;\n"
4029                 << "void main (void)\n"
4030                 << "{\n"
4031                 << "    const float u = gl_TessCoord.x;\n"
4032                 << "    const float v = gl_TessCoord.y;\n"
4033                 << "    const float w = gl_TessCoord.z;\n"
4034                 << "    gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position "
4035                    "+ u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n"
4036                 << "    out_color = in_color[0];\n"
4037                 << "}\n";
4038             sourceCollections.glslSources.add("tessellation_evaluation")
4039                 << glu::TessellationEvaluationSource(source_te.str());
4040         }
4041 
4042         if (m_parametersGraphic.queryStatisticFlags & (VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT |
4043                                                        VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT |
4044                                                        VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT |
4045                                                        VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT))
4046         { // Geometry Shader
4047             const bool isTopologyPointSize = m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
4048             std::ostringstream source;
4049             source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4050                    << "layout(" << inputTypeToGLString(m_parametersGraphic.primitiveTopology) << ") in;\n"
4051                    << "layout(" << outputTypeToGLString(m_parametersGraphic.primitiveTopology)
4052                    << ", max_vertices = 16) out;\n"
4053                    << "layout(location = 0) in vec4 in_color[];\n"
4054                    << "layout(location = 0) out vec4 out_color;\n"
4055                    << "void main (void)\n"
4056                    << "{\n"
4057                    << "    out_color = in_color[0];\n"
4058                    << (isTopologyPointSize ? "${pointSize}" : "") << "    gl_Position = gl_in[0].gl_Position;\n"
4059                    << "    EmitVertex();\n"
4060                    << "    EndPrimitive();\n"
4061                    << "\n"
4062                    << "    out_color = in_color[0];\n"
4063                    << (isTopologyPointSize ? "${pointSize}" : "") << "    gl_Position = vec4(1.0, 1.0, 1.0, 1.0);\n"
4064                    << "    EmitVertex();\n"
4065                    << "    out_color = in_color[0];\n"
4066                    << (isTopologyPointSize ? "${pointSize}" : "") << "    gl_Position = vec4(-1.0, -1.0, 1.0, 1.0);\n"
4067                    << "    EmitVertex();\n"
4068                    << "    EndPrimitive();\n"
4069                    << "\n";
4070             if (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
4071                 m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
4072             {
4073                 source << "\n"
4074                        << "    out_color = in_color[0];\n"
4075                        << "    gl_Position = gl_in[0].gl_Position;\n"
4076                        << "    EmitVertex();\n"
4077                        << "    out_color = in_color[0];\n"
4078                        << "    gl_Position = gl_in[1].gl_Position;\n"
4079                        << "    EmitVertex();\n"
4080                        << "    out_color = in_color[0];\n"
4081                        << "    gl_Position = gl_in[2].gl_Position;\n"
4082                        << "    EmitVertex();\n"
4083                        << "    out_color = in_color[0];\n"
4084                        << "    gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
4085                        << "    EmitVertex();\n"
4086                        << "    EndPrimitive();\n";
4087             }
4088             else
4089             {
4090                 source << "    out_color = in_color[0];\n"
4091                        << (isTopologyPointSize ? "${pointSize}" : "") << "    gl_Position = vec4(1.0, 1.0, 1.0, 1.0);\n"
4092                        << "    EmitVertex();\n"
4093                        << "    out_color = in_color[0];\n"
4094                        << (isTopologyPointSize ? "${pointSize}" : "")
4095                        << "    gl_Position = vec4(1.0, -1.0, 1.0, 1.0);\n"
4096                        << "    EmitVertex();\n"
4097                        << "    out_color = in_color[0];\n"
4098                        << (isTopologyPointSize ? "${pointSize}" : "")
4099                        << "    gl_Position = vec4(-1.0, 1.0, 1.0, 1.0);\n"
4100                        << "    EmitVertex();\n"
4101                        << "    out_color = in_color[0];\n"
4102                        << (isTopologyPointSize ? "${pointSize}" : "")
4103                        << "    gl_Position = vec4(-1.0, -1.0, 1.0, 1.0);\n"
4104                        << "    EmitVertex();\n"
4105                        << "    EndPrimitive();\n";
4106             }
4107             source << "}\n";
4108 
4109             if (isTopologyPointSize)
4110             {
4111                 // Add geometry shader codes with and without gl_PointSize if the primitive topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST
4112 
4113                 tcu::StringTemplate sourceTemplate(source.str());
4114 
4115                 std::map<std::string, std::string> pointSize;
4116                 std::map<std::string, std::string> noPointSize;
4117 
4118                 pointSize["pointSize"]   = "    gl_PointSize = gl_in[0].gl_PointSize;\n";
4119                 noPointSize["pointSize"] = "";
4120 
4121                 sourceCollections.glslSources.add("geometry")
4122                     << glu::GeometrySource(sourceTemplate.specialize(noPointSize));
4123                 sourceCollections.glslSources.add("geometry_point_size")
4124                     << glu::GeometrySource(sourceTemplate.specialize(pointSize));
4125             }
4126             else
4127             {
4128                 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(source.str());
4129             }
4130         }
4131 
4132         if (!m_parametersGraphic.vertexOnlyPipe)
4133         { // Fragment Shader
4134             std::ostringstream source;
4135             source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4136                    << "layout(location = 0) in vec4 in_color;\n"
4137                    << "layout(location = 0) out vec4 out_color;\n"
4138                    << "void main()\n"
4139                    << "{\n"
4140                    << "    out_color = in_color;\n"
4141                    << "}\n";
4142             sourceCollections.glslSources.add("fragment") << glu::FragmentSource(source.str());
4143         }
4144     }
4145 
4146 private:
4147     std::vector<GraphicBasicTestInstance::VertexData> m_data;
4148     const GraphicBasicTestInstance::ParametersGraphic m_parametersGraphic;
4149     std::vector<uint64_t> m_drawRepeats;
4150 };
4151 
4152 #define NUM_QUERY_STATISTICS 4
4153 
4154 class StatisticMultipleQueryTestInstance : public TestInstance
4155 {
4156 public:
4157     StatisticMultipleQueryTestInstance(Context &context, const uint32_t queryCount);
4158 
4159 protected:
4160     BufferPtr m_queryBuffer;
4161 
4162     virtual void checkExtensions();
4163 };
4164 
StatisticMultipleQueryTestInstance(Context & context,const uint32_t queryCount)4165 StatisticMultipleQueryTestInstance::StatisticMultipleQueryTestInstance(Context &context, const uint32_t queryCount)
4166     : TestInstance(context)
4167     , m_queryBuffer(Buffer::createAndAlloc(
4168           context.getDeviceInterface(), context.getDevice(),
4169           BufferCreateInfo(NUM_QUERY_STATISTICS * sizeof(uint64_t) * queryCount, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
4170           context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible))
4171 {
4172     const vk::Allocation &allocation = m_queryBuffer->getBoundMemory();
4173     void *allocationData             = allocation.getHostPtr();
4174     deMemset(allocationData, 0xff, NUM_QUERY_STATISTICS * sizeof(uint64_t) * queryCount);
4175 }
4176 
checkExtensions()4177 void StatisticMultipleQueryTestInstance::checkExtensions()
4178 {
4179     if (!m_context.getDeviceFeatures().pipelineStatisticsQuery)
4180         throw tcu::NotSupportedError("Pipeline statistics queries are not supported");
4181 }
4182 
4183 class GraphicBasicMultipleQueryTestInstance : public StatisticMultipleQueryTestInstance
4184 {
4185 public:
4186     struct VertexData
4187     {
VertexDatavkt::QueryPool::__anon6b4348560111::GraphicBasicMultipleQueryTestInstance::VertexData4188         VertexData(const tcu::Vec4 position_, const tcu::Vec4 color_) : position(position_), color(color_)
4189         {
4190         }
4191         tcu::Vec4 position;
4192         tcu::Vec4 color;
4193     };
4194 
4195     struct ParametersGraphic : public GenericParameters
4196     {
ParametersGraphicvkt::QueryPool::__anon6b4348560111::GraphicBasicMultipleQueryTestInstance::ParametersGraphic4197         ParametersGraphic(const VkQueryPipelineStatisticFlags queryStatisticFlags_,
4198                           const VkQueryResultFlags queryFlags_, const uint32_t queryCount_, const bool vertexOnlyPipe_,
4199                           const CopyType copyType_, const uint32_t dstOffset_, const StrideType strideType_,
4200                           const ClearOperation clearOp_ = CLEAR_NOOP)
4201             : GenericParameters{RESET_TYPE_NORMAL, copyType_, (queryFlags_ & VK_QUERY_RESULT_64_BIT) != 0u,
4202                                 dstOffset_ != 0u, strideType_}
4203             , queryStatisticFlags(queryStatisticFlags_)
4204             , vertexOnlyPipe(vertexOnlyPipe_)
4205             , queryFlags(queryFlags_)
4206             , queryCount(queryCount_)
4207             , dstOffset(dstOffset_)
4208             , clearOp(clearOp_)
4209         {
4210         }
4211 
4212         VkQueryPipelineStatisticFlags queryStatisticFlags;
4213         VkPrimitiveTopology primitiveTopology;
4214         bool vertexOnlyPipe;
4215         VkQueryResultFlags queryFlags;
4216         uint32_t queryCount;
4217         uint32_t dstOffset;
4218         ClearOperation clearOp;
4219     };
4220     GraphicBasicMultipleQueryTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
4221                                           const ParametersGraphic &parametersGraphic);
4222     tcu::TestStatus iterate(void);
4223 
4224 protected:
4225     BufferPtr creatAndFillVertexBuffer(void);
4226     virtual void createPipeline(void) = 0;
4227     void creatColorAttachmentAndRenderPass(void);
4228     virtual tcu::TestStatus executeTest(void)                  = 0;
4229     virtual tcu::TestStatus checkResult(VkQueryPool queryPool) = 0;
4230     virtual void draw(VkCommandBuffer cmdBuffer)               = 0;
4231 
4232     const VkFormat m_colorAttachmentFormat;
4233     de::SharedPtr<Image> m_colorAttachmentImage;
4234     de::SharedPtr<Image> m_depthImage;
4235     Move<VkImageView> m_attachmentView;
4236     Move<VkImageView> m_depthView;
4237     Move<VkRenderPass> m_renderPass;
4238     Move<VkFramebuffer> m_framebuffer;
4239     Move<VkPipeline> m_pipeline;
4240     Move<VkPipelineLayout> m_pipelineLayout;
4241     const std::vector<VertexData> &m_data;
4242     const ParametersGraphic &m_parametersGraphic;
4243 };
4244 
GraphicBasicMultipleQueryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic)4245 GraphicBasicMultipleQueryTestInstance::GraphicBasicMultipleQueryTestInstance(vkt::Context &context,
4246                                                                              const std::vector<VertexData> &data,
4247                                                                              const ParametersGraphic &parametersGraphic)
4248     : StatisticMultipleQueryTestInstance(context,
4249                                          (parametersGraphic.queryCount + (parametersGraphic.dstOffset != 0u ? 1u : 0u)))
4250     , m_colorAttachmentFormat(VK_FORMAT_R8G8B8A8_UNORM)
4251     , m_data(data)
4252     , m_parametersGraphic(parametersGraphic)
4253 {
4254 }
4255 
iterate(void)4256 tcu::TestStatus GraphicBasicMultipleQueryTestInstance::iterate(void)
4257 {
4258     checkExtensions();
4259     creatColorAttachmentAndRenderPass();
4260     createPipeline();
4261     return executeTest();
4262 }
4263 
creatAndFillVertexBuffer(void)4264 BufferPtr GraphicBasicMultipleQueryTestInstance::creatAndFillVertexBuffer(void)
4265 {
4266     const DeviceInterface &vk = m_context.getDeviceInterface();
4267     const VkDevice device     = m_context.getDevice();
4268 
4269     const VkDeviceSize dataSize = static_cast<VkDeviceSize>(
4270         deAlignSize(static_cast<size_t>(m_data.size() * sizeof(VertexData)),
4271                     static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
4272 
4273     BufferPtr vertexBuffer =
4274         Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
4275                                m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
4276 
4277     uint8_t *ptr = reinterpret_cast<uint8_t *>(vertexBuffer->getBoundMemory().getHostPtr());
4278     deMemcpy(ptr, &m_data[0], static_cast<size_t>(m_data.size() * sizeof(VertexData)));
4279 
4280     flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(),
4281                            vertexBuffer->getBoundMemory().getOffset(), dataSize);
4282     return vertexBuffer;
4283 }
4284 
creatColorAttachmentAndRenderPass(void)4285 void GraphicBasicMultipleQueryTestInstance::creatColorAttachmentAndRenderPass(void)
4286 {
4287     const DeviceInterface &vk = m_context.getDeviceInterface();
4288     const VkDevice device     = m_context.getDevice();
4289 
4290     {
4291         VkExtent3D imageExtent = {
4292             WIDTH,  // width;
4293             HEIGHT, // height;
4294             1u      // depth;
4295         };
4296 
4297         const ImageCreateInfo colorImageCreateInfo(
4298             VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT,
4299             VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4300 
4301         m_colorAttachmentImage =
4302             Image::createAndAlloc(vk, device, colorImageCreateInfo, m_context.getDefaultAllocator(),
4303                                   m_context.getUniversalQueueFamilyIndex());
4304 
4305         const ImageViewCreateInfo attachmentViewInfo(m_colorAttachmentImage->object(), VK_IMAGE_VIEW_TYPE_2D,
4306                                                      m_colorAttachmentFormat);
4307         m_attachmentView = createImageView(vk, device, &attachmentViewInfo);
4308 
4309         ImageCreateInfo depthImageCreateInfo(vk::VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM, imageExtent, 1, 1,
4310                                              vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
4311                                              vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
4312 
4313         m_depthImage = Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(),
4314                                              m_context.getUniversalQueueFamilyIndex());
4315 
4316         // Construct a depth  view from depth image
4317         const ImageViewCreateInfo depthViewInfo(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM);
4318         m_depthView = vk::createImageView(vk, device, &depthViewInfo);
4319     }
4320 
4321     {
4322         // Renderpass and Framebuffer
4323         RenderPassCreateInfo renderPassCreateInfo;
4324         renderPassCreateInfo.addAttachment(
4325             AttachmentDescription(m_colorAttachmentFormat,                    // format
4326                                   VK_SAMPLE_COUNT_1_BIT,                      // samples
4327                                   VK_ATTACHMENT_LOAD_OP_CLEAR,                // loadOp
4328                                   VK_ATTACHMENT_STORE_OP_STORE,               // storeOp
4329                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,            // stencilLoadOp
4330                                   VK_ATTACHMENT_STORE_OP_STORE,               // stencilLoadOp
4331                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,   // initialLauout
4332                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); // finalLayout
4333 
4334         renderPassCreateInfo.addAttachment(
4335             AttachmentDescription(VK_FORMAT_D16_UNORM,                                    // format
4336                                   vk::VK_SAMPLE_COUNT_1_BIT,                              // samples
4337                                   vk::VK_ATTACHMENT_LOAD_OP_CLEAR,                        // loadOp
4338                                   vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // storeOp
4339                                   vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // stencilLoadOp
4340                                   vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // stencilLoadOp
4341                                   vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // initialLauout
4342                                   vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); // finalLayout
4343 
4344         const VkAttachmentReference colorAttachmentReference = {
4345             0u,                                      // attachment
4346             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
4347         };
4348 
4349         const VkAttachmentReference depthAttachmentReference = {
4350             1u,                                                  // attachment
4351             vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // layout
4352         };
4353 
4354         const VkSubpassDescription subpass = {
4355             (VkSubpassDescriptionFlags)0,    //VkSubpassDescriptionFlags flags;
4356             VK_PIPELINE_BIND_POINT_GRAPHICS, //VkPipelineBindPoint pipelineBindPoint;
4357             0u,                              //uint32_t inputAttachmentCount;
4358             DE_NULL,                         //const VkAttachmentReference* pInputAttachments;
4359             1u,                              //uint32_t colorAttachmentCount;
4360             &colorAttachmentReference,       //const VkAttachmentReference* pColorAttachments;
4361             DE_NULL,                         //const VkAttachmentReference* pResolveAttachments;
4362             &depthAttachmentReference,       //const VkAttachmentReference* pDepthStencilAttachment;
4363             0u,                              //uint32_t preserveAttachmentCount;
4364             DE_NULL,                         //const uint32_t* pPreserveAttachments;
4365         };
4366 
4367         renderPassCreateInfo.addSubpass(subpass);
4368         m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
4369 
4370         std::vector<vk::VkImageView> attachments(2);
4371         attachments[0] = *m_attachmentView;
4372         attachments[1] = *m_depthView;
4373 
4374         FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
4375         m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
4376     }
4377 }
4378 
4379 class VertexShaderMultipleQueryTestInstance : public GraphicBasicMultipleQueryTestInstance
4380 {
4381 public:
4382     VertexShaderMultipleQueryTestInstance(vkt::Context &context, const std::vector<VertexData> &data,
4383                                           const ParametersGraphic &parametersGraphic);
4384 
4385 protected:
4386     virtual void createPipeline(void);
4387     virtual tcu::TestStatus executeTest(void);
4388     virtual tcu::TestStatus checkResult(VkQueryPool queryPool);
4389     void draw(VkCommandBuffer cmdBuffer);
4390     uint64_t calculateExpectedMin(VkQueryResultFlags flag);
4391     uint64_t calculateExpectedMax(VkQueryResultFlags flag);
4392 };
4393 
VertexShaderMultipleQueryTestInstance(vkt::Context & context,const std::vector<VertexData> & data,const ParametersGraphic & parametersGraphic)4394 VertexShaderMultipleQueryTestInstance::VertexShaderMultipleQueryTestInstance(vkt::Context &context,
4395                                                                              const std::vector<VertexData> &data,
4396                                                                              const ParametersGraphic &parametersGraphic)
4397     : GraphicBasicMultipleQueryTestInstance(context, data, parametersGraphic)
4398 {
4399 }
4400 
createPipeline(void)4401 void VertexShaderMultipleQueryTestInstance::createPipeline(void)
4402 {
4403     const DeviceInterface &vk = m_context.getDeviceInterface();
4404     const VkDevice device     = m_context.getDevice();
4405 
4406     // Pipeline
4407     Unique<VkShaderModule> vs(createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), 0));
4408     Move<VkShaderModule> fs;
4409 
4410     if (!m_parametersGraphic.vertexOnlyPipe)
4411         fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), 0);
4412 
4413     const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
4414 
4415     const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
4416     m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
4417 
4418     const VkVertexInputBindingDescription vertexInputBindingDescription = {
4419         0,                                         // binding;
4420         static_cast<uint32_t>(sizeof(VertexData)), // stride;
4421         VK_VERTEX_INPUT_RATE_VERTEX                // inputRate
4422     };
4423 
4424     const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
4425         {0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u}, // VertexElementData::position
4426         {1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, static_cast<uint32_t>(sizeof(tcu::Vec4))}, // VertexElementData::color
4427     };
4428 
4429     const VkPipelineVertexInputStateCreateInfo vf_info = {
4430         // sType;
4431         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // pNext;
4432         NULL,                                                      // flags;
4433         0u,                                                        // vertexBindingDescriptionCount;
4434         1u,                                                        // pVertexBindingDescriptions;
4435         &vertexInputBindingDescription,                            // vertexAttributeDescriptionCount;
4436         2u,                                                        // pVertexAttributeDescriptions;
4437         vertexInputAttributeDescriptions};
4438 
4439     PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
4440     pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
4441     if (!m_parametersGraphic.vertexOnlyPipe)
4442         pipelineCreateInfo.addShader(
4443             PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4444     pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
4445     pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
4446     pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
4447 
4448     const VkViewport viewport = makeViewport(WIDTH, HEIGHT);
4449     const VkRect2D scissor    = makeRect2D(WIDTH, HEIGHT);
4450     pipelineCreateInfo.addState(
4451         PipelineCreateInfo::ViewportState(1u, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
4452     pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
4453     pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
4454     pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
4455     pipelineCreateInfo.addState(vf_info);
4456     m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
4457 }
4458 
executeTest(void)4459 tcu::TestStatus VertexShaderMultipleQueryTestInstance::executeTest(void)
4460 {
4461     const DeviceInterface &vk       = m_context.getDeviceInterface();
4462     const VkDevice device           = m_context.getDevice();
4463     const VkQueue queue             = m_context.getUniversalQueue();
4464     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
4465 
4466     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
4467     const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
4468     const Unique<VkQueryPool> queryPool(
4469         makeQueryPool(vk, device, m_parametersGraphic.queryCount, m_parametersGraphic.queryStatisticFlags));
4470 
4471     const VkDeviceSize vertexBufferOffset = 0u;
4472     const BufferPtr vertexBufferSp        = creatAndFillVertexBuffer();
4473     const VkBuffer vertexBuffer           = vertexBufferSp->object();
4474 
4475     const Unique<VkCommandBuffer> cmdBuffer(
4476         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4477 
4478     beginCommandBuffer(vk, *cmdBuffer);
4479     {
4480         std::vector<VkClearValue> renderPassClearValues(2);
4481         deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(VkClearValue));
4482 
4483         initialTransitionColor2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(),
4484                                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4485                                       VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
4486         initialTransitionDepth2DImage(
4487             vk, *cmdBuffer, m_depthImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4488             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4489             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
4490 
4491         vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, m_parametersGraphic.queryCount);
4492 
4493         beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT),
4494                         (uint32_t)renderPassClearValues.size(), &renderPassClearValues[0]);
4495 
4496         vk.cmdBeginQuery(*cmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
4497         vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
4498         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
4499 
4500         draw(*cmdBuffer);
4501 
4502         vk.cmdEndQuery(*cmdBuffer, *queryPool, 0u);
4503 
4504         endRenderPass(vk, *cmdBuffer);
4505 
4506         if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
4507         {
4508             VkDeviceSize copyStride = NUM_QUERY_STATISTICS * sizeof(uint64_t);
4509             if (m_parametersGraphic.queryCount == 1u && m_parametersGraphic.strideType == STRIDE_TYPE_ZERO)
4510                 copyStride = 0u;
4511 
4512             vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, 0, m_parametersGraphic.queryCount,
4513                                        m_queryBuffer->object(), m_parametersGraphic.dstOffset, copyStride,
4514                                        m_parametersGraphic.queryFlags);
4515 
4516             const VkDeviceSize bufferSize = NUM_QUERY_STATISTICS * sizeof(uint64_t) * m_parametersGraphic.queryCount;
4517             const VkBufferMemoryBarrier barrier = {
4518                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
4519                 DE_NULL,                                 //  const void* pNext;
4520                 VK_ACCESS_TRANSFER_WRITE_BIT,            //  VkAccessFlags srcAccessMask;
4521                 VK_ACCESS_HOST_READ_BIT,                 //  VkAccessFlags dstAccessMask;
4522                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
4523                 VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
4524                 m_queryBuffer->object(),                 //  VkBuffer buffer;
4525                 0u,                                      //  VkDeviceSize offset;
4526                 bufferSize,                              //  VkDeviceSize size;
4527             };
4528 
4529             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
4530                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1u, &barrier, 0,
4531                                   (const VkImageMemoryBarrier *)DE_NULL);
4532         }
4533 
4534         transition2DImage(vk, *cmdBuffer, m_colorAttachmentImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
4535                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
4536                           VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
4537                           VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4538     }
4539     endCommandBuffer(vk, *cmdBuffer);
4540 
4541     // Wait for completion
4542     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
4543     return checkResult(*queryPool);
4544 }
4545 
calculateExpectedMin(VkQueryResultFlags flag)4546 uint64_t VertexShaderMultipleQueryTestInstance::calculateExpectedMin(VkQueryResultFlags flag)
4547 {
4548     uint64_t expectedMin = 0u;
4549     switch (flag)
4550     {
4551     case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT:
4552         expectedMin = 15u;
4553         break;
4554 
4555     case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT:
4556         expectedMin = 5u;
4557         break;
4558 
4559     case VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT:
4560         expectedMin = 15u;
4561         break;
4562 
4563     case VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT:
4564         expectedMin = 2016u;
4565         break;
4566     default:
4567         DE_FATAL("Unexpected type of statistics query");
4568         break;
4569     }
4570     return expectedMin;
4571 }
4572 
4573 /* This is just to check that driver doesn't return garbage for the partial, no wait case.
4574  * TODO: adjust the values accordingly, in case some driver returns higher values.
4575  */
calculateExpectedMax(VkQueryResultFlags flag)4576 uint64_t VertexShaderMultipleQueryTestInstance::calculateExpectedMax(VkQueryResultFlags flag)
4577 {
4578     uint64_t expectedMax = 0u;
4579     switch (flag)
4580     {
4581     case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT:
4582         expectedMax = 16u;
4583         break;
4584 
4585     case VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT:
4586         expectedMax = 5u;
4587         break;
4588 
4589     case VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT:
4590         expectedMax = 15u;
4591         break;
4592 
4593     case VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT:
4594         expectedMax = 2304u;
4595         break;
4596     default:
4597         DE_FATAL("Unexpected type of statistics query");
4598         break;
4599     }
4600     return expectedMax;
4601 }
4602 
checkResult(VkQueryPool queryPool)4603 tcu::TestStatus VertexShaderMultipleQueryTestInstance::checkResult(VkQueryPool queryPool)
4604 {
4605     const DeviceInterface &vk = m_context.getDeviceInterface();
4606     const VkDevice device     = m_context.getDevice();
4607     uint32_t queryCount       = (m_parametersGraphic.queryCount + (m_parametersGraphic.dstOffset ? 1u : 0u));
4608     uint32_t size             = NUM_QUERY_STATISTICS * queryCount;
4609     std::vector<uint64_t> results(size, 0ull);
4610 
4611     bool hasPartialFlag = (bool)(m_parametersGraphic.queryFlags & VK_QUERY_RESULT_PARTIAL_BIT);
4612     bool hasWaitFlag    = (bool)(m_parametersGraphic.queryFlags & VK_QUERY_RESULT_WAIT_BIT);
4613     // Use the last value of each query to store the availability bit for the vertexOnlyPipe case.
4614     VkQueryResultFlags queryFlags = m_parametersGraphic.queryFlags;
4615 
4616     if (m_parametersGraphic.copyType == COPY_TYPE_CMD)
4617     {
4618         const vk::Allocation &allocation = m_queryBuffer->getBoundMemory();
4619         const void *allocationData       = allocation.getHostPtr();
4620 
4621         vk::invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), allocation);
4622         deMemcpy(results.data(), allocationData, size * sizeof(uint64_t));
4623     }
4624     else
4625     {
4626         VkResult result =
4627             vk.getQueryPoolResults(device, queryPool, 0u, m_parametersGraphic.queryCount, de::dataSize(results),
4628                                    de::dataOrNull(results), NUM_QUERY_STATISTICS * sizeof(uint64_t), queryFlags);
4629 
4630         if (!(result == VK_SUCCESS || (!hasWaitFlag && result == VK_NOT_READY)))
4631             return tcu::TestStatus::fail("Unexpected getQueryPoolResults() returned value: " +
4632                                          de::toString(getResultStr(result)));
4633     }
4634 
4635     for (uint32_t queryIdx = 0; queryIdx < queryCount; queryIdx++)
4636     {
4637         int32_t queryMask = m_parametersGraphic.queryStatisticFlags;
4638         uint32_t index    = queryIdx * NUM_QUERY_STATISTICS;
4639         // Last element of each query is the availability value for the vertexOnlyPipe case.
4640         bool availableQuery = results[index + (NUM_QUERY_STATISTICS - 1)] != 0u;
4641 
4642         // Check dstOffset values were not overwritten.
4643         if (m_parametersGraphic.dstOffset != 0u && queryIdx == 0u)
4644         {
4645             const uint64_t refVal = 0xfffffffffffffffful;
4646             for (; index < NUM_QUERY_STATISTICS; index++)
4647             {
4648                 if (results[index] != refVal)
4649                     return tcu::TestStatus::fail("dstOffset values were overwritten");
4650             }
4651             continue;
4652         }
4653 
4654         if (hasWaitFlag && !hasPartialFlag && !availableQuery)
4655             return tcu::TestStatus::fail("Results should be available");
4656 
4657         while (queryMask)
4658         {
4659             int32_t statisticBit = deInt32BitScan(&queryMask);
4660             uint64_t expectedMin = calculateExpectedMin((1u << statisticBit));
4661             uint64_t expectedMax = calculateExpectedMax((1u << statisticBit));
4662 
4663             if (availableQuery && (results[index] < expectedMin))
4664                 return tcu::TestStatus::fail("QueryPoolResults incorrect: wrong value (" +
4665                                              de::toString(results[index]) + ") is lower than expected (" +
4666                                              de::toString(expectedMin) + ")");
4667 
4668             /* From the spec:
4669              *
4670              *    If VK_QUERY_RESULT_PARTIAL_BIT is set, VK_QUERY_RESULT_WAIT_BIT is not set,
4671              *    and the query's status is unavailable, an intermediate result value between zero
4672              *    and the final result value is written to pData for that query.
4673              */
4674             if (hasPartialFlag && !hasWaitFlag && !availableQuery && results[index] > expectedMax)
4675                 return tcu::TestStatus::fail("QueryPoolResults incorrect: wrong partial value (" +
4676                                              de::toString(results[index]) + ") is greater than expected (" +
4677                                              de::toString(expectedMax) + ")");
4678 
4679             index++;
4680         }
4681     }
4682 
4683     return tcu::TestStatus::pass("Pass");
4684 }
4685 
draw(VkCommandBuffer cmdBuffer)4686 void VertexShaderMultipleQueryTestInstance::draw(VkCommandBuffer cmdBuffer)
4687 {
4688     const DeviceInterface &vk = m_context.getDeviceInterface();
4689     vk.cmdDraw(cmdBuffer, 16u, 1u, 0u, 0u);
4690 }
4691 
4692 template <class Instance>
4693 class QueryPoolGraphicMultipleQueryStatisticsTest : public TestCase
4694 {
4695 public:
QueryPoolGraphicMultipleQueryStatisticsTest(tcu::TestContext & context,const std::string & name,const GraphicBasicMultipleQueryTestInstance::ParametersGraphic parametersGraphic)4696     QueryPoolGraphicMultipleQueryStatisticsTest(
4697         tcu::TestContext &context, const std::string &name,
4698         const GraphicBasicMultipleQueryTestInstance::ParametersGraphic parametersGraphic)
4699         : TestCase(context, name.c_str())
4700         , m_parametersGraphic(parametersGraphic)
4701     {
4702         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f),
4703                                                                            tcu::RGBA::red().toVec()));
4704         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f),
4705                                                                            tcu::RGBA::red().toVec()));
4706         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, -1.0f, 1.0f, 1.0f),
4707                                                                            tcu::RGBA::red().toVec()));
4708         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
4709                                                                            tcu::RGBA::red().toVec()));
4710 
4711         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f),
4712                                                                            tcu::RGBA::green().toVec()));
4713         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f),
4714                                                                            tcu::RGBA::green().toVec()));
4715         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
4716                                                                            tcu::RGBA::green().toVec()));
4717         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f),
4718                                                                            tcu::RGBA::green().toVec()));
4719 
4720         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, -1.0f, 1.0f, 1.0f),
4721                                                                            tcu::RGBA::blue().toVec()));
4722         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
4723                                                                            tcu::RGBA::blue().toVec()));
4724         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f),
4725                                                                            tcu::RGBA::blue().toVec()));
4726         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
4727                                                                            tcu::RGBA::blue().toVec()));
4728 
4729         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
4730                                                                            tcu::RGBA::gray().toVec()));
4731         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f),
4732                                                                            tcu::RGBA::gray().toVec()));
4733         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
4734                                                                            tcu::RGBA::gray().toVec()));
4735         m_data.push_back(GraphicBasicMultipleQueryTestInstance::VertexData(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
4736                                                                            tcu::RGBA::gray().toVec()));
4737     }
4738 
createInstance(vkt::Context & context) const4739     vkt::TestInstance *createInstance(vkt::Context &context) const
4740     {
4741         return new Instance(context, m_data, m_parametersGraphic);
4742     }
4743 
initPrograms(SourceCollections & sourceCollections) const4744     void initPrograms(SourceCollections &sourceCollections) const
4745     {
4746         { // Vertex Shader
4747             std::ostringstream source;
4748             source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4749                    << "layout(location = 0) in highp vec4 in_position;\n"
4750                    << "layout(location = 1) in vec4 in_color;\n"
4751                    << "layout(location = 0) out vec4 out_color;\n"
4752                    << "void main (void)\n"
4753                    << "{\n"
4754                    << "    gl_PointSize = 1.0;\n"
4755                    << "    gl_Position = in_position;\n"
4756                    << "    out_color = in_color;\n"
4757                    << "}\n";
4758             sourceCollections.glslSources.add("vertex") << glu::VertexSource(source.str());
4759         }
4760 
4761         if (!m_parametersGraphic.vertexOnlyPipe)
4762         { // Fragment Shader
4763             std::ostringstream source;
4764             source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4765                    << "layout(location = 0) in vec4 in_color;\n"
4766                    << "layout(location = 0) out vec4 out_color;\n"
4767                    << "void main()\n"
4768                    << "{\n"
4769                    << "    out_color = in_color;\n"
4770                    << "}\n";
4771             sourceCollections.glslSources.add("fragment") << glu::FragmentSource(source.str());
4772         }
4773     }
4774 
4775 private:
4776     std::vector<GraphicBasicMultipleQueryTestInstance::VertexData> m_data;
4777     const GraphicBasicMultipleQueryTestInstance::ParametersGraphic m_parametersGraphic;
4778 };
4779 
4780 class BlitBetweenIncompatibleFormatsTestInstance : public StatisticMultipleQueryTestInstance
4781 {
4782 public:
4783     BlitBetweenIncompatibleFormatsTestInstance(vkt::Context &context);
4784 
4785 protected:
4786     virtual tcu::TestStatus iterate(void);
4787 };
4788 
BlitBetweenIncompatibleFormatsTestInstance(vkt::Context & context)4789 BlitBetweenIncompatibleFormatsTestInstance::BlitBetweenIncompatibleFormatsTestInstance(vkt::Context &context)
4790     : StatisticMultipleQueryTestInstance(context, 1u)
4791 {
4792 }
4793 
iterate(void)4794 tcu::TestStatus BlitBetweenIncompatibleFormatsTestInstance::iterate(void)
4795 {
4796     const DeviceInterface &vk       = m_context.getDeviceInterface();
4797     const VkDevice device           = m_context.getDevice();
4798     const VkQueue queue             = m_context.getUniversalQueue();
4799     auto &alloc                     = m_context.getDefaultAllocator();
4800     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
4801 
4802     const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
4803     const Move<VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolCreateInfo));
4804     const Unique<VkQueryPool> queryPool(
4805         makeQueryPool(vk, device, 1u, VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT));
4806     const Unique<VkCommandBuffer> cmdBuffer(
4807         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4808 
4809     const VkImageSubresourceLayers subresourceLayers{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u};
4810     const VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
4811     const VkClearColorValue clearColor{{0.0f, 1.0f, 0.0f, 1.0f}};
4812     const VkImageBlit blitRegion{
4813         subresourceLayers, {{8, 0, 0}, {16, 16, 1}}, subresourceLayers, {{0, 8, 0}, {8, 16, 1}}};
4814 
4815     VkImageCreateInfo imageCreateInfo{
4816         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
4817         DE_NULL,                                                           // const void* pNext;
4818         0,                                                                 // VkImageCreateFlags flags;
4819         VK_IMAGE_TYPE_2D,                                                  // VkImageType imageType;
4820         VK_FORMAT_R32G32B32A32_SFLOAT,                                     // VkFormat format;
4821         {16u, 16u, 1u},                                                    // VkExtent3D extent;
4822         1u,                                                                // uint32_t mipLevels;
4823         1u,                                                                // uint32_t arraySize;
4824         VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
4825         VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
4826         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
4827         VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
4828         1u,                                                                // uint32_t queueFamilyIndexCount;
4829         &queueFamilyIndex,                                                 // const uint32_t* pQueueFamilyIndices;
4830         VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
4831     };
4832 
4833     de::MovePtr<ImageWithMemory> srcImage(
4834         new ImageWithMemory(vk, device, alloc, imageCreateInfo, MemoryRequirement::Any));
4835     imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
4836     de::MovePtr<ImageWithMemory> dstImage(
4837         new ImageWithMemory(vk, device, alloc, imageCreateInfo, MemoryRequirement::Any));
4838 
4839     VkImageMemoryBarrier imageBarriers[2];
4840     imageBarriers[0] = {
4841         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4842         DE_NULL,                                // const void* pNext;
4843         0,                                      // VkAccessFlags srcAccessMask;
4844         VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
4845         VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout oldLayout;
4846         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
4847         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
4848         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
4849         **srcImage,                             // VkImage image;
4850         subresourceRange                        // VkImageSubresourceRange subresourceRange;
4851     };
4852     imageBarriers[1]       = imageBarriers[0];
4853     imageBarriers[1].image = **dstImage;
4854 
4855     beginCommandBuffer(vk, *cmdBuffer);
4856 
4857     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
4858                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
4859                           (const VkBufferMemoryBarrier *)DE_NULL, 2, imageBarriers);
4860     vk.cmdClearColorImage(*cmdBuffer, **srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1,
4861                           &subresourceRange);
4862 
4863     imageBarriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
4864     imageBarriers[0].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
4865     imageBarriers[0].oldLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4866     imageBarriers[0].newLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4867     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
4868                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
4869                           (const VkBufferMemoryBarrier *)DE_NULL, 1, imageBarriers);
4870 
4871     vk.cmdResetQueryPool(*cmdBuffer, *queryPool, 0u, 1u);
4872     vk.cmdBeginQuery(*cmdBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
4873     vk.cmdBlitImage(*cmdBuffer, **srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **dstImage,
4874                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blitRegion, VK_FILTER_NEAREST);
4875     vk.cmdEndQuery(*cmdBuffer, *queryPool, 0u);
4876 
4877     endCommandBuffer(vk, *cmdBuffer);
4878 
4879     // Wait for completion
4880     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
4881 
4882     uint64_t queryResult = 1;
4883     VkResult result      = vk.getQueryPoolResults(device, *queryPool, 0u, 1u, sizeof(uint64_t), &queryResult,
4884                                                   sizeof(uint64_t), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
4885     if (result != VK_SUCCESS)
4886         return tcu::TestStatus::fail("getQueryPoolResults() returned: " + de::toString(getResultStr(result)));
4887 
4888     if (queryResult == 0)
4889         return tcu::TestStatus::pass("pass");
4890 
4891     return tcu::TestStatus::fail("QueryPoolResults incorrect result");
4892 }
4893 
4894 class BlitBetweenIncompatibleFormatsTestCase : public TestCase
4895 {
4896 public:
4897     BlitBetweenIncompatibleFormatsTestCase(tcu::TestContext &context, const std::string &name);
4898 
4899     void checkSupport(vkt::Context &context) const;
4900 
4901     vkt::TestInstance *createInstance(vkt::Context &context) const;
4902 };
4903 
BlitBetweenIncompatibleFormatsTestCase(tcu::TestContext & context,const std::string & name)4904 BlitBetweenIncompatibleFormatsTestCase::BlitBetweenIncompatibleFormatsTestCase(tcu::TestContext &context,
4905                                                                                const std::string &name)
4906     : TestCase(context, name.c_str())
4907 {
4908 }
4909 
checkSupport(vkt::Context & context) const4910 void BlitBetweenIncompatibleFormatsTestCase::checkSupport(vkt::Context &context) const
4911 {
4912     if (!context.getDeviceFeatures().pipelineStatisticsQuery)
4913         TCU_THROW(NotSupportedError, "Pipeline statistics queries are not supported");
4914 }
4915 
createInstance(vkt::Context & context) const4916 vkt::TestInstance *BlitBetweenIncompatibleFormatsTestCase::createInstance(vkt::Context &context) const
4917 {
4918     return new BlitBetweenIncompatibleFormatsTestInstance(context);
4919 }
4920 
4921 struct MultipleGeomStatsParams
4922 {
4923     const bool copy;         // true == copy, false == get
4924     const bool availability; // availability bit or not.
4925     const bool inheritance;  // secondary with inheritance.
4926 };
4927 
4928 class MultipleGeomStatsTestInstance : public vkt::TestInstance
4929 {
4930 public:
MultipleGeomStatsTestInstance(Context & context,const MultipleGeomStatsParams & params)4931     MultipleGeomStatsTestInstance(Context &context, const MultipleGeomStatsParams &params)
4932         : vkt::TestInstance(context)
4933         , m_params(params)
4934     {
4935     }
~MultipleGeomStatsTestInstance(void)4936     virtual ~MultipleGeomStatsTestInstance(void)
4937     {
4938     }
4939 
4940     tcu::TestStatus iterate(void) override;
4941 
4942 protected:
4943     const MultipleGeomStatsParams m_params;
4944 };
4945 
4946 class MultipleGeomStatsTestCase : public vkt::TestCase
4947 {
4948 public:
MultipleGeomStatsTestCase(tcu::TestContext & testCtx,const std::string & name,const MultipleGeomStatsParams & params)4949     MultipleGeomStatsTestCase(tcu::TestContext &testCtx, const std::string &name, const MultipleGeomStatsParams &params)
4950         : vkt::TestCase(testCtx, name)
4951         , m_params(params)
4952     {
4953     }
~MultipleGeomStatsTestCase(void)4954     virtual ~MultipleGeomStatsTestCase(void)
4955     {
4956     }
4957 
4958     void initPrograms(vk::SourceCollections &programCollection) const override;
4959     TestInstance *createInstance(Context &context) const override;
4960     void checkSupport(Context &context) const override;
4961 
4962 protected:
4963     const MultipleGeomStatsParams m_params;
4964 };
4965 
initPrograms(vk::SourceCollections & programCollection) const4966 void MultipleGeomStatsTestCase::initPrograms(vk::SourceCollections &programCollection) const
4967 {
4968     std::ostringstream vert;
4969     vert << "#version 460\n"
4970          << "layout (location=0) in vec4 inPos;\n"
4971          << "out gl_PerVertex\n"
4972          << "{\n"
4973          << "    vec4 gl_Position;\n"
4974          << "};\n"
4975          << "void main (void) {\n"
4976          << "    gl_Position = inPos;\n"
4977          << "}\n";
4978     programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
4979 
4980     std::ostringstream geom;
4981     geom << "#version 450\n"
4982          << "layout (triangles) in;\n"
4983          << "layout (triangle_strip, max_vertices=" << kTriangleVertices << ") out;\n"
4984          << "in gl_PerVertex\n"
4985          << "{\n"
4986          << "    vec4 gl_Position;\n"
4987          << "} gl_in[" << kTriangleVertices << "];\n"
4988          << "out gl_PerVertex\n"
4989          << "{\n"
4990          << "    vec4 gl_Position;\n"
4991          << "};\n"
4992          << "void main() {\n";
4993     for (uint32_t i = 0; i < kTriangleVertices; ++i)
4994     {
4995         geom << "    gl_Position = gl_in[" << i << "].gl_Position;\n"
4996              << "    EmitVertex();\n";
4997     }
4998     geom << "}\n";
4999     programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
5000 
5001     std::ostringstream frag;
5002     frag << "#version 460\n"
5003          << "layout (location=0) out vec4 outColor;\n"
5004          << "void main (void) {\n"
5005          << "    outColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
5006          << "}\n";
5007     programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
5008 }
5009 
createInstance(Context & context) const5010 TestInstance *MultipleGeomStatsTestCase::createInstance(Context &context) const
5011 {
5012     return new MultipleGeomStatsTestInstance(context, m_params);
5013 }
5014 
checkSupport(Context & context) const5015 void MultipleGeomStatsTestCase::checkSupport(Context &context) const
5016 {
5017     context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
5018     context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY);
5019 
5020     if (m_params.inheritance)
5021         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_INHERITED_QUERIES);
5022 }
5023 
iterate(void)5024 tcu::TestStatus MultipleGeomStatsTestInstance::iterate(void)
5025 {
5026     const auto &ctx = m_context.getContextCommonData();
5027     const tcu::IVec3 fbExtent(16, 16, 1);
5028     const auto vkExtent  = makeExtent3D(fbExtent);
5029     const auto fbFormat  = VK_FORMAT_R8G8B8A8_UNORM;
5030     const auto tcuFormat = mapVkFormat(fbFormat);
5031     const auto fbUsage   = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
5032     const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
5033     const tcu::Vec4 geomColor(0.0f, 0.0f, 1.0f, 1.0f); // Must match frag shader.
5034     const tcu::Vec4 threshold(0.0f, 0.0f, 0.0f, 0.0f); // When using 0 and 1 only, we expect exact results.
5035     const auto bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
5036 
5037     // Color buffer with verification buffer.
5038     ImageWithBuffer colorBuffer(ctx.vkd, ctx.device, ctx.allocator, vkExtent, fbFormat, fbUsage, VK_IMAGE_TYPE_2D);
5039 
5040     // Vertices.
5041     std::vector<tcu::Vec4> vertices;
5042     const auto imageWidth  = static_cast<float>(fbExtent.x());
5043     const auto imageHeight = static_cast<float>(fbExtent.y());
5044     const auto pixelWidth  = 2.0f / imageWidth;
5045     const auto pixelHeight = 2.0f / imageHeight;
5046     const auto horMargin   = pixelWidth / 4.0f;
5047     const auto vertMargin  = pixelHeight / 4.0f;
5048 
5049     vertices.reserve(vkExtent.width * vkExtent.height * kTriangleVertices);
5050 
5051     for (uint32_t y = 0u; y < vkExtent.height; ++y)
5052         for (uint32_t x = 0u; x < vkExtent.width; ++x)
5053         {
5054             // Pixel center in normalized coordinates.
5055             const auto pixX = (static_cast<float>(x) + 0.5f) / imageWidth * 2.0f - 1.0f;
5056             const auto pixY = (static_cast<float>(y) + 0.5f) / imageHeight * 2.0f - 1.0f;
5057 
5058             // Triangle around pixel center.
5059             vertices.push_back(tcu::Vec4(pixX - horMargin, pixY + vertMargin, 0.0f, 1.0f));
5060             vertices.push_back(tcu::Vec4(pixX + horMargin, pixY + vertMargin, 0.0f, 1.0f));
5061             vertices.push_back(tcu::Vec4(pixX, pixY - vertMargin, 0.0f, 1.0f));
5062         }
5063 
5064     // Vertex buffer
5065     const auto vbSize = static_cast<VkDeviceSize>(de::dataSize(vertices));
5066     const auto vbInfo = makeBufferCreateInfo(vbSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
5067     BufferWithMemory vertexBuffer(ctx.vkd, ctx.device, ctx.allocator, vbInfo, MemoryRequirement::HostVisible);
5068     const auto vbAlloc  = vertexBuffer.getAllocation();
5069     void *vbData        = vbAlloc.getHostPtr();
5070     const auto vbOffset = static_cast<VkDeviceSize>(0);
5071 
5072     deMemcpy(vbData, de::dataOrNull(vertices), de::dataSize(vertices));
5073     flushAlloc(ctx.vkd, ctx.device, vbAlloc); // strictly speaking, not needed.
5074 
5075     const auto pipelineLayout = makePipelineLayout(ctx.vkd, ctx.device);
5076     const auto renderPass     = makeRenderPass(ctx.vkd, ctx.device, fbFormat);
5077     const auto framebuffer =
5078         makeFramebuffer(ctx.vkd, ctx.device, *renderPass, colorBuffer.getImageView(), vkExtent.width, vkExtent.height);
5079 
5080     // Modules.
5081     const auto &binaries  = m_context.getBinaryCollection();
5082     const auto vertModule = createShaderModule(ctx.vkd, ctx.device, binaries.get("vert"));
5083     const auto geomModule = createShaderModule(ctx.vkd, ctx.device, binaries.get("geom"));
5084     const auto fragModule = createShaderModule(ctx.vkd, ctx.device, binaries.get("frag"));
5085 
5086     const std::vector<VkViewport> viewports(1u, makeViewport(vkExtent));
5087     const std::vector<VkRect2D> scissors(1u, makeRect2D(vkExtent));
5088 
5089     const auto pipeline = makeGraphicsPipeline(
5090         ctx.vkd, ctx.device, *pipelineLayout, *vertModule, VK_NULL_HANDLE, VK_NULL_HANDLE, *geomModule, *fragModule,
5091         *renderPass, viewports,
5092         scissors); // The default values works for the current setup, including the vertex input data format.
5093 
5094     CommandPoolWithBuffer cmd(ctx.vkd, ctx.device, ctx.qfIndex);
5095     const auto cmdBuffer = *cmd.cmdBuffer;
5096 
5097     const VkQueryPipelineStatisticFlags stats = (VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT |
5098                                                  VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT);
5099 
5100     const VkQueryPoolCreateInfo queryPoolCreateInfo = {
5101         VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType;
5102         nullptr,                                  // const void* pNext;
5103         0u,                                       // VkQueryPoolCreateFlags flags;
5104         VK_QUERY_TYPE_PIPELINE_STATISTICS,        // VkQueryType queryType;
5105         1u,                                       // uint32_t queryCount;
5106         stats,                                    // VkQueryPipelineStatisticFlags pipelineStatistics;
5107     };
5108     const auto queryPool         = createQueryPool(ctx.vkd, ctx.device, &queryPoolCreateInfo);
5109     const auto perQueryItemCount = (2u + (m_params.availability ? 1u : 0u));
5110     const VkQueryResultFlags resultFlags =
5111         (VK_QUERY_RESULT_WAIT_BIT | (m_params.availability ? VK_QUERY_RESULT_WITH_AVAILABILITY_BIT : 0));
5112     std::vector<uint32_t> queryResults(perQueryItemCount, 0);
5113 
5114     std::unique_ptr<BufferWithMemory> resultsBuffer;
5115     if (m_params.copy)
5116     {
5117         const auto resultsBufferCreateInfo = makeBufferCreateInfo(static_cast<VkDeviceSize>(de::dataSize(queryResults)),
5118                                                                   VK_BUFFER_USAGE_TRANSFER_DST_BIT);
5119         resultsBuffer.reset(new BufferWithMemory(ctx.vkd, ctx.device, ctx.allocator, resultsBufferCreateInfo,
5120                                                  MemoryRequirement::HostVisible));
5121         deMemset(resultsBuffer->getAllocation().getHostPtr(), 0xFF, de::dataSize(queryResults));
5122         flushAlloc(ctx.vkd, ctx.device, resultsBuffer->getAllocation());
5123     }
5124 
5125     Move<VkCommandBuffer> secCmdBuffer;
5126     if (m_params.inheritance)
5127     {
5128         secCmdBuffer = allocateCommandBuffer(ctx.vkd, ctx.device, *cmd.cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
5129         const auto usageFlags =
5130             (VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
5131 
5132         const VkCommandBufferInheritanceInfo inheritanceInfo = {
5133             VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
5134             nullptr,                                           // const void* pNext;
5135             *renderPass,                                       // VkRenderPass renderPass;
5136             0u,                                                // uint32_t subpass;
5137             *framebuffer,                                      // VkFramebuffer framebuffer;
5138             VK_FALSE,                                          // VkBool32 occlusionQueryEnable;
5139             0u,                                                // VkQueryControlFlags queryFlags;
5140             stats,                                             // VkQueryPipelineStatisticFlags pipelineStatistics;
5141         };
5142         const VkCommandBufferBeginInfo beginInfo = {
5143             VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
5144             nullptr,                                     // const void* pNext;
5145             usageFlags,                                  // VkCommandBufferUsageFlags flags;
5146             &inheritanceInfo,                            // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
5147         };
5148         ctx.vkd.beginCommandBuffer(*secCmdBuffer, &beginInfo);
5149     }
5150 
5151     // Render pass contents command buffer.
5152     const auto rpCmdBuffer = (m_params.inheritance ? *secCmdBuffer : *cmd.cmdBuffer);
5153     const auto subpassContents =
5154         (m_params.inheritance ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE);
5155 
5156     beginCommandBuffer(ctx.vkd, cmdBuffer);
5157     ctx.vkd.cmdResetQueryPool(cmdBuffer, *queryPool, 0u, 1u);
5158     ctx.vkd.cmdBeginQuery(cmdBuffer, *queryPool, 0u, 0u);
5159     beginRenderPass(ctx.vkd, cmdBuffer, *renderPass, *framebuffer, scissors.at(0u), clearColor, subpassContents);
5160     {
5161         ctx.vkd.cmdBindVertexBuffers(rpCmdBuffer, 0u, 1u, &vertexBuffer.get(), &vbOffset);
5162         ctx.vkd.cmdBindPipeline(rpCmdBuffer, bindPoint, *pipeline);
5163         ctx.vkd.cmdDraw(rpCmdBuffer, de::sizeU32(vertices), 1u, 0u, 0u);
5164     }
5165     if (m_params.inheritance)
5166     {
5167         endCommandBuffer(ctx.vkd, *secCmdBuffer);
5168         ctx.vkd.cmdExecuteCommands(*cmd.cmdBuffer, 1u, &secCmdBuffer.get());
5169     }
5170     endRenderPass(ctx.vkd, cmdBuffer);
5171     ctx.vkd.cmdEndQuery(cmdBuffer, *queryPool, 0u);
5172     copyImageToBuffer(ctx.vkd, cmdBuffer, colorBuffer.getImage(), colorBuffer.getBuffer(), fbExtent.swizzle(0, 1),
5173                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1u,
5174                       VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
5175                       VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
5176     if (m_params.copy)
5177     {
5178         ctx.vkd.cmdCopyQueryPoolResults(cmdBuffer, *queryPool, 0u, 1u, resultsBuffer->get(), 0ull, 0ull, resultFlags);
5179         const auto queryResultsBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
5180         cmdPipelineMemoryBarrier(ctx.vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
5181                                  &queryResultsBarrier);
5182     }
5183     endCommandBuffer(ctx.vkd, cmdBuffer);
5184     submitCommandsAndWait(ctx.vkd, ctx.device, ctx.queue, cmdBuffer);
5185 
5186     // Verify query results.
5187     if (m_params.copy)
5188     {
5189         invalidateAlloc(ctx.vkd, ctx.device, resultsBuffer->getAllocation());
5190         deMemcpy(de::dataOrNull(queryResults), resultsBuffer->getAllocation().getHostPtr(), de::dataSize(queryResults));
5191     }
5192     else
5193     {
5194         ctx.vkd.getQueryPoolResults(ctx.device, *queryPool, 0u, 1u, de::dataSize(queryResults),
5195                                     de::dataOrNull(queryResults), 0ull, resultFlags);
5196     }
5197 
5198     for (uint32_t queryItem = 0u; queryItem < perQueryItemCount; ++queryItem)
5199     {
5200         const bool isAvailabilityBit = (m_params.availability && queryItem == perQueryItemCount - 1u);
5201         const auto minValue          = (isAvailabilityBit ? 1u : de::sizeU32(vertices) / kTriangleVertices);
5202 	const auto maxValue   	     = std::numeric_limits<uint32_t>::max();
5203         const auto &value            = queryResults.at(queryItem);
5204 
5205         if (value < minValue || value > maxValue)
5206         {
5207             std::ostringstream msg;
5208             msg << "Unexpected value for query item " << queryItem << ": " << value << " out of expected range ["
5209                 << minValue << ", " << maxValue << "]";
5210             TCU_FAIL(msg.str());
5211         }
5212     }
5213 
5214     // Verify color output.
5215     invalidateAlloc(ctx.vkd, ctx.device, colorBuffer.getBufferAllocation());
5216     tcu::PixelBufferAccess resultAccess(tcuFormat, fbExtent, colorBuffer.getBufferAllocation().getHostPtr());
5217 
5218     auto &log = m_context.getTestContext().getLog();
5219     if (!tcu::floatThresholdCompare(log, "Result", "", geomColor, resultAccess, threshold, tcu::COMPARE_LOG_ON_ERROR))
5220         return tcu::TestStatus::fail("Unexpected color in result buffer; check log for details");
5221 
5222     return tcu::TestStatus::pass("Pass");
5223 }
5224 
5225 } // namespace
5226 
QueryPoolStatisticsTests(tcu::TestContext & testCtx)5227 QueryPoolStatisticsTests::QueryPoolStatisticsTests(tcu::TestContext &testCtx)
5228     : TestCaseGroup(testCtx, "statistics_query")
5229 {
5230 }
5231 
bitPrefix(bool query64bits,bool dstOffset)5232 inline std::string bitPrefix(bool query64bits, bool dstOffset)
5233 {
5234     std::string prefix = (query64bits ? "64bits_" : "32bits_");
5235     prefix += (dstOffset ? "dstoffset_" : "");
5236     return prefix;
5237 }
5238 
init(void)5239 void QueryPoolStatisticsTests::init(void)
5240 {
5241     std::string topology_name[VK_PRIMITIVE_TOPOLOGY_LAST] = {"point_list",
5242                                                              "line_list",
5243                                                              "line_strip",
5244                                                              "triangle_list",
5245                                                              "triangle_strip",
5246                                                              "triangle_fan",
5247                                                              "line_list_with_adjacency",
5248                                                              "line_strip_with_adjacency",
5249                                                              "triangle_list_with_adjacency",
5250                                                              "triangle_strip_with_adjacency",
5251                                                              "patch_list"};
5252 
5253     std::vector<uint64_t> sixRepeats = {1, 3, 5, 8, 15, 24};
5254     de::MovePtr<TestCaseGroup> computeShaderInvocationsGroup(
5255         new TestCaseGroup(m_testCtx, "compute_shader_invocations"));
5256     de::MovePtr<TestCaseGroup> inputAssemblyVertices(new TestCaseGroup(m_testCtx, "input_assembly_vertices"));
5257     de::MovePtr<TestCaseGroup> inputAssemblyPrimitives(new TestCaseGroup(m_testCtx, "input_assembly_primitives"));
5258     de::MovePtr<TestCaseGroup> vertexShaderInvocations(new TestCaseGroup(m_testCtx, "vertex_shader_invocations"));
5259     de::MovePtr<TestCaseGroup> fragmentShaderInvocations(new TestCaseGroup(m_testCtx, "fragment_shader_invocations"));
5260     de::MovePtr<TestCaseGroup> geometryShaderInvocations(new TestCaseGroup(m_testCtx, "geometry_shader_invocations"));
5261     de::MovePtr<TestCaseGroup> geometryShaderPrimitives(new TestCaseGroup(m_testCtx, "geometry_shader_primitives"));
5262     de::MovePtr<TestCaseGroup> clippingInvocations(new TestCaseGroup(m_testCtx, "clipping_invocations"));
5263     de::MovePtr<TestCaseGroup> clippingPrimitives(new TestCaseGroup(m_testCtx, "clipping_primitives"));
5264     de::MovePtr<TestCaseGroup> tesControlPatches(new TestCaseGroup(m_testCtx, "tes_control_patches"));
5265     de::MovePtr<TestCaseGroup> tesEvaluationShaderInvocations(
5266         new TestCaseGroup(m_testCtx, "tes_evaluation_shader_invocations"));
5267 
5268     de::MovePtr<TestCaseGroup> vertexOnlyGroup(new TestCaseGroup(m_testCtx, "vertex_only"));
5269     de::MovePtr<TestCaseGroup> inputAssemblyVerticesVertexOnly(new TestCaseGroup(m_testCtx, "input_assembly_vertices"));
5270     de::MovePtr<TestCaseGroup> inputAssemblyPrimitivesVertexOnly(
5271         new TestCaseGroup(m_testCtx, "input_assembly_primitives"));
5272     de::MovePtr<TestCaseGroup> vertexShaderInvocationsVertexOnly(
5273         new TestCaseGroup(m_testCtx, "vertex_shader_invocations"));
5274 
5275     de::MovePtr<TestCaseGroup> hostQueryResetGroup(new TestCaseGroup(m_testCtx, "host_query_reset"));
5276     de::MovePtr<TestCaseGroup> computeShaderInvocationsGroupHostQueryReset(
5277         new TestCaseGroup(m_testCtx, "compute_shader_invocations"));
5278     de::MovePtr<TestCaseGroup> inputAssemblyVerticesHostQueryReset(
5279         new TestCaseGroup(m_testCtx, "input_assembly_vertices"));
5280     de::MovePtr<TestCaseGroup> inputAssemblyPrimitivesHostQueryReset(
5281         new TestCaseGroup(m_testCtx, "input_assembly_primitives"));
5282     de::MovePtr<TestCaseGroup> vertexShaderInvocationsHostQueryReset(
5283         new TestCaseGroup(m_testCtx, "vertex_shader_invocations"));
5284     de::MovePtr<TestCaseGroup> fragmentShaderInvocationsHostQueryReset(
5285         new TestCaseGroup(m_testCtx, "fragment_shader_invocations"));
5286     de::MovePtr<TestCaseGroup> geometryShaderInvocationsHostQueryReset(
5287         new TestCaseGroup(m_testCtx, "geometry_shader_invocations"));
5288     de::MovePtr<TestCaseGroup> geometryShaderPrimitivesHostQueryReset(
5289         new TestCaseGroup(m_testCtx, "geometry_shader_primitives"));
5290     de::MovePtr<TestCaseGroup> clippingInvocationsHostQueryReset(new TestCaseGroup(m_testCtx, "clipping_invocations"));
5291     de::MovePtr<TestCaseGroup> clippingPrimitivesHostQueryReset(new TestCaseGroup(m_testCtx, "clipping_primitives"));
5292     de::MovePtr<TestCaseGroup> tesControlPatchesHostQueryReset(new TestCaseGroup(m_testCtx, "tes_control_patches"));
5293     de::MovePtr<TestCaseGroup> tesEvaluationShaderInvocationsHostQueryReset(
5294         new TestCaseGroup(m_testCtx, "tes_evaluation_shader_invocations"));
5295 
5296     de::MovePtr<TestCaseGroup> resetBeforeCopyGroup(new TestCaseGroup(m_testCtx, "reset_before_copy"));
5297     de::MovePtr<TestCaseGroup> computeShaderInvocationsGroupResetBeforeCopy(
5298         new TestCaseGroup(m_testCtx, "compute_shader_invocations"));
5299     de::MovePtr<TestCaseGroup> inputAssemblyVerticesResetBeforeCopy(
5300         new TestCaseGroup(m_testCtx, "input_assembly_vertices"));
5301     de::MovePtr<TestCaseGroup> inputAssemblyPrimitivesResetBeforeCopy(
5302         new TestCaseGroup(m_testCtx, "input_assembly_primitives"));
5303     de::MovePtr<TestCaseGroup> vertexShaderInvocationsResetBeforeCopy(
5304         new TestCaseGroup(m_testCtx, "vertex_shader_invocations"));
5305     de::MovePtr<TestCaseGroup> fragmentShaderInvocationsResetBeforeCopy(
5306         new TestCaseGroup(m_testCtx, "fragment_shader_invocations"));
5307     de::MovePtr<TestCaseGroup> geometryShaderInvocationsResetBeforeCopy(
5308         new TestCaseGroup(m_testCtx, "geometry_shader_invocations"));
5309     de::MovePtr<TestCaseGroup> geometryShaderPrimitivesResetBeforeCopy(
5310         new TestCaseGroup(m_testCtx, "geometry_shader_primitives"));
5311     de::MovePtr<TestCaseGroup> clippingInvocationsResetBeforeCopy(new TestCaseGroup(m_testCtx, "clipping_invocations"));
5312     de::MovePtr<TestCaseGroup> clippingPrimitivesResetBeforeCopy(new TestCaseGroup(m_testCtx, "clipping_primitives"));
5313     de::MovePtr<TestCaseGroup> tesControlPatchesResetBeforeCopy(new TestCaseGroup(m_testCtx, "tes_control_patches"));
5314     de::MovePtr<TestCaseGroup> tesEvaluationShaderInvocationsResetBeforeCopy(
5315         new TestCaseGroup(m_testCtx, "tes_evaluation_shader_invocations"));
5316 
5317     de::MovePtr<TestCaseGroup> resetAfterCopyGroup(new TestCaseGroup(m_testCtx, "reset_after_copy"));
5318     de::MovePtr<TestCaseGroup> computeShaderInvocationsGroupResetAfterCopy(
5319         new TestCaseGroup(m_testCtx, "compute_shader_invocations"));
5320     de::MovePtr<TestCaseGroup> inputAssemblyVerticesResetAfterCopy(
5321         new TestCaseGroup(m_testCtx, "input_assembly_vertices"));
5322     de::MovePtr<TestCaseGroup> inputAssemblyPrimitivesResetAfterCopy(
5323         new TestCaseGroup(m_testCtx, "input_assembly_primitives"));
5324     de::MovePtr<TestCaseGroup> vertexShaderInvocationsResetAfterCopy(
5325         new TestCaseGroup(m_testCtx, "vertex_shader_invocations"));
5326     de::MovePtr<TestCaseGroup> fragmentShaderInvocationsResetAfterCopy(
5327         new TestCaseGroup(m_testCtx, "fragment_shader_invocations"));
5328     de::MovePtr<TestCaseGroup> geometryShaderInvocationsResetAfterCopy(
5329         new TestCaseGroup(m_testCtx, "geometry_shader_invocations"));
5330     de::MovePtr<TestCaseGroup> geometryShaderPrimitivesResetAfterCopy(
5331         new TestCaseGroup(m_testCtx, "geometry_shader_primitives"));
5332     de::MovePtr<TestCaseGroup> clippingInvocationsResetAfterCopy(new TestCaseGroup(m_testCtx, "clipping_invocations"));
5333     de::MovePtr<TestCaseGroup> clippingPrimitivesResetAfterCopy(new TestCaseGroup(m_testCtx, "clipping_primitives"));
5334     de::MovePtr<TestCaseGroup> tesControlPatchesResetAfterCopy(new TestCaseGroup(m_testCtx, "tes_control_patches"));
5335     de::MovePtr<TestCaseGroup> tesEvaluationShaderInvocationsResetAfterCopy(
5336         new TestCaseGroup(m_testCtx, "tes_evaluation_shader_invocations"));
5337 
5338     de::MovePtr<TestCaseGroup> vertexShaderMultipleQueries(new TestCaseGroup(m_testCtx, "multiple_queries"));
5339     de::MovePtr<TestCaseGroup> multipleGeomStats(new TestCaseGroup(m_testCtx, "multiple_geom_stats"));
5340 
5341     CopyType copyType[]       = {COPY_TYPE_GET, COPY_TYPE_CMD};
5342     std::string copyTypeStr[] = {"", "cmdcopyquerypoolresults_"};
5343 
5344     StrideType strideType[]     = {STRIDE_TYPE_VALID, STRIDE_TYPE_ZERO};
5345     std::string strideTypeStr[] = {"", "stride_zero_"};
5346 
5347     for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
5348     {
5349         for (uint32_t i = 0; i < 4; ++i)
5350         {
5351             bool query64Bits   = (i & 1);
5352             bool dstOffset     = (i & 2);
5353             std::string prefix = bitPrefix(query64Bits, dstOffset);
5354 
5355             // It makes no sense to use dstOffset with vkGetQueryPoolResults()
5356             if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
5357                 continue;
5358 
5359             //VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT
5360 
5361             for (const auto computeQueue : {false, true})
5362             {
5363                 const std::string cqSuffix = (computeQueue ? "_cq" : "");
5364 
5365                 for (uint32_t strideTypeIdx = 0; strideTypeIdx < DE_LENGTH_OF_ARRAY(strideType); strideTypeIdx++)
5366                 {
5367                     if (strideType[strideTypeIdx] == STRIDE_TYPE_ZERO && copyType[copyTypeIdx] != COPY_TYPE_CMD)
5368                         continue;
5369 
5370                     computeShaderInvocationsGroup->addChild(
5371                         new QueryPoolComputeStatsTest<ComputeInvocationsTestInstance>(
5372                             m_testCtx,
5373                             prefix + copyTypeStr[copyTypeIdx] + strideTypeStr[strideTypeIdx] + "primary" + cqSuffix,
5374                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset,
5375                             strideType[strideTypeIdx]));
5376                     computeShaderInvocationsGroup->addChild(
5377                         new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryTestInstance>(
5378                             m_testCtx,
5379                             prefix + copyTypeStr[copyTypeIdx] + strideTypeStr[strideTypeIdx] + "secondary" + cqSuffix,
5380                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset,
5381                             strideType[strideTypeIdx]));
5382                     computeShaderInvocationsGroup->addChild(
5383                         new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryInheritedTestInstance>(
5384                             m_testCtx,
5385                             prefix + copyTypeStr[copyTypeIdx] + strideTypeStr[strideTypeIdx] + "secondary_inherited" +
5386                                 cqSuffix,
5387                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset,
5388                             strideType[strideTypeIdx]));
5389                 }
5390 
5391                 computeShaderInvocationsGroupHostQueryReset->addChild(
5392                     new QueryPoolComputeStatsTest<ComputeInvocationsTestInstance>(
5393                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + cqSuffix, RESET_TYPE_HOST,
5394                         copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5395                 computeShaderInvocationsGroupHostQueryReset->addChild(
5396                     new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryTestInstance>(
5397                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + cqSuffix, RESET_TYPE_HOST,
5398                         copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5399                 computeShaderInvocationsGroupHostQueryReset->addChild(
5400                     new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryInheritedTestInstance>(
5401                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited" + cqSuffix,
5402                         RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5403 
5404                 computeShaderInvocationsGroupResetBeforeCopy->addChild(
5405                     new QueryPoolComputeStatsTest<ComputeInvocationsTestInstance>(
5406                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + cqSuffix, RESET_TYPE_BEFORE_COPY,
5407                         copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5408                 computeShaderInvocationsGroupResetBeforeCopy->addChild(
5409                     new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryTestInstance>(
5410                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + cqSuffix, RESET_TYPE_BEFORE_COPY,
5411                         copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5412                 computeShaderInvocationsGroupResetBeforeCopy->addChild(
5413                     new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryInheritedTestInstance>(
5414                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited" + cqSuffix,
5415                         RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5416 
5417                 if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5418                 {
5419                     computeShaderInvocationsGroupResetAfterCopy->addChild(
5420                         new QueryPoolComputeStatsTest<ComputeInvocationsTestInstance>(
5421                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + cqSuffix, RESET_TYPE_AFTER_COPY,
5422                             copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5423                     computeShaderInvocationsGroupResetAfterCopy->addChild(
5424                         new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryTestInstance>(
5425                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + cqSuffix,
5426                             RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5427                     computeShaderInvocationsGroupResetAfterCopy->addChild(
5428                         new QueryPoolComputeStatsTest<ComputeInvocationsSecondaryInheritedTestInstance>(
5429                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited" + cqSuffix,
5430                             RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx], query64Bits, computeQueue, dstOffset));
5431                 }
5432             }
5433 
5434             //VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT
5435 
5436             // Tests with no attachments for only primary command to reduce # of test cases.
5437             inputAssemblyVertices->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5438                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary_with_no_color_attachments",
5439                 GraphicBasicTestInstance::ParametersGraphic(
5440                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5441                     RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5442                 sixRepeats));
5443             inputAssemblyVerticesVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5444                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary_with_no_color_attachments",
5445                 GraphicBasicTestInstance::ParametersGraphic(
5446                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5447                     RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5448                 sixRepeats));
5449             inputAssemblyVerticesHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5450                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary_with_no_color_attachments",
5451                 GraphicBasicTestInstance::ParametersGraphic(
5452                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5453                     RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5454                 sixRepeats));
5455             inputAssemblyVerticesResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5456                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary_with_no_color_attachments",
5457                 GraphicBasicTestInstance::ParametersGraphic(
5458                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5459                     RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5460                 sixRepeats));
5461 
5462             if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5463                 inputAssemblyVerticesResetAfterCopy->addChild(
5464                     new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5465                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary_with_no_color_attachments",
5466                         GraphicBasicTestInstance::ParametersGraphic(
5467                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5468                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5469                             false, dstOffset, CLEAR_NOOP, true),
5470                         sixRepeats));
5471 
5472             /* Tests for clear operation within a statistics query activated.
5473              * The query shouldn't count internal driver operations relevant to the clear operations.
5474              */
5475             const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
5476             const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
5477 
5478             for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
5479             {
5480                 inputAssemblyVertices->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5481                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + clearOpStr[clearOpIdx],
5482                     GraphicBasicTestInstance::ParametersGraphic(
5483                         VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5484                         RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5485                     sixRepeats));
5486                 inputAssemblyVertices->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5487                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + clearOpStr[clearOpIdx],
5488                     GraphicBasicTestInstance::ParametersGraphic(
5489                         VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5490                         RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5491                     sixRepeats));
5492 
5493                 inputAssemblyVerticesVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5494                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + clearOpStr[clearOpIdx],
5495                     GraphicBasicTestInstance::ParametersGraphic(
5496                         VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5497                         RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, true, dstOffset, clearOp[clearOpIdx]),
5498                     sixRepeats));
5499                 inputAssemblyVerticesVertexOnly->addChild(
5500                     new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5501                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + clearOpStr[clearOpIdx],
5502                         GraphicBasicTestInstance::ParametersGraphic(
5503                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5504                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5505                             true, dstOffset, clearOp[clearOpIdx]),
5506                         sixRepeats));
5507 
5508                 inputAssemblyVerticesHostQueryReset->addChild(
5509                     new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5510                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + clearOpStr[clearOpIdx],
5511                         GraphicBasicTestInstance::ParametersGraphic(
5512                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5513                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
5514                             false, dstOffset, clearOp[clearOpIdx]),
5515                         sixRepeats));
5516                 inputAssemblyVerticesHostQueryReset->addChild(
5517                     new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5518                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + clearOpStr[clearOpIdx],
5519                         GraphicBasicTestInstance::ParametersGraphic(
5520                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5521                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
5522                             false, dstOffset, clearOp[clearOpIdx]),
5523                         sixRepeats));
5524 
5525                 inputAssemblyVerticesResetBeforeCopy->addChild(
5526                     new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5527                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + clearOpStr[clearOpIdx],
5528                         GraphicBasicTestInstance::ParametersGraphic(
5529                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5530                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
5531                             query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5532                         sixRepeats));
5533                 inputAssemblyVerticesResetBeforeCopy->addChild(
5534                     new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5535                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + clearOpStr[clearOpIdx],
5536                         GraphicBasicTestInstance::ParametersGraphic(
5537                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5538                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
5539                             query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5540                         sixRepeats));
5541 
5542                 if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5543                 {
5544                     inputAssemblyVerticesResetAfterCopy->addChild(
5545                         new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5546                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "primary" + clearOpStr[clearOpIdx],
5547                             GraphicBasicTestInstance::ParametersGraphic(
5548                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5549                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
5550                                 query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5551                             sixRepeats));
5552                     inputAssemblyVerticesResetAfterCopy->addChild(
5553                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5554                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary" + clearOpStr[clearOpIdx],
5555                             GraphicBasicTestInstance::ParametersGraphic(
5556                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5557                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
5558                                 query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5559                             sixRepeats));
5560                 }
5561             }
5562 
5563             inputAssemblyVertices->addChild(
5564                 new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5565                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",
5566                     GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5567                                                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL,
5568                                                                 copyType[copyTypeIdx], query64Bits, false, dstOffset),
5569                     sixRepeats));
5570 
5571             inputAssemblyVerticesVertexOnly->addChild(
5572                 new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5573                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",
5574                     GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5575                                                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL,
5576                                                                 copyType[copyTypeIdx], query64Bits, true, dstOffset),
5577                     sixRepeats));
5578 
5579             inputAssemblyVerticesHostQueryReset->addChild(
5580                 new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5581                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",
5582                     GraphicBasicTestInstance::ParametersGraphic(VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5583                                                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST,
5584                                                                 copyType[copyTypeIdx], query64Bits, false, dstOffset),
5585                     sixRepeats));
5586 
5587             inputAssemblyVerticesResetBeforeCopy->addChild(
5588                 new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5589                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",
5590                     GraphicBasicTestInstance::ParametersGraphic(
5591                         VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
5592                         RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, false, dstOffset),
5593                     sixRepeats));
5594 
5595             if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5596                 inputAssemblyVerticesResetAfterCopy->addChild(
5597                     new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5598                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "secondary_inherited",
5599                         GraphicBasicTestInstance::ParametersGraphic(
5600                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
5601                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
5602                             query64Bits, false, dstOffset),
5603                         sixRepeats));
5604         }
5605     }
5606 
5607     //VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT
5608     {
5609         de::MovePtr<TestCaseGroup> primary(new TestCaseGroup(m_testCtx, "primary"));
5610         de::MovePtr<TestCaseGroup> secondary(new TestCaseGroup(m_testCtx, "secondary"));
5611         de::MovePtr<TestCaseGroup> secondaryInherited(new TestCaseGroup(m_testCtx, "secondary_inherited"));
5612 
5613         de::MovePtr<TestCaseGroup> primaryVertexOnly(new TestCaseGroup(m_testCtx, "primary"));
5614         de::MovePtr<TestCaseGroup> secondaryVertexOnly(new TestCaseGroup(m_testCtx, "secondary"));
5615         de::MovePtr<TestCaseGroup> secondaryInheritedVertexOnly(new TestCaseGroup(m_testCtx, "secondary_inherited"));
5616 
5617         de::MovePtr<TestCaseGroup> primaryHostQueryReset(new TestCaseGroup(m_testCtx, "primary"));
5618         de::MovePtr<TestCaseGroup> secondaryHostQueryReset(new TestCaseGroup(m_testCtx, "secondary"));
5619         de::MovePtr<TestCaseGroup> secondaryInheritedHostQueryReset(
5620             new TestCaseGroup(m_testCtx, "secondary_inherited"));
5621 
5622         de::MovePtr<TestCaseGroup> primaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "primary"));
5623         de::MovePtr<TestCaseGroup> secondaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "secondary"));
5624         de::MovePtr<TestCaseGroup> secondaryInheritedResetBeforeCopy(
5625             new TestCaseGroup(m_testCtx, "secondary_inherited"));
5626 
5627         de::MovePtr<TestCaseGroup> primaryResetAfterCopy(new TestCaseGroup(m_testCtx, "primary"));
5628         de::MovePtr<TestCaseGroup> secondaryResetAfterCopy(new TestCaseGroup(m_testCtx, "secondary"));
5629         de::MovePtr<TestCaseGroup> secondaryInheritedResetAfterCopy(
5630             new TestCaseGroup(m_testCtx, "secondary_inherited"));
5631 
5632         for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
5633         {
5634             for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
5635                  ++topologyNdx)
5636             {
5637                 for (uint32_t i = 0; i < 4; ++i)
5638                 {
5639                     bool query64Bits   = (i & 1);
5640                     bool dstOffset     = (i & 2);
5641                     std::string prefix = bitPrefix(query64Bits, dstOffset);
5642 
5643                     // It makes no sense to use dstOffset with vkGetQueryPoolResults()
5644                     if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
5645                         continue;
5646 
5647                     // Tests with no attachments for only primary command to reduce # of test cases.
5648                     primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5649                         m_testCtx,
5650                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "_with_no_color_attachments",
5651                         GraphicBasicTestInstance::ParametersGraphic(
5652                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
5653                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5654                         sixRepeats));
5655 
5656                     primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5657                         m_testCtx,
5658                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "_with_no_color_attachments",
5659                         GraphicBasicTestInstance::ParametersGraphic(
5660                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
5661                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5662                         sixRepeats));
5663 
5664                     primaryVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5665                         m_testCtx,
5666                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "_with_no_color_attachments",
5667                         GraphicBasicTestInstance::ParametersGraphic(
5668                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
5669                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5670                         sixRepeats));
5671 
5672                     primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5673                         m_testCtx,
5674                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "_with_no_color_attachments",
5675                         GraphicBasicTestInstance::ParametersGraphic(
5676                             VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
5677                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5678                         sixRepeats));
5679 
5680                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5681                         primaryResetAfterCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5682                             m_testCtx,
5683                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
5684                                 "_with_no_color_attachments",
5685                             GraphicBasicTestInstance::ParametersGraphic(
5686                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5687                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5688                                 false, dstOffset, CLEAR_NOOP, true),
5689                             sixRepeats));
5690 
5691                     /* Tests for clear operation within a statistics query activated.
5692                      * Nothing for secondary_inherited cases can be done since it violates the specification.
5693                      *
5694                      * The query shouldn't count internal driver operations relevant to the clear operations.
5695                      */
5696                     const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
5697                     const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
5698 
5699                     for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
5700                     {
5701                         primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5702                             m_testCtx,
5703                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5704                             GraphicBasicTestInstance::ParametersGraphic(
5705                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5706                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5707                                 false, dstOffset, clearOp[clearOpIdx]),
5708                             sixRepeats));
5709                         secondary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5710                             m_testCtx,
5711                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5712                             GraphicBasicTestInstance::ParametersGraphic(
5713                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5714                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5715                                 false, dstOffset, clearOp[clearOpIdx]),
5716                             sixRepeats));
5717 
5718                         primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5719                             m_testCtx,
5720                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5721                             GraphicBasicTestInstance::ParametersGraphic(
5722                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5723                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
5724                                 false, dstOffset, clearOp[clearOpIdx]),
5725                             sixRepeats));
5726                         secondaryHostQueryReset->addChild(
5727                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5728                                 m_testCtx,
5729                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5730                                 GraphicBasicTestInstance::ParametersGraphic(
5731                                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5732                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx],
5733                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5734                                 sixRepeats));
5735 
5736                         primaryVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5737                             m_testCtx,
5738                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5739                             GraphicBasicTestInstance::ParametersGraphic(
5740                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5741                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5742                                 true, dstOffset, clearOp[clearOpIdx]),
5743                             sixRepeats));
5744                         secondaryVertexOnly->addChild(
5745                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5746                                 m_testCtx,
5747                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5748                                 GraphicBasicTestInstance::ParametersGraphic(
5749                                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5750                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx],
5751                                     query64Bits, true, dstOffset, clearOp[clearOpIdx]),
5752                                 sixRepeats));
5753 
5754                         primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5755                             m_testCtx,
5756                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5757                             GraphicBasicTestInstance::ParametersGraphic(
5758                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5759                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
5760                                 query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5761                             sixRepeats));
5762                         secondaryResetBeforeCopy->addChild(
5763                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5764                                 m_testCtx,
5765                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5766                                 GraphicBasicTestInstance::ParametersGraphic(
5767                                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5768                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
5769                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5770                                 sixRepeats));
5771 
5772                         if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5773                         {
5774                             primaryResetAfterCopy->addChild(
5775                                 new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5776                                     m_testCtx,
5777                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
5778                                         clearOpStr[clearOpIdx],
5779                                     GraphicBasicTestInstance::ParametersGraphic(
5780                                         VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5781                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
5782                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5783                                     sixRepeats));
5784                             secondaryResetAfterCopy->addChild(
5785                                 new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5786                                     m_testCtx,
5787                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
5788                                         clearOpStr[clearOpIdx],
5789                                     GraphicBasicTestInstance::ParametersGraphic(
5790                                         VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5791                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
5792                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
5793                                     sixRepeats));
5794                         }
5795                     }
5796 
5797                     secondaryInherited->addChild(
5798                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5799                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
5800                             GraphicBasicTestInstance::ParametersGraphic(
5801                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5802                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5803                                 false, dstOffset),
5804                             sixRepeats));
5805                     secondaryInheritedHostQueryReset->addChild(
5806                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5807                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
5808                             GraphicBasicTestInstance::ParametersGraphic(
5809                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5810                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
5811                                 false, dstOffset),
5812                             sixRepeats));
5813                     secondaryInheritedVertexOnly->addChild(
5814                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5815                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
5816                             GraphicBasicTestInstance::ParametersGraphic(
5817                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5818                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5819                                 true, dstOffset),
5820                             sixRepeats));
5821                     secondaryInheritedResetBeforeCopy->addChild(
5822                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5823                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
5824                             GraphicBasicTestInstance::ParametersGraphic(
5825                                 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5826                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
5827                                 query64Bits, false, dstOffset),
5828                             sixRepeats));
5829                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5830                         secondaryInheritedResetAfterCopy->addChild(
5831                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
5832                                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
5833                                 GraphicBasicTestInstance::ParametersGraphic(
5834                                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
5835                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
5836                                     query64Bits, false, dstOffset),
5837                                 sixRepeats));
5838                 }
5839             }
5840         }
5841 
5842         inputAssemblyPrimitives->addChild(primary.release());
5843         inputAssemblyPrimitives->addChild(secondary.release());
5844         inputAssemblyPrimitives->addChild(secondaryInherited.release());
5845 
5846         inputAssemblyPrimitivesVertexOnly->addChild(primaryVertexOnly.release());
5847         inputAssemblyPrimitivesVertexOnly->addChild(secondaryVertexOnly.release());
5848         inputAssemblyPrimitivesVertexOnly->addChild(secondaryInheritedVertexOnly.release());
5849 
5850         inputAssemblyPrimitivesHostQueryReset->addChild(primaryHostQueryReset.release());
5851         inputAssemblyPrimitivesHostQueryReset->addChild(secondaryHostQueryReset.release());
5852         inputAssemblyPrimitivesHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
5853 
5854         inputAssemblyPrimitivesResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
5855         inputAssemblyPrimitivesResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
5856         inputAssemblyPrimitivesResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
5857 
5858         inputAssemblyPrimitivesResetAfterCopy->addChild(primaryResetAfterCopy.release());
5859         inputAssemblyPrimitivesResetAfterCopy->addChild(secondaryResetAfterCopy.release());
5860         inputAssemblyPrimitivesResetAfterCopy->addChild(secondaryInheritedResetAfterCopy.release());
5861     }
5862 
5863     //VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT
5864     {
5865         de::MovePtr<TestCaseGroup> primary(new TestCaseGroup(m_testCtx, "primary"));
5866         de::MovePtr<TestCaseGroup> secondary(new TestCaseGroup(m_testCtx, "secondary"));
5867         de::MovePtr<TestCaseGroup> secondaryInherited(new TestCaseGroup(m_testCtx, "secondary_inherited"));
5868 
5869         de::MovePtr<TestCaseGroup> primaryVertexOnly(new TestCaseGroup(m_testCtx, "primary"));
5870         de::MovePtr<TestCaseGroup> secondaryVertexOnly(new TestCaseGroup(m_testCtx, "secondary"));
5871         de::MovePtr<TestCaseGroup> secondaryInheritedVertexOnly(new TestCaseGroup(m_testCtx, "secondary_inherited"));
5872 
5873         de::MovePtr<TestCaseGroup> primaryHostQueryReset(new TestCaseGroup(m_testCtx, "primary"));
5874         de::MovePtr<TestCaseGroup> secondaryHostQueryReset(new TestCaseGroup(m_testCtx, "secondary"));
5875         de::MovePtr<TestCaseGroup> secondaryInheritedHostQueryReset(
5876             new TestCaseGroup(m_testCtx, "secondary_inherited"));
5877 
5878         de::MovePtr<TestCaseGroup> primaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "primary"));
5879         de::MovePtr<TestCaseGroup> secondaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "secondary"));
5880         de::MovePtr<TestCaseGroup> secondaryInheritedResetBeforeCopy(
5881             new TestCaseGroup(m_testCtx, "secondary_inherited"));
5882 
5883         de::MovePtr<TestCaseGroup> primaryResetAfterCopy(new TestCaseGroup(m_testCtx, "primary"));
5884         de::MovePtr<TestCaseGroup> secondaryResetAfterCopy(new TestCaseGroup(m_testCtx, "secondary"));
5885         de::MovePtr<TestCaseGroup> secondaryInheritedResetAfterCopy(
5886             new TestCaseGroup(m_testCtx, "secondary_inherited"));
5887 
5888         for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
5889         {
5890             for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
5891                  ++topologyNdx)
5892             {
5893                 for (uint32_t i = 0; i < 4; ++i)
5894                 {
5895                     bool query64Bits   = (i & 1);
5896                     bool dstOffset     = (i & 2);
5897                     std::string prefix = bitPrefix(query64Bits, dstOffset);
5898 
5899                     // It makes no sense to use dstOffset with vkGetQueryPoolResults()
5900                     if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
5901                         continue;
5902 
5903                     // Tests with no attachments for only primary command to reduce # of test cases.
5904                     primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5905                         m_testCtx,
5906                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
5907                         GraphicBasicTestInstance::ParametersGraphic(
5908                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
5909                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5910                         sixRepeats));
5911 
5912                     primaryVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5913                         m_testCtx,
5914                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
5915                         GraphicBasicTestInstance::ParametersGraphic(
5916                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
5917                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5918                         sixRepeats));
5919 
5920                     primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5921                         m_testCtx,
5922                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
5923                         GraphicBasicTestInstance::ParametersGraphic(
5924                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
5925                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5926                         sixRepeats));
5927 
5928                     primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5929                         m_testCtx,
5930                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
5931                         GraphicBasicTestInstance::ParametersGraphic(
5932                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
5933                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
5934                         sixRepeats));
5935 
5936                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
5937                         primaryResetAfterCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5938                             m_testCtx,
5939                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
5940                                 "with_no_color_attachments",
5941                             GraphicBasicTestInstance::ParametersGraphic(
5942                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
5943                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5944                                 false, dstOffset, CLEAR_NOOP, true),
5945                             sixRepeats));
5946 
5947                     /* Tests for clear operation within a statistics query activated.
5948                      * Nothing for secondary_inherited cases can be done since it violates the specification.
5949                      *
5950                      * The query shouldn't count internal driver operations relevant to the clear operations.
5951                      */
5952                     const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
5953                     const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
5954 
5955                     for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
5956                     {
5957                         primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5958                             m_testCtx,
5959                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5960                             GraphicBasicTestInstance::ParametersGraphic(
5961                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
5962                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5963                                 false, dstOffset, clearOp[clearOpIdx]),
5964                             sixRepeats));
5965                         secondary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5966                             m_testCtx,
5967                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5968                             GraphicBasicTestInstance::ParametersGraphic(
5969                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
5970                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5971                                 false, dstOffset, clearOp[clearOpIdx]),
5972                             sixRepeats));
5973 
5974                         primaryVertexOnly->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5975                             m_testCtx,
5976                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5977                             GraphicBasicTestInstance::ParametersGraphic(
5978                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
5979                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
5980                                 true, dstOffset, clearOp[clearOpIdx]),
5981                             sixRepeats));
5982                         secondaryVertexOnly->addChild(
5983                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
5984                                 m_testCtx,
5985                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5986                                 GraphicBasicTestInstance::ParametersGraphic(
5987                                     VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
5988                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx],
5989                                     query64Bits, true, dstOffset, clearOp[clearOpIdx]),
5990                                 sixRepeats));
5991 
5992                         primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
5993                             m_testCtx,
5994                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
5995                             GraphicBasicTestInstance::ParametersGraphic(
5996                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
5997                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
5998                                 false, dstOffset, clearOp[clearOpIdx]),
5999                             sixRepeats));
6000                         secondaryHostQueryReset->addChild(
6001                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
6002                                 m_testCtx,
6003                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6004                                 GraphicBasicTestInstance::ParametersGraphic(
6005                                     VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6006                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx],
6007                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6008                                 sixRepeats));
6009 
6010                         primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6011                             m_testCtx,
6012                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6013                             GraphicBasicTestInstance::ParametersGraphic(
6014                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6015                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6016                                 query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6017                             sixRepeats));
6018                         secondaryResetBeforeCopy->addChild(
6019                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
6020                                 m_testCtx,
6021                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6022                                 GraphicBasicTestInstance::ParametersGraphic(
6023                                     VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6024                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6025                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6026                                 sixRepeats));
6027 
6028                         if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6029                         {
6030                             primaryResetAfterCopy->addChild(
6031                                 new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6032                                     m_testCtx,
6033                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6034                                         clearOpStr[clearOpIdx],
6035                                     GraphicBasicTestInstance::ParametersGraphic(
6036                                         VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6037                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6038                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6039                                     sixRepeats));
6040                             secondaryResetAfterCopy->addChild(
6041                                 new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
6042                                     m_testCtx,
6043                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6044                                         clearOpStr[clearOpIdx],
6045                                     GraphicBasicTestInstance::ParametersGraphic(
6046                                         VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6047                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6048                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6049                                     sixRepeats));
6050                         }
6051                     }
6052 
6053                     secondaryInherited->addChild(
6054                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6055                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6056                             GraphicBasicTestInstance::ParametersGraphic(
6057                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6058                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6059                                 false, dstOffset),
6060                             sixRepeats));
6061                     secondaryInheritedVertexOnly->addChild(
6062                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6063                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6064                             GraphicBasicTestInstance::ParametersGraphic(
6065                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6066                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6067                                 true, dstOffset),
6068                             sixRepeats));
6069                     secondaryInheritedHostQueryReset->addChild(
6070                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6071                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6072                             GraphicBasicTestInstance::ParametersGraphic(
6073                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6074                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
6075                                 false, dstOffset),
6076                             sixRepeats));
6077                     secondaryInheritedResetBeforeCopy->addChild(
6078                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6079                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6080                             GraphicBasicTestInstance::ParametersGraphic(
6081                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6082                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6083                                 query64Bits, false, dstOffset),
6084                             sixRepeats));
6085                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6086                         secondaryInheritedResetAfterCopy->addChild(
6087                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6088                                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6089                                 GraphicBasicTestInstance::ParametersGraphic(
6090                                     VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6091                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6092                                     query64Bits, false, dstOffset),
6093                                 sixRepeats));
6094                 }
6095             }
6096         }
6097 
6098         vertexShaderInvocations->addChild(primary.release());
6099         vertexShaderInvocations->addChild(secondary.release());
6100         vertexShaderInvocations->addChild(secondaryInherited.release());
6101 
6102         vertexShaderInvocationsVertexOnly->addChild(primaryVertexOnly.release());
6103         vertexShaderInvocationsVertexOnly->addChild(secondaryVertexOnly.release());
6104         vertexShaderInvocationsVertexOnly->addChild(secondaryInheritedVertexOnly.release());
6105 
6106         vertexShaderInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
6107         vertexShaderInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
6108         vertexShaderInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
6109 
6110         vertexShaderInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
6111         vertexShaderInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
6112         vertexShaderInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
6113 
6114         vertexShaderInvocationsResetAfterCopy->addChild(primaryResetAfterCopy.release());
6115         vertexShaderInvocationsResetAfterCopy->addChild(secondaryResetAfterCopy.release());
6116         vertexShaderInvocationsResetAfterCopy->addChild(secondaryInheritedResetAfterCopy.release());
6117     }
6118 
6119     //VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT
6120     {
6121         de::MovePtr<TestCaseGroup> primary(new TestCaseGroup(m_testCtx, "primary"));
6122         de::MovePtr<TestCaseGroup> secondary(new TestCaseGroup(m_testCtx, "secondary"));
6123         de::MovePtr<TestCaseGroup> secondaryInherited(new TestCaseGroup(m_testCtx, "secondary_inherited"));
6124 
6125         de::MovePtr<TestCaseGroup> primaryHostQueryReset(new TestCaseGroup(m_testCtx, "primary"));
6126         de::MovePtr<TestCaseGroup> secondaryHostQueryReset(new TestCaseGroup(m_testCtx, "secondary"));
6127         de::MovePtr<TestCaseGroup> secondaryInheritedHostQueryReset(
6128             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6129 
6130         de::MovePtr<TestCaseGroup> primaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "primary"));
6131         de::MovePtr<TestCaseGroup> secondaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "secondary"));
6132         de::MovePtr<TestCaseGroup> secondaryInheritedResetBeforeCopy(
6133             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6134 
6135         de::MovePtr<TestCaseGroup> primaryResetAfterCopy(new TestCaseGroup(m_testCtx, "primary"));
6136         de::MovePtr<TestCaseGroup> secondaryResetAfterCopy(new TestCaseGroup(m_testCtx, "secondary"));
6137         de::MovePtr<TestCaseGroup> secondaryInheritedResetAfterCopy(
6138             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6139 
6140         for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
6141         {
6142             for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
6143                  ++topologyNdx)
6144             {
6145                 for (uint32_t i = 0; i < 4; ++i)
6146                 {
6147                     bool query64Bits   = (i & 1);
6148                     bool dstOffset     = (i & 2);
6149                     std::string prefix = bitPrefix(query64Bits, dstOffset);
6150 
6151                     // It makes no sense to use dstOffset with vkGetQueryPoolResults()
6152                     if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
6153                         continue;
6154 
6155                     // Tests with no attachments for only primary command to reduce # of test cases.
6156                     primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6157                         m_testCtx,
6158                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6159                         GraphicBasicTestInstance::ParametersGraphic(
6160                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6161                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6162                         sixRepeats));
6163 
6164                     primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6165                         m_testCtx,
6166                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6167                         GraphicBasicTestInstance::ParametersGraphic(
6168                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6169                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6170                         sixRepeats));
6171 
6172                     primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6173                         m_testCtx,
6174                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6175                         GraphicBasicTestInstance::ParametersGraphic(
6176                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6177                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6178                         sixRepeats));
6179 
6180                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6181                         primaryResetAfterCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6182                             m_testCtx,
6183                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6184                                 "with_no_color_attachments",
6185                             GraphicBasicTestInstance::ParametersGraphic(
6186                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6187                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6188                                 false, dstOffset, CLEAR_NOOP, true),
6189                             sixRepeats));
6190 
6191                     /* Tests for clear operation within a statistics query activated.
6192                      * Nothing for secondary_inherited cases can be done since it violates the specification.
6193                      *
6194                      * The query shouldn't count internal driver operations relevant to the clear operations.
6195                      */
6196                     const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
6197                     const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
6198 
6199                     for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
6200                     {
6201                         primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6202                             m_testCtx,
6203                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6204                             GraphicBasicTestInstance::ParametersGraphic(
6205                                 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6206                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6207                                 false, dstOffset, clearOp[clearOpIdx]),
6208                             sixRepeats));
6209                         secondary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
6210                             m_testCtx,
6211                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6212                             GraphicBasicTestInstance::ParametersGraphic(
6213                                 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6214                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6215                                 false, dstOffset),
6216                             sixRepeats));
6217 
6218                         primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6219                             m_testCtx,
6220                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6221                             GraphicBasicTestInstance::ParametersGraphic(
6222                                 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6223                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
6224                                 false, dstOffset, clearOp[clearOpIdx]),
6225                             sixRepeats));
6226                         secondaryHostQueryReset->addChild(
6227                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
6228                                 m_testCtx,
6229                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6230                                 GraphicBasicTestInstance::ParametersGraphic(
6231                                     VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6232                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx],
6233                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6234                                 sixRepeats));
6235 
6236                         primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6237                             m_testCtx,
6238                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6239                             GraphicBasicTestInstance::ParametersGraphic(
6240                                 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6241                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6242                                 query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6243                             sixRepeats));
6244                         secondaryResetBeforeCopy->addChild(
6245                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
6246                                 m_testCtx,
6247                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6248                                 GraphicBasicTestInstance::ParametersGraphic(
6249                                     VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6250                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6251                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6252                                 sixRepeats));
6253 
6254                         if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6255                         {
6256                             primaryResetAfterCopy->addChild(
6257                                 new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6258                                     m_testCtx,
6259                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6260                                         clearOpStr[clearOpIdx],
6261                                     GraphicBasicTestInstance::ParametersGraphic(
6262                                         VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6263                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6264                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6265                                     sixRepeats));
6266                             secondaryResetAfterCopy->addChild(
6267                                 new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryTestInstance>(
6268                                     m_testCtx,
6269                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6270                                         clearOpStr[clearOpIdx],
6271                                     GraphicBasicTestInstance::ParametersGraphic(
6272                                         VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6273                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6274                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6275                                     sixRepeats));
6276                         }
6277                     }
6278 
6279                     secondaryInherited->addChild(
6280                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6281                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6282                             GraphicBasicTestInstance::ParametersGraphic(
6283                                 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6284                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6285                                 false, dstOffset),
6286                             sixRepeats));
6287                     secondaryInheritedHostQueryReset->addChild(
6288                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6289                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6290                             GraphicBasicTestInstance::ParametersGraphic(
6291                                 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6292                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
6293                                 false, dstOffset),
6294                             sixRepeats));
6295                     secondaryInheritedResetBeforeCopy->addChild(
6296                         new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6297                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6298                             GraphicBasicTestInstance::ParametersGraphic(
6299                                 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6300                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6301                                 query64Bits, false, dstOffset),
6302                             sixRepeats));
6303                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6304                         secondaryInheritedResetAfterCopy->addChild(
6305                             new QueryPoolGraphicStatisticsTest<VertexShaderSecondaryInheritedTestInstance>(
6306                                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6307                                 GraphicBasicTestInstance::ParametersGraphic(
6308                                     VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
6309                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6310                                     query64Bits, false, dstOffset),
6311                                 sixRepeats));
6312                 }
6313             }
6314         }
6315 
6316         fragmentShaderInvocations->addChild(primary.release());
6317         fragmentShaderInvocations->addChild(secondary.release());
6318         fragmentShaderInvocations->addChild(secondaryInherited.release());
6319 
6320         fragmentShaderInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
6321         fragmentShaderInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
6322         fragmentShaderInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
6323 
6324         fragmentShaderInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
6325         fragmentShaderInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
6326         fragmentShaderInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
6327 
6328         fragmentShaderInvocationsResetAfterCopy->addChild(primaryResetAfterCopy.release());
6329         fragmentShaderInvocationsResetAfterCopy->addChild(secondaryResetAfterCopy.release());
6330         fragmentShaderInvocationsResetAfterCopy->addChild(secondaryInheritedResetAfterCopy.release());
6331     }
6332 
6333     //VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT
6334     {
6335         de::MovePtr<TestCaseGroup> primary(new TestCaseGroup(m_testCtx, "primary"));
6336         de::MovePtr<TestCaseGroup> secondary(new TestCaseGroup(m_testCtx, "secondary"));
6337         de::MovePtr<TestCaseGroup> secondaryInherited(new TestCaseGroup(m_testCtx, "secondary_inherited"));
6338 
6339         de::MovePtr<TestCaseGroup> primaryHostQueryReset(new TestCaseGroup(m_testCtx, "primary"));
6340         de::MovePtr<TestCaseGroup> secondaryHostQueryReset(new TestCaseGroup(m_testCtx, "secondary"));
6341         de::MovePtr<TestCaseGroup> secondaryInheritedHostQueryReset(
6342             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6343 
6344         de::MovePtr<TestCaseGroup> primaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "primary"));
6345         de::MovePtr<TestCaseGroup> secondaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "secondary"));
6346         de::MovePtr<TestCaseGroup> secondaryInheritedResetBeforeCopy(
6347             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6348 
6349         de::MovePtr<TestCaseGroup> primaryResetAfterCopy(new TestCaseGroup(m_testCtx, "primary"));
6350         de::MovePtr<TestCaseGroup> secondaryResetAfterCopy(new TestCaseGroup(m_testCtx, "secondary"));
6351         de::MovePtr<TestCaseGroup> secondaryInheritedResetAfterCopy(
6352             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6353 
6354         for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
6355         {
6356             for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
6357                  ++topologyNdx)
6358             {
6359                 for (uint32_t i = 0; i < 4; ++i)
6360                 {
6361                     bool query64Bits   = (i & 1);
6362                     bool dstOffset     = (i & 2);
6363                     std::string prefix = bitPrefix(query64Bits, dstOffset);
6364 
6365                     // It makes no sense to use dstOffset with vkGetQueryPoolResults()
6366                     if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
6367                         continue;
6368 
6369                     // Tests with no attachments for only primary command to reduce # of test cases.
6370                     primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6371                         m_testCtx,
6372                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6373                         GraphicBasicTestInstance::ParametersGraphic(
6374                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6375                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6376                         sixRepeats));
6377 
6378                     primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6379                         m_testCtx,
6380                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6381                         GraphicBasicTestInstance::ParametersGraphic(
6382                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6383                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6384                         sixRepeats));
6385 
6386                     primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6387                         m_testCtx,
6388                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6389                         GraphicBasicTestInstance::ParametersGraphic(
6390                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6391                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6392                         sixRepeats));
6393 
6394                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6395                         primaryResetAfterCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6396                             m_testCtx,
6397                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6398                                 "with_no_color_attachments",
6399                             GraphicBasicTestInstance::ParametersGraphic(
6400                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6401                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6402                                 false, dstOffset, CLEAR_NOOP, true),
6403                             sixRepeats));
6404 
6405                     /* Tests for clear operation within a statistics query activated.
6406                      * Nothing for secondary_inherited cases can be done since it violates the specification.
6407                      *
6408                      * The query shouldn't count internal driver operations relevant to the clear operations.
6409                      */
6410                     const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
6411                     const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
6412 
6413                     for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
6414                     {
6415                         primary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6416                             m_testCtx,
6417                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6418                             GraphicBasicTestInstance::ParametersGraphic(
6419                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6420                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6421                                 false, dstOffset, clearOp[clearOpIdx]),
6422                             sixRepeats));
6423                         secondary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6424                             m_testCtx,
6425                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6426                             GraphicBasicTestInstance::ParametersGraphic(
6427                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6428                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6429                                 false, dstOffset, clearOp[clearOpIdx]),
6430                             sixRepeats));
6431 
6432                         primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6433                             m_testCtx,
6434                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6435                             GraphicBasicTestInstance::ParametersGraphic(
6436                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6437                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
6438                                 false, dstOffset, clearOp[clearOpIdx]),
6439                             sixRepeats));
6440                         secondaryHostQueryReset->addChild(
6441                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6442                                 m_testCtx,
6443                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6444                                 GraphicBasicTestInstance::ParametersGraphic(
6445                                     VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6446                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx],
6447                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6448                                 sixRepeats));
6449 
6450                         primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6451                             m_testCtx,
6452                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6453                             GraphicBasicTestInstance::ParametersGraphic(
6454                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6455                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6456                                 query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6457                             sixRepeats));
6458                         secondaryResetBeforeCopy->addChild(
6459                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6460                                 m_testCtx,
6461                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6462                                 GraphicBasicTestInstance::ParametersGraphic(
6463                                     VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6464                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6465                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6466                                 sixRepeats));
6467 
6468                         if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6469                         {
6470                             primaryResetAfterCopy->addChild(
6471                                 new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6472                                     m_testCtx,
6473                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6474                                         clearOpStr[clearOpIdx],
6475                                     GraphicBasicTestInstance::ParametersGraphic(
6476                                         VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6477                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6478                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6479                                     sixRepeats));
6480                             secondaryResetAfterCopy->addChild(
6481                                 new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6482                                     m_testCtx,
6483                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6484                                         clearOpStr[clearOpIdx],
6485                                     GraphicBasicTestInstance::ParametersGraphic(
6486                                         VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6487                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6488                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6489                                     sixRepeats));
6490                         }
6491                     }
6492 
6493                     secondaryInherited->addChild(
6494                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6495                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6496                             GraphicBasicTestInstance::ParametersGraphic(
6497                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6498                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6499                                 false, dstOffset),
6500                             sixRepeats));
6501                     secondaryInheritedHostQueryReset->addChild(
6502                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6503                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6504                             GraphicBasicTestInstance::ParametersGraphic(
6505                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6506                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
6507                                 false, dstOffset),
6508                             sixRepeats));
6509                     secondaryInheritedResetBeforeCopy->addChild(
6510                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6511                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6512                             GraphicBasicTestInstance::ParametersGraphic(
6513                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6514                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6515                                 query64Bits, false, dstOffset),
6516                             sixRepeats));
6517                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6518                         secondaryInheritedResetAfterCopy->addChild(
6519                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6520                                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6521                                 GraphicBasicTestInstance::ParametersGraphic(
6522                                     VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
6523                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6524                                     query64Bits, false, dstOffset),
6525                                 sixRepeats));
6526                 }
6527             }
6528         }
6529 
6530         geometryShaderInvocations->addChild(primary.release());
6531         geometryShaderInvocations->addChild(secondary.release());
6532         geometryShaderInvocations->addChild(secondaryInherited.release());
6533 
6534         geometryShaderInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
6535         geometryShaderInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
6536         geometryShaderInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
6537 
6538         geometryShaderInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
6539         geometryShaderInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
6540         geometryShaderInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
6541 
6542         geometryShaderInvocationsResetAfterCopy->addChild(primaryResetAfterCopy.release());
6543         geometryShaderInvocationsResetAfterCopy->addChild(secondaryResetAfterCopy.release());
6544         geometryShaderInvocationsResetAfterCopy->addChild(secondaryInheritedResetAfterCopy.release());
6545     }
6546 
6547     //VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT
6548     {
6549         de::MovePtr<TestCaseGroup> primary(new TestCaseGroup(m_testCtx, "primary"));
6550         de::MovePtr<TestCaseGroup> secondary(new TestCaseGroup(m_testCtx, "secondary"));
6551         de::MovePtr<TestCaseGroup> secondaryInherited(new TestCaseGroup(m_testCtx, "secondary_inherited"));
6552 
6553         de::MovePtr<TestCaseGroup> primaryHostQueryReset(new TestCaseGroup(m_testCtx, "primary"));
6554         de::MovePtr<TestCaseGroup> secondaryHostQueryReset(new TestCaseGroup(m_testCtx, "secondary"));
6555         de::MovePtr<TestCaseGroup> secondaryInheritedHostQueryReset(
6556             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6557 
6558         de::MovePtr<TestCaseGroup> primaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "primary"));
6559         de::MovePtr<TestCaseGroup> secondaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "secondary"));
6560         de::MovePtr<TestCaseGroup> secondaryInheritedResetBeforeCopy(
6561             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6562 
6563         de::MovePtr<TestCaseGroup> primaryResetAfterCopy(new TestCaseGroup(m_testCtx, "primary"));
6564         de::MovePtr<TestCaseGroup> secondaryResetAfterCopy(new TestCaseGroup(m_testCtx, "secondary"));
6565         de::MovePtr<TestCaseGroup> secondaryInheritedResetAfterCopy(
6566             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6567 
6568         for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
6569         {
6570             for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
6571                  ++topologyNdx)
6572             {
6573                 for (uint32_t i = 0; i < 4; ++i)
6574                 {
6575                     bool query64Bits   = (i & 1);
6576                     bool dstOffset     = (i & 2);
6577                     std::string prefix = bitPrefix(query64Bits, dstOffset);
6578 
6579                     // It makes no sense to use dstOffset with vkGetQueryPoolResults()
6580                     if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
6581                         continue;
6582 
6583                     // Tests with no attachments.
6584                     primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6585                         m_testCtx,
6586                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6587                         GraphicBasicTestInstance::ParametersGraphic(
6588                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6589                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6590                         sixRepeats));
6591 
6592                     primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6593                         m_testCtx,
6594                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6595                         GraphicBasicTestInstance::ParametersGraphic(
6596                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6597                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6598                         sixRepeats));
6599 
6600                     primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6601                         m_testCtx,
6602                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6603                         GraphicBasicTestInstance::ParametersGraphic(
6604                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6605                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6606                         sixRepeats));
6607 
6608                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6609                         primaryResetAfterCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6610                             m_testCtx,
6611                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6612                                 "with_no_color_attachments",
6613                             GraphicBasicTestInstance::ParametersGraphic(
6614                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6615                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6616                                 false, dstOffset, CLEAR_NOOP, true),
6617                             sixRepeats));
6618 
6619                     /* Tests for clear operation within a statistics query activated.
6620                      * Nothing for secondary_inherited cases can be done since it violates the specification.
6621                      *
6622                      * The query shouldn't count internal driver operations relevant to the clear operations.
6623                      */
6624                     const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
6625                     const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
6626 
6627                     for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
6628                     {
6629                         primary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6630                             m_testCtx,
6631                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6632                             GraphicBasicTestInstance::ParametersGraphic(
6633                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6634                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6635                                 false, dstOffset, clearOp[clearOpIdx]),
6636                             sixRepeats));
6637                         secondary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6638                             m_testCtx,
6639                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6640                             GraphicBasicTestInstance::ParametersGraphic(
6641                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6642                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6643                                 false, dstOffset, clearOp[clearOpIdx]),
6644                             sixRepeats));
6645 
6646                         primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6647                             m_testCtx,
6648                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6649                             GraphicBasicTestInstance::ParametersGraphic(
6650                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6651                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
6652                                 false, dstOffset, clearOp[clearOpIdx]),
6653                             sixRepeats));
6654                         secondaryHostQueryReset->addChild(
6655                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6656                                 m_testCtx,
6657                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6658                                 GraphicBasicTestInstance::ParametersGraphic(
6659                                     VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6660                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx],
6661                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6662                                 sixRepeats));
6663 
6664                         primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6665                             m_testCtx,
6666                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6667                             GraphicBasicTestInstance::ParametersGraphic(
6668                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6669                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6670                                 query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6671                             sixRepeats));
6672                         secondaryResetBeforeCopy->addChild(
6673                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6674                                 m_testCtx,
6675                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6676                                 GraphicBasicTestInstance::ParametersGraphic(
6677                                     VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6678                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6679                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6680                                 sixRepeats));
6681 
6682                         if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6683                         {
6684                             primaryResetAfterCopy->addChild(
6685                                 new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6686                                     m_testCtx,
6687                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6688                                         clearOpStr[clearOpIdx],
6689                                     GraphicBasicTestInstance::ParametersGraphic(
6690                                         VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6691                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6692                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6693                                     sixRepeats));
6694                             secondaryResetAfterCopy->addChild(
6695                                 new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6696                                     m_testCtx,
6697                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6698                                         clearOpStr[clearOpIdx],
6699                                     GraphicBasicTestInstance::ParametersGraphic(
6700                                         VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6701                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6702                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6703                                     sixRepeats));
6704                         }
6705                     }
6706                     secondaryInherited->addChild(
6707                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6708                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6709                             GraphicBasicTestInstance::ParametersGraphic(
6710                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6711                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6712                                 false, dstOffset),
6713                             sixRepeats));
6714                     secondaryInheritedHostQueryReset->addChild(
6715                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6716                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6717                             GraphicBasicTestInstance::ParametersGraphic(
6718                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6719                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
6720                                 false, dstOffset),
6721                             sixRepeats));
6722                     secondaryInheritedResetBeforeCopy->addChild(
6723                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6724                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6725                             GraphicBasicTestInstance::ParametersGraphic(
6726                                 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6727                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6728                                 query64Bits, false, dstOffset),
6729                             sixRepeats));
6730                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6731                         secondaryInheritedResetAfterCopy->addChild(
6732                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6733                                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6734                                 GraphicBasicTestInstance::ParametersGraphic(
6735                                     VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
6736                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6737                                     query64Bits, false, dstOffset),
6738                                 sixRepeats));
6739                 }
6740             }
6741         }
6742 
6743         geometryShaderPrimitives->addChild(primary.release());
6744         geometryShaderPrimitives->addChild(secondary.release());
6745         geometryShaderPrimitives->addChild(secondaryInherited.release());
6746 
6747         geometryShaderPrimitivesHostQueryReset->addChild(primaryHostQueryReset.release());
6748         geometryShaderPrimitivesHostQueryReset->addChild(secondaryHostQueryReset.release());
6749         geometryShaderPrimitivesHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
6750 
6751         geometryShaderPrimitivesResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
6752         geometryShaderPrimitivesResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
6753         geometryShaderPrimitivesResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
6754 
6755         geometryShaderPrimitivesResetAfterCopy->addChild(primaryResetAfterCopy.release());
6756         geometryShaderPrimitivesResetAfterCopy->addChild(secondaryResetAfterCopy.release());
6757         geometryShaderPrimitivesResetAfterCopy->addChild(secondaryInheritedResetAfterCopy.release());
6758     }
6759 
6760     //VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT
6761     {
6762         de::MovePtr<TestCaseGroup> primary(new TestCaseGroup(m_testCtx, "primary"));
6763         de::MovePtr<TestCaseGroup> secondary(new TestCaseGroup(m_testCtx, "secondary"));
6764         de::MovePtr<TestCaseGroup> secondaryInherited(new TestCaseGroup(m_testCtx, "secondary_inherited"));
6765 
6766         de::MovePtr<TestCaseGroup> primaryHostQueryReset(new TestCaseGroup(m_testCtx, "primary"));
6767         de::MovePtr<TestCaseGroup> secondaryHostQueryReset(new TestCaseGroup(m_testCtx, "secondary"));
6768         de::MovePtr<TestCaseGroup> secondaryInheritedHostQueryReset(
6769             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6770 
6771         de::MovePtr<TestCaseGroup> primaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "primary"));
6772         de::MovePtr<TestCaseGroup> secondaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "secondary"));
6773         de::MovePtr<TestCaseGroup> secondaryInheritedResetBeforeCopy(
6774             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6775 
6776         de::MovePtr<TestCaseGroup> primaryResetAfterCopy(new TestCaseGroup(m_testCtx, "primary"));
6777         de::MovePtr<TestCaseGroup> secondaryResetAfterCopy(new TestCaseGroup(m_testCtx, "secondary"));
6778         de::MovePtr<TestCaseGroup> secondaryInheritedResetAfterCopy(
6779             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6780 
6781         for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
6782         {
6783             for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
6784                  ++topologyNdx)
6785             {
6786                 for (uint32_t i = 0; i < 4; ++i)
6787                 {
6788                     bool query64Bits   = (i & 1);
6789                     bool dstOffset     = (i & 2);
6790                     std::string prefix = bitPrefix(query64Bits, dstOffset);
6791 
6792                     // It makes no sense to use dstOffset with vkGetQueryPoolResults()
6793                     if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
6794                         continue;
6795 
6796                     // Tests with no attachments for only primary command to reduce # of test cases.
6797                     primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6798                         m_testCtx,
6799                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6800                         GraphicBasicTestInstance::ParametersGraphic(
6801                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6802                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6803                         sixRepeats));
6804 
6805                     primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6806                         m_testCtx,
6807                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6808                         GraphicBasicTestInstance::ParametersGraphic(
6809                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6810                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6811                         sixRepeats));
6812 
6813                     primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6814                         m_testCtx,
6815                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
6816                         GraphicBasicTestInstance::ParametersGraphic(
6817                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6818                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
6819                         sixRepeats));
6820 
6821                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6822                         primaryResetAfterCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
6823                             m_testCtx,
6824                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6825                                 "with_no_color_attachments",
6826                             GraphicBasicTestInstance::ParametersGraphic(
6827                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
6828                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
6829                                 false, dstOffset, CLEAR_NOOP, true),
6830                             sixRepeats));
6831 
6832                     /* Tests for clear operation within a statistics query activated.
6833                      * Nothing for secondary_inherited cases can be done since it violates the specification.
6834                      *
6835                      * The query shouldn't count internal driver operations relevant to the clear operations.
6836                      */
6837                     const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
6838                     const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
6839 
6840                     for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
6841                     {
6842                         primary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6843                             m_testCtx,
6844                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6845                             GraphicBasicTestInstance::ParametersGraphic(
6846                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6847                                 RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset,
6848                                 clearOp[clearOpIdx]),
6849                             sixRepeats));
6850                         secondary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6851                             m_testCtx,
6852                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6853                             GraphicBasicTestInstance::ParametersGraphic(
6854                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6855                                 RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset,
6856                                 clearOp[clearOpIdx]),
6857                             sixRepeats));
6858 
6859                         primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6860                             m_testCtx,
6861                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6862                             GraphicBasicTestInstance::ParametersGraphic(
6863                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6864                                 RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, false, dstOffset,
6865                                 clearOp[clearOpIdx]),
6866                             sixRepeats));
6867                         secondaryHostQueryReset->addChild(
6868                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6869                                 m_testCtx,
6870                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6871                                 GraphicBasicTestInstance::ParametersGraphic(
6872                                     VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT,
6873                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx],
6874                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6875                                 sixRepeats));
6876 
6877                         primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6878                             m_testCtx,
6879                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6880                             GraphicBasicTestInstance::ParametersGraphic(
6881                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6882                                 RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, false, dstOffset,
6883                                 clearOp[clearOpIdx]),
6884                             sixRepeats));
6885                         secondaryResetBeforeCopy->addChild(
6886                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6887                                 m_testCtx,
6888                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
6889                                 GraphicBasicTestInstance::ParametersGraphic(
6890                                     VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT,
6891                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
6892                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6893                                 sixRepeats));
6894 
6895                         if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6896                         {
6897                             primaryResetAfterCopy->addChild(
6898                                 new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
6899                                     m_testCtx,
6900                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6901                                         clearOpStr[clearOpIdx],
6902                                     GraphicBasicTestInstance::ParametersGraphic(
6903                                         VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT,
6904                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6905                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6906                                     sixRepeats));
6907                             secondaryResetAfterCopy->addChild(
6908                                 new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
6909                                     m_testCtx,
6910                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
6911                                         clearOpStr[clearOpIdx],
6912                                     GraphicBasicTestInstance::ParametersGraphic(
6913                                         VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT,
6914                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6915                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
6916                                     sixRepeats));
6917                         }
6918                     }
6919 
6920                     secondaryInherited->addChild(
6921                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6922                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6923                             GraphicBasicTestInstance::ParametersGraphic(
6924                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6925                                 RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset),
6926                             sixRepeats));
6927                     secondaryInheritedHostQueryReset->addChild(
6928                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6929                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6930                             GraphicBasicTestInstance::ParametersGraphic(
6931                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6932                                 RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, false, dstOffset),
6933                             sixRepeats));
6934                     secondaryInheritedResetBeforeCopy->addChild(
6935                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6936                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6937                             GraphicBasicTestInstance::ParametersGraphic(
6938                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
6939                                 RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, false, dstOffset),
6940                             sixRepeats));
6941                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
6942                         secondaryInheritedResetAfterCopy->addChild(
6943                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
6944                                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
6945                                 GraphicBasicTestInstance::ParametersGraphic(
6946                                     VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT,
6947                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
6948                                     query64Bits, false, dstOffset),
6949                                 sixRepeats));
6950                 }
6951             }
6952         }
6953 
6954         // test corner case: on some implementations running queries while blitting between incompatible formats
6955         // falls back to a draw shader, and this may end up erroneously incrementing pipeline statistics results
6956         primary->addChild(new BlitBetweenIncompatibleFormatsTestCase(m_testCtx, "blit_between_incompatible_formats"));
6957 
6958         clippingInvocations->addChild(primary.release());
6959         clippingInvocations->addChild(secondary.release());
6960         clippingInvocations->addChild(secondaryInherited.release());
6961 
6962         clippingInvocationsHostQueryReset->addChild(primaryHostQueryReset.release());
6963         clippingInvocationsHostQueryReset->addChild(secondaryHostQueryReset.release());
6964         clippingInvocationsHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
6965 
6966         clippingInvocationsResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
6967         clippingInvocationsResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
6968         clippingInvocationsResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
6969 
6970         clippingInvocationsResetAfterCopy->addChild(primaryResetAfterCopy.release());
6971         clippingInvocationsResetAfterCopy->addChild(secondaryResetAfterCopy.release());
6972         clippingInvocationsResetAfterCopy->addChild(secondaryInheritedResetAfterCopy.release());
6973     }
6974 
6975     //VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT
6976     {
6977         de::MovePtr<TestCaseGroup> primary(new TestCaseGroup(m_testCtx, "primary"));
6978         de::MovePtr<TestCaseGroup> secondary(new TestCaseGroup(m_testCtx, "secondary"));
6979         de::MovePtr<TestCaseGroup> secondaryInherited(new TestCaseGroup(m_testCtx, "secondary_inherited"));
6980 
6981         de::MovePtr<TestCaseGroup> primaryHostQueryReset(new TestCaseGroup(m_testCtx, "primary"));
6982         de::MovePtr<TestCaseGroup> secondaryHostQueryReset(new TestCaseGroup(m_testCtx, "secondary"));
6983         de::MovePtr<TestCaseGroup> secondaryInheritedHostQueryReset(
6984             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6985 
6986         de::MovePtr<TestCaseGroup> primaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "primary"));
6987         de::MovePtr<TestCaseGroup> secondaryResetBeforeCopy(new TestCaseGroup(m_testCtx, "secondary"));
6988         de::MovePtr<TestCaseGroup> secondaryInheritedResetBeforeCopy(
6989             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6990 
6991         de::MovePtr<TestCaseGroup> primaryResetAfterCopy(new TestCaseGroup(m_testCtx, "primary"));
6992         de::MovePtr<TestCaseGroup> secondaryResetAfterCopy(new TestCaseGroup(m_testCtx, "secondary"));
6993         de::MovePtr<TestCaseGroup> secondaryInheritedResetAfterCopy(
6994             new TestCaseGroup(m_testCtx, "secondary_inherited"));
6995 
6996         for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
6997         {
6998             for (int topologyNdx = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; topologyNdx < VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
6999                  ++topologyNdx)
7000             {
7001                 for (uint32_t i = 0; i < 4; ++i)
7002                 {
7003                     bool query64Bits   = (i & 1);
7004                     bool dstOffset     = (i & 2);
7005                     std::string prefix = bitPrefix(query64Bits, dstOffset);
7006 
7007                     // It makes no sense to use dstOffset with vkGetQueryPoolResults()
7008                     if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
7009                         continue;
7010 
7011                     // Tests with no attachments for only primary command to reduce # of test cases.
7012                     primary->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
7013                         m_testCtx,
7014                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
7015                         GraphicBasicTestInstance::ParametersGraphic(
7016                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
7017                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
7018                         sixRepeats));
7019 
7020                     primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
7021                         m_testCtx,
7022                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
7023                         GraphicBasicTestInstance::ParametersGraphic(
7024                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
7025                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
7026                         sixRepeats));
7027 
7028                     primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
7029                         m_testCtx,
7030                         prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + "with_no_color_attachments",
7031                         GraphicBasicTestInstance::ParametersGraphic(
7032                             VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, (VkPrimitiveTopology)topologyNdx,
7033                             RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset, CLEAR_NOOP, true),
7034                         sixRepeats));
7035 
7036                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7037                         primaryResetAfterCopy->addChild(new QueryPoolGraphicStatisticsTest<VertexShaderTestInstance>(
7038                             m_testCtx,
7039                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
7040                                 "with_no_color_attachments",
7041                             GraphicBasicTestInstance::ParametersGraphic(
7042                                 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
7043                                 (VkPrimitiveTopology)topologyNdx, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
7044                                 false, dstOffset, CLEAR_NOOP, true),
7045                             sixRepeats));
7046 
7047                     /* Tests for clear operation within a statistics query activated.
7048                      * Nothing for secondary_inherited cases can be done since it violates the specification.
7049                      *
7050                      * The query shouldn't count internal driver operations relevant to the clear operations.
7051                      */
7052                     const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
7053                     const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
7054 
7055                     for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
7056                     {
7057                         primary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
7058                             m_testCtx,
7059                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
7060                             GraphicBasicTestInstance::ParametersGraphic(
7061                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
7062                                 RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset,
7063                                 clearOp[clearOpIdx]),
7064                             sixRepeats));
7065                         secondary->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
7066                             m_testCtx,
7067                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
7068                             GraphicBasicTestInstance::ParametersGraphic(
7069                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
7070                                 RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset,
7071                                 clearOp[clearOpIdx]),
7072                             sixRepeats));
7073 
7074                         primaryHostQueryReset->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
7075                             m_testCtx,
7076                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
7077                             GraphicBasicTestInstance::ParametersGraphic(
7078                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
7079                                 RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, false, dstOffset,
7080                                 clearOp[clearOpIdx]),
7081                             sixRepeats));
7082                         secondaryHostQueryReset->addChild(
7083                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
7084                                 m_testCtx,
7085                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
7086                                 GraphicBasicTestInstance::ParametersGraphic(
7087                                     VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT,
7088                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_HOST, copyType[copyTypeIdx],
7089                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
7090                                 sixRepeats));
7091 
7092                         primaryResetBeforeCopy->addChild(new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
7093                             m_testCtx,
7094                             prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
7095                             GraphicBasicTestInstance::ParametersGraphic(
7096                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
7097                                 RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, false, dstOffset,
7098                                 clearOp[clearOpIdx]),
7099                             sixRepeats));
7100                         secondaryResetBeforeCopy->addChild(
7101                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
7102                                 m_testCtx,
7103                                 prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] + clearOpStr[clearOpIdx],
7104                                 GraphicBasicTestInstance::ParametersGraphic(
7105                                     VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT,
7106                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7107                                     query64Bits, false, dstOffset, clearOp[clearOpIdx]),
7108                                 sixRepeats));
7109 
7110                         if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7111                         {
7112                             primaryResetAfterCopy->addChild(
7113                                 new QueryPoolGraphicStatisticsTest<GeometryShaderTestInstance>(
7114                                     m_testCtx,
7115                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
7116                                         clearOpStr[clearOpIdx],
7117                                     GraphicBasicTestInstance::ParametersGraphic(
7118                                         VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT,
7119                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7120                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
7121                                     sixRepeats));
7122                             secondaryResetAfterCopy->addChild(
7123                                 new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryTestInstance>(
7124                                     m_testCtx,
7125                                     prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx] +
7126                                         clearOpStr[clearOpIdx],
7127                                     GraphicBasicTestInstance::ParametersGraphic(
7128                                         VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT,
7129                                         (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7130                                         query64Bits, false, dstOffset, clearOp[clearOpIdx]),
7131                                     sixRepeats));
7132                         }
7133                     }
7134 
7135                     secondaryInherited->addChild(
7136                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
7137                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
7138                             GraphicBasicTestInstance::ParametersGraphic(
7139                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
7140                                 RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false, dstOffset),
7141                             sixRepeats));
7142                     secondaryInheritedHostQueryReset->addChild(
7143                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
7144                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
7145                             GraphicBasicTestInstance::ParametersGraphic(
7146                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
7147                                 RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits, false, dstOffset),
7148                             sixRepeats));
7149                     secondaryInheritedResetBeforeCopy->addChild(
7150                         new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
7151                             m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
7152                             GraphicBasicTestInstance::ParametersGraphic(
7153                                 VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT, (VkPrimitiveTopology)topologyNdx,
7154                                 RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx], query64Bits, false, dstOffset),
7155                             sixRepeats));
7156                     if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7157                         secondaryInheritedResetAfterCopy->addChild(
7158                             new QueryPoolGraphicStatisticsTest<GeometryShaderSecondaryInheritedTestInstance>(
7159                                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + topology_name[topologyNdx],
7160                                 GraphicBasicTestInstance::ParametersGraphic(
7161                                     VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT,
7162                                     (VkPrimitiveTopology)topologyNdx, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7163                                     query64Bits, false, dstOffset),
7164                                 sixRepeats));
7165                 }
7166             }
7167         }
7168 
7169         clippingPrimitives->addChild(primary.release());
7170         clippingPrimitives->addChild(secondary.release());
7171         clippingPrimitives->addChild(secondaryInherited.release());
7172 
7173         clippingPrimitivesHostQueryReset->addChild(primaryHostQueryReset.release());
7174         clippingPrimitivesHostQueryReset->addChild(secondaryHostQueryReset.release());
7175         clippingPrimitivesHostQueryReset->addChild(secondaryInheritedHostQueryReset.release());
7176 
7177         clippingPrimitivesResetBeforeCopy->addChild(primaryResetBeforeCopy.release());
7178         clippingPrimitivesResetBeforeCopy->addChild(secondaryResetBeforeCopy.release());
7179         clippingPrimitivesResetBeforeCopy->addChild(secondaryInheritedResetBeforeCopy.release());
7180 
7181         clippingPrimitivesResetAfterCopy->addChild(primaryResetAfterCopy.release());
7182         clippingPrimitivesResetAfterCopy->addChild(secondaryResetAfterCopy.release());
7183         clippingPrimitivesResetAfterCopy->addChild(secondaryInheritedResetAfterCopy.release());
7184     }
7185 
7186     //VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT
7187     //VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT
7188     for (uint32_t copyTypeIdx = 0; copyTypeIdx < DE_LENGTH_OF_ARRAY(copyType); copyTypeIdx++)
7189     {
7190         for (uint32_t i = 0; i < 4; ++i)
7191         {
7192             bool query64Bits   = (i & 1);
7193             bool dstOffset     = (i & 2);
7194             std::string prefix = bitPrefix(query64Bits, dstOffset);
7195 
7196             // It makes no sense to use dstOffset with vkGetQueryPoolResults()
7197             if (copyType[copyTypeIdx] == COPY_TYPE_GET && dstOffset)
7198                 continue;
7199 
7200             // Tests with no attachments for only primary command to reduce # of test cases.
7201             tesControlPatches->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7202                 m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_with_no_color_attachments",
7203                 GraphicBasicTestInstance::ParametersGraphic(
7204                     VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7205                     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false,
7206                     dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7207                 sixRepeats));
7208 
7209             tesControlPatchesHostQueryReset->addChild(
7210                 new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7211                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_with_no_color_attachments",
7212                     GraphicBasicTestInstance::ParametersGraphic(
7213                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7214                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7215                         false, dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7216                     sixRepeats));
7217 
7218             tesControlPatchesResetBeforeCopy->addChild(
7219                 new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7220                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_with_no_color_attachments",
7221                     GraphicBasicTestInstance::ParametersGraphic(
7222                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7223                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7224                         query64Bits, false, dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7225                     sixRepeats));
7226 
7227             if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7228                 tesControlPatchesResetAfterCopy->addChild(
7229                     new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7230                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_with_no_color_attachments",
7231                         GraphicBasicTestInstance::ParametersGraphic(
7232                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7233                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7234                             query64Bits, false, dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7235                         sixRepeats));
7236 
7237             tesEvaluationShaderInvocations->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7238                 m_testCtx,
7239                 prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_with_no_color_attachments",
7240                 GraphicBasicTestInstance::ParametersGraphic(
7241                     VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7242                     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits, false,
7243                     dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7244                 sixRepeats));
7245 
7246             tesEvaluationShaderInvocationsHostQueryReset->addChild(
7247                 new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7248                     m_testCtx,
7249                     prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_with_no_color_attachments",
7250                     GraphicBasicTestInstance::ParametersGraphic(
7251                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7252                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7253                         false, dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7254                     sixRepeats));
7255 
7256             tesEvaluationShaderInvocationsResetBeforeCopy->addChild(
7257                 new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7258                     m_testCtx,
7259                     prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_with_no_color_attachments",
7260                     GraphicBasicTestInstance::ParametersGraphic(
7261                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7262                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7263                         query64Bits, false, dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7264                     sixRepeats));
7265 
7266             if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7267                 tesEvaluationShaderInvocationsResetAfterCopy->addChild(
7268                     new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7269                         m_testCtx,
7270                         prefix + copyTypeStr[copyTypeIdx] +
7271                             "tes_evaluation_shader_invocations_with_no_color_attachments",
7272                         GraphicBasicTestInstance::ParametersGraphic(
7273                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7274                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7275                             query64Bits, false, dstOffset, CLEAR_NOOP, true, STRIDE_TYPE_VALID, true),
7276                         sixRepeats));
7277 
7278             /* Tests for clear operation within a statistics query activated.
7279              * Nothing for secondary_inherited cases can be done since it violates the specification.
7280              *
7281              * The query shouldn't count internal driver operations relevant to the clear operations.
7282              */
7283             const ClearOperation clearOp[] = {CLEAR_NOOP, CLEAR_COLOR, CLEAR_DEPTH};
7284             const char *const clearOpStr[] = {"", "_clear_color", "_clear_depth"};
7285 
7286             for (int clearOpIdx = 0; clearOpIdx < DE_LENGTH_OF_ARRAY(clearOp); ++clearOpIdx)
7287             {
7288                 tesControlPatches->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7289                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches" + clearOpStr[clearOpIdx],
7290                     GraphicBasicTestInstance::ParametersGraphic(
7291                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7292                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
7293                         false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7294                     sixRepeats));
7295                 tesControlPatches->addChild(new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7296                     m_testCtx,
7297                     prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary" + clearOpStr[clearOpIdx],
7298                     GraphicBasicTestInstance::ParametersGraphic(
7299                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7300                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
7301                         false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7302                     sixRepeats));
7303 
7304                 tesControlPatchesHostQueryReset->addChild(
7305                     new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7306                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches" + clearOpStr[clearOpIdx],
7307                         GraphicBasicTestInstance::ParametersGraphic(
7308                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7309                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7310                             false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7311                         sixRepeats));
7312                 tesControlPatchesHostQueryReset->addChild(
7313                     new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7314                         m_testCtx,
7315                         prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary" + clearOpStr[clearOpIdx],
7316                         GraphicBasicTestInstance::ParametersGraphic(
7317                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7318                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7319                             false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7320                         sixRepeats));
7321 
7322                 tesControlPatchesResetBeforeCopy->addChild(
7323                     new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7324                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches" + clearOpStr[clearOpIdx],
7325                         GraphicBasicTestInstance::ParametersGraphic(
7326                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7327                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7328                             query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7329                         sixRepeats));
7330                 tesControlPatchesResetBeforeCopy->addChild(
7331                     new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7332                         m_testCtx,
7333                         prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary" + clearOpStr[clearOpIdx],
7334                         GraphicBasicTestInstance::ParametersGraphic(
7335                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7336                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7337                             query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7338                         sixRepeats));
7339 
7340                 if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7341                 {
7342                     tesControlPatchesResetAfterCopy->addChild(
7343                         new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7344                             m_testCtx,
7345                             prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches" + clearOpStr[clearOpIdx],
7346                             GraphicBasicTestInstance::ParametersGraphic(
7347                                 VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7348                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7349                                 query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7350                             sixRepeats));
7351                     tesControlPatchesResetAfterCopy->addChild(
7352                         new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7353                             m_testCtx,
7354                             prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary" +
7355                                 clearOpStr[clearOpIdx],
7356                             GraphicBasicTestInstance::ParametersGraphic(
7357                                 VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7358                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7359                                 query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7360                             sixRepeats));
7361                 }
7362 
7363                 tesEvaluationShaderInvocations->addChild(
7364                     new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7365                         m_testCtx,
7366                         prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations" +
7367                             clearOpStr[clearOpIdx],
7368                         GraphicBasicTestInstance::ParametersGraphic(
7369                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7370                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
7371                             false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7372                         sixRepeats));
7373                 tesEvaluationShaderInvocations->addChild(
7374                     new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7375                         m_testCtx,
7376                         prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary" +
7377                             clearOpStr[clearOpIdx],
7378                         GraphicBasicTestInstance::ParametersGraphic(
7379                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7380                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
7381                             false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7382                         sixRepeats));
7383 
7384                 tesEvaluationShaderInvocationsHostQueryReset->addChild(
7385                     new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7386                         m_testCtx,
7387                         prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations" +
7388                             clearOpStr[clearOpIdx],
7389                         GraphicBasicTestInstance::ParametersGraphic(
7390                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7391                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7392                             false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7393                         sixRepeats));
7394                 tesEvaluationShaderInvocationsHostQueryReset->addChild(
7395                     new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7396                         m_testCtx,
7397                         prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary" +
7398                             clearOpStr[clearOpIdx],
7399                         GraphicBasicTestInstance::ParametersGraphic(
7400                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7401                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7402                             false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7403                         sixRepeats));
7404 
7405                 tesEvaluationShaderInvocationsResetBeforeCopy->addChild(
7406                     new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7407                         m_testCtx,
7408                         prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations" +
7409                             clearOpStr[clearOpIdx],
7410                         GraphicBasicTestInstance::ParametersGraphic(
7411                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7412                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7413                             query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7414                         sixRepeats));
7415                 tesEvaluationShaderInvocationsResetBeforeCopy->addChild(
7416                     new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7417                         m_testCtx,
7418                         prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary" +
7419                             clearOpStr[clearOpIdx],
7420                         GraphicBasicTestInstance::ParametersGraphic(
7421                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7422                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7423                             query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7424                         sixRepeats));
7425 
7426                 if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7427                 {
7428                     tesEvaluationShaderInvocationsResetAfterCopy->addChild(
7429                         new QueryPoolGraphicStatisticsTest<TessellationShaderTestInstance>(
7430                             m_testCtx,
7431                             prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations" +
7432                                 clearOpStr[clearOpIdx],
7433                             GraphicBasicTestInstance::ParametersGraphic(
7434                                 VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7435                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7436                                 query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7437                             sixRepeats));
7438                     tesEvaluationShaderInvocationsResetAfterCopy->addChild(
7439                         new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayTestInstance>(
7440                             m_testCtx,
7441                             prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary" +
7442                                 clearOpStr[clearOpIdx],
7443                             GraphicBasicTestInstance::ParametersGraphic(
7444                                 VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7445                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7446                                 query64Bits, false, dstOffset, clearOp[clearOpIdx], false, STRIDE_TYPE_VALID, true),
7447                             sixRepeats));
7448                 }
7449             }
7450 
7451             tesControlPatches->addChild(
7452                 new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7453                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary_inherited",
7454                     GraphicBasicTestInstance::ParametersGraphic(
7455                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7456                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
7457                         false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7458                     sixRepeats));
7459             tesControlPatchesHostQueryReset->addChild(
7460                 new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7461                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary_inherited",
7462                     GraphicBasicTestInstance::ParametersGraphic(
7463                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7464                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7465                         false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7466                     sixRepeats));
7467             tesControlPatchesResetBeforeCopy->addChild(
7468                 new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7469                     m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary_inherited",
7470                     GraphicBasicTestInstance::ParametersGraphic(
7471                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7472                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7473                         query64Bits, false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7474                     sixRepeats));
7475             if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7476                 tesControlPatchesResetAfterCopy->addChild(
7477                     new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7478                         m_testCtx, prefix + copyTypeStr[copyTypeIdx] + "tes_control_patches_secondary_inherited",
7479                         GraphicBasicTestInstance::ParametersGraphic(
7480                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
7481                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7482                             query64Bits, false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7483                         sixRepeats));
7484 
7485             tesEvaluationShaderInvocations->addChild(
7486                 new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7487                     m_testCtx,
7488                     prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary_inherited",
7489                     GraphicBasicTestInstance::ParametersGraphic(
7490                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7491                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_NORMAL, copyType[copyTypeIdx], query64Bits,
7492                         false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7493                     sixRepeats));
7494             tesEvaluationShaderInvocationsHostQueryReset->addChild(
7495                 new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7496                     m_testCtx,
7497                     prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary_inherited",
7498                     GraphicBasicTestInstance::ParametersGraphic(
7499                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7500                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_HOST, copyType[copyTypeIdx], query64Bits,
7501                         false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7502                     sixRepeats));
7503             tesEvaluationShaderInvocationsResetBeforeCopy->addChild(
7504                 new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7505                     m_testCtx,
7506                     prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary_inherited",
7507                     GraphicBasicTestInstance::ParametersGraphic(
7508                         VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7509                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_BEFORE_COPY, copyType[copyTypeIdx],
7510                         query64Bits, false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7511                     sixRepeats));
7512             if (copyType[copyTypeIdx] == COPY_TYPE_CMD)
7513                 tesEvaluationShaderInvocationsResetAfterCopy->addChild(
7514                     new QueryPoolGraphicStatisticsTest<TessellationShaderSecondrayInheritedTestInstance>(
7515                         m_testCtx,
7516                         prefix + copyTypeStr[copyTypeIdx] + "tes_evaluation_shader_invocations_secondary_inherited",
7517                         GraphicBasicTestInstance::ParametersGraphic(
7518                             VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
7519                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, RESET_TYPE_AFTER_COPY, copyType[copyTypeIdx],
7520                             query64Bits, false, dstOffset, CLEAR_NOOP, false, STRIDE_TYPE_VALID, true),
7521                         sixRepeats));
7522         }
7523     }
7524 
7525     // Multiple statistics query flags enabled
7526     {
7527         VkQueryResultFlags partialFlags[]   = {0u, VK_QUERY_RESULT_PARTIAL_BIT};
7528         const char *const partialFlagsStr[] = {"", "_partial"};
7529         VkQueryResultFlags waitFlags[]      = {0u, VK_QUERY_RESULT_WAIT_BIT};
7530         const char *const waitFlagsStr[]    = {"", "_wait"};
7531 
7532         const CopyType copyTypes[]       = {COPY_TYPE_GET, COPY_TYPE_CMD, COPY_TYPE_CMD};
7533         const char *const copyTypesStr[] = {"", "_cmdcopy", "_cmdcopy_dstoffset"};
7534 
7535         const StrideType strideTypes[]     = {STRIDE_TYPE_VALID, STRIDE_TYPE_ZERO};
7536         const char *const strideTypesStr[] = {"", "_stride_zero"};
7537 
7538         const VkQueryPipelineStatisticFlags statisticsFlags = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT |
7539                                                               VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT;
7540 
7541         for (uint32_t partialFlagsIdx = 0u; partialFlagsIdx < DE_LENGTH_OF_ARRAY(partialFlags); partialFlagsIdx++)
7542         {
7543             for (uint32_t waitFlagsIdx = 0u; waitFlagsIdx < DE_LENGTH_OF_ARRAY(waitFlags); waitFlagsIdx++)
7544             {
7545                 for (uint32_t copyTypesIdx = 0u; copyTypesIdx < DE_LENGTH_OF_ARRAY(copyTypes); copyTypesIdx++)
7546                 {
7547                     for (uint32_t strideTypesIdx = 0u; strideTypesIdx < DE_LENGTH_OF_ARRAY(strideTypes);
7548                          strideTypesIdx++)
7549                     {
7550                         uint32_t dstOffset =
7551                             copyTypesIdx == 2u ? uint32_t(NUM_QUERY_STATISTICS * sizeof(uint64_t)) : uint32_t(0u);
7552                         /* Avoid waiting infinite time for the queries, when one of them is not going to be issued in
7553                          * the partial case.
7554                          */
7555                         if ((bool)(partialFlags[partialFlagsIdx] & VK_QUERY_RESULT_PARTIAL_BIT) &&
7556                             (bool)(waitFlags[waitFlagsIdx] & VK_QUERY_RESULT_WAIT_BIT))
7557                             continue;
7558 
7559                         // Skip stride bogus tests when there are more than one query count.
7560                         if (partialFlags[partialFlagsIdx] && strideTypes[strideTypesIdx] == STRIDE_TYPE_ZERO)
7561                             continue;
7562 
7563                         if (strideTypes[strideTypesIdx] == STRIDE_TYPE_ZERO && copyType[copyTypesIdx] != COPY_TYPE_CMD)
7564                             continue;
7565 
7566                         VkQueryResultFlags queryFlags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT |
7567                                                         partialFlags[partialFlagsIdx] | waitFlags[waitFlagsIdx];
7568                         uint32_t queryCount = partialFlagsIdx ? 2u : 1u;
7569                         {
7570                             std::ostringstream testName;
7571                             testName << "input_assembly_vertex_fragment" << partialFlagsStr[partialFlagsIdx]
7572                                      << waitFlagsStr[waitFlagsIdx] << copyTypesStr[copyTypesIdx]
7573                                      << strideTypesStr[strideTypesIdx];
7574                             GraphicBasicMultipleQueryTestInstance::ParametersGraphic param(
7575                                 statisticsFlags | VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
7576                                 queryFlags, queryCount, false, copyTypes[copyTypesIdx], dstOffset,
7577                                 strideType[strideTypesIdx]);
7578                             vertexShaderMultipleQueries->addChild(
7579                                 new QueryPoolGraphicMultipleQueryStatisticsTest<VertexShaderMultipleQueryTestInstance>(
7580                                     m_testCtx, testName.str().c_str(), param));
7581                         }
7582 
7583                         {
7584                             // No fragment shader case
7585                             std::ostringstream testName;
7586                             testName << "input_assembly_vertex" << partialFlagsStr[partialFlagsIdx]
7587                                      << waitFlagsStr[waitFlagsIdx] << copyTypesStr[copyTypesIdx]
7588                                      << strideTypesStr[strideTypesIdx];
7589                             GraphicBasicMultipleQueryTestInstance::ParametersGraphic param(
7590                                 statisticsFlags | VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT, queryFlags,
7591                                 queryCount, true, copyTypes[copyTypesIdx], dstOffset, strideType[strideTypesIdx]);
7592                             vertexShaderMultipleQueries->addChild(
7593                                 new QueryPoolGraphicMultipleQueryStatisticsTest<VertexShaderMultipleQueryTestInstance>(
7594                                     m_testCtx, testName.str().c_str(), param));
7595                         }
7596                     }
7597                 }
7598             }
7599         }
7600     }
7601 
7602     {
7603         for (const auto useCopy : {false, true})
7604             for (const auto useAvailability : {false, true})
7605                 for (const auto useInheritance : {false, true})
7606                 {
7607                     const std::string name = std::string(useCopy ? "copy" : "get") +
7608                                              (useAvailability ? "_with_availability" : "") +
7609                                              (useInheritance ? "_and_inheritance" : "");
7610 
7611                     const MultipleGeomStatsParams params{
7612                         useCopy,
7613                         useAvailability,
7614                         useInheritance,
7615                     };
7616                     multipleGeomStats->addChild(new MultipleGeomStatsTestCase(m_testCtx, name, params));
7617                 }
7618     }
7619 
7620     addChild(computeShaderInvocationsGroup.release());
7621     addChild(inputAssemblyVertices.release());
7622     addChild(inputAssemblyPrimitives.release());
7623     addChild(vertexShaderInvocations.release());
7624     addChild(fragmentShaderInvocations.release());
7625     addChild(geometryShaderInvocations.release());
7626     addChild(geometryShaderPrimitives.release());
7627     addChild(clippingInvocations.release());
7628     addChild(clippingPrimitives.release());
7629     addChild(tesControlPatches.release());
7630     addChild(tesEvaluationShaderInvocations.release());
7631 
7632     vertexOnlyGroup->addChild(inputAssemblyVerticesVertexOnly.release());
7633     vertexOnlyGroup->addChild(inputAssemblyPrimitivesVertexOnly.release());
7634     vertexOnlyGroup->addChild(vertexShaderInvocationsVertexOnly.release());
7635     addChild(vertexOnlyGroup.release());
7636 
7637     hostQueryResetGroup->addChild(computeShaderInvocationsGroupHostQueryReset.release());
7638     hostQueryResetGroup->addChild(inputAssemblyVerticesHostQueryReset.release());
7639     hostQueryResetGroup->addChild(inputAssemblyPrimitivesHostQueryReset.release());
7640     hostQueryResetGroup->addChild(vertexShaderInvocationsHostQueryReset.release());
7641     hostQueryResetGroup->addChild(fragmentShaderInvocationsHostQueryReset.release());
7642     hostQueryResetGroup->addChild(geometryShaderInvocationsHostQueryReset.release());
7643     hostQueryResetGroup->addChild(geometryShaderPrimitivesHostQueryReset.release());
7644     hostQueryResetGroup->addChild(clippingInvocationsHostQueryReset.release());
7645     hostQueryResetGroup->addChild(clippingPrimitivesHostQueryReset.release());
7646     hostQueryResetGroup->addChild(tesControlPatchesHostQueryReset.release());
7647     hostQueryResetGroup->addChild(tesEvaluationShaderInvocationsHostQueryReset.release());
7648     addChild(hostQueryResetGroup.release());
7649 
7650     resetBeforeCopyGroup->addChild(computeShaderInvocationsGroupResetBeforeCopy.release());
7651     resetBeforeCopyGroup->addChild(inputAssemblyVerticesResetBeforeCopy.release());
7652     resetBeforeCopyGroup->addChild(inputAssemblyPrimitivesResetBeforeCopy.release());
7653     resetBeforeCopyGroup->addChild(vertexShaderInvocationsResetBeforeCopy.release());
7654     resetBeforeCopyGroup->addChild(fragmentShaderInvocationsResetBeforeCopy.release());
7655     resetBeforeCopyGroup->addChild(geometryShaderInvocationsResetBeforeCopy.release());
7656     resetBeforeCopyGroup->addChild(geometryShaderPrimitivesResetBeforeCopy.release());
7657     resetBeforeCopyGroup->addChild(clippingInvocationsResetBeforeCopy.release());
7658     resetBeforeCopyGroup->addChild(clippingPrimitivesResetBeforeCopy.release());
7659     resetBeforeCopyGroup->addChild(tesControlPatchesResetBeforeCopy.release());
7660     resetBeforeCopyGroup->addChild(tesEvaluationShaderInvocationsResetBeforeCopy.release());
7661     addChild(resetBeforeCopyGroup.release());
7662 
7663     resetAfterCopyGroup->addChild(computeShaderInvocationsGroupResetAfterCopy.release());
7664     resetAfterCopyGroup->addChild(inputAssemblyVerticesResetAfterCopy.release());
7665     resetAfterCopyGroup->addChild(inputAssemblyPrimitivesResetAfterCopy.release());
7666     resetAfterCopyGroup->addChild(vertexShaderInvocationsResetAfterCopy.release());
7667     resetAfterCopyGroup->addChild(fragmentShaderInvocationsResetAfterCopy.release());
7668     resetAfterCopyGroup->addChild(geometryShaderInvocationsResetAfterCopy.release());
7669     resetAfterCopyGroup->addChild(geometryShaderPrimitivesResetAfterCopy.release());
7670     resetAfterCopyGroup->addChild(clippingInvocationsResetAfterCopy.release());
7671     resetAfterCopyGroup->addChild(clippingPrimitivesResetAfterCopy.release());
7672     resetAfterCopyGroup->addChild(tesControlPatchesResetAfterCopy.release());
7673     resetAfterCopyGroup->addChild(tesEvaluationShaderInvocationsResetAfterCopy.release());
7674     addChild(resetAfterCopyGroup.release());
7675 
7676     addChild(vertexShaderMultipleQueries.release());
7677     addChild(multipleGeomStats.release());
7678 }
7679 
deinit(void)7680 void QueryPoolStatisticsTests::deinit(void)
7681 {
7682     destroyDeviceHelpers();
7683 }
7684 
7685 } // namespace QueryPool
7686 } // namespace vkt
7687