+bool OcclusionQueryTestInstance::hasSeparateResetCmdBuf (void) const
+{
+ // Determine if resetting query pool should be performed in separate command buffer
+ // to avoid race condition between host query access and device query reset.
+
+ if (m_testVector.queryResultsMode == RESULTS_MODE_COPY)
+ {
+ // We copy query results on device, so there is no race condition between
+ // host and device
+ return false;
+ }
+ if (m_testVector.queryWait == WAIT_QUEUE)
+ {
+ // We wait for queue to be complete before accessing query results
+ return false;
+ }
+
+ // Separate command buffer with reset must be submitted & completed before
+ // host accesses the query results
+ return true;
+}
+
+bool OcclusionQueryTestInstance::hasSeparateCopyCmdBuf (void) const
+{
+ // Copy query results must go into separate command buffer, if we want to wait on queue before that
+ return (m_testVector.queryResultsMode == RESULTS_MODE_COPY && m_testVector.queryWait == WAIT_QUEUE);
+}
+
+vk::Move<vk::VkCommandBuffer> OcclusionQueryTestInstance::recordQueryPoolReset (vk::VkCommandPool cmdPool)
+{
+ const vk::VkDevice device = m_context.getDevice();
+ const vk::DeviceInterface& vk = m_context.getDeviceInterface();
+
+ DE_ASSERT(hasSeparateResetCmdBuf());
+
+ const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ cmdPool, // VkCommandPool commandPool;
+ vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
+ 1u, // deUint32 bufferCount;
+ };
+ vk::Move<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo));
+ CmdBufferBeginInfo beginInfo (0u);
+
+ vk.beginCommandBuffer(*cmdBuffer, &beginInfo);
+ vk.cmdResetQueryPool(*cmdBuffer, m_queryPool, 0, NUM_QUERIES_IN_POOL);
+ vk.endCommandBuffer(*cmdBuffer);
+
+ return cmdBuffer;
+}
+