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> ¶meters);
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> ¶meters)
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> ¶meters);
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> ¶meters)
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> ¶meters);
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> ¶meters)
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 ¶metersGraphic, 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 ¶metersGraphic,
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 ¶metersGraphic, 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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic, 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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic,
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 ¶metersGraphic);
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 ¶metersGraphic)
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 ¶metersGraphic);
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 ¶metersGraphic)
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 ¶ms)
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 ¶ms)
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