Add concurrent query pool tests
authorSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Mon, 27 Jan 2020 08:56:14 +0000 (09:56 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Mon, 9 Mar 2020 09:54:57 +0000 (05:54 -0400)
Components: Vulkan
VK-GL-CTS issue: 2195

Added tests:

   dEQP-VK.query_pool.concurrent_queries.*

Change-Id: I6852ce9865f2bbceace5d0df648e050d68b88bbb

AndroidGen.mk
android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/query_pool/CMakeLists.txt
external/vulkancts/modules/vulkan/query_pool/vktQueryPoolConcurrentTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/query_pool/vktQueryPoolConcurrentTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/query_pool/vktQueryPoolTests.cpp
external/vulkancts/mustpass/master/vk-default-no-waivers.txt
external/vulkancts/mustpass/master/vk-default.txt

index 38c4457..b904efa 100644 (file)
@@ -252,6 +252,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWorkgroupStorageTests.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemYCbCrConversionTests.cpp \
+       external/vulkancts/modules/vulkan/query_pool/vktQueryPoolConcurrentTests.cpp \
        external/vulkancts/modules/vulkan/query_pool/vktQueryPoolOcclusionTests.cpp \
        external/vulkancts/modules/vulkan/query_pool/vktQueryPoolPerformanceTests.cpp \
        external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp \
index 930a3a4..787db86 100644 (file)
@@ -108817,6 +108817,8 @@ dEQP-VK.query_pool.performance_query.query_graphic
 dEQP-VK.query_pool.performance_query.query_compute
 dEQP-VK.query_pool.performance_query.multiple_pools_graphic
 dEQP-VK.query_pool.performance_query.multiple_pools_compute
+dEQP-VK.query_pool.concurrent_queries.primary_command_buffer
+dEQP-VK.query_pool.concurrent_queries.secondary_command_buffer
 dEQP-VK.draw.concurrent.compute_and_triangle_list
 dEQP-VK.draw.instanced.draw_vk_primitive_topology_point_list_attrib_divisor_0_multiview
 dEQP-VK.draw.instanced.draw_vk_primitive_topology_point_list_attrib_divisor_1_multiview
index 3da62c0..ca9fb1a 100644 (file)
@@ -411277,6 +411277,8 @@ dEQP-VK.query_pool.performance_query.query_graphic
 dEQP-VK.query_pool.performance_query.query_compute
 dEQP-VK.query_pool.performance_query.multiple_pools_graphic
 dEQP-VK.query_pool.performance_query.multiple_pools_compute
+dEQP-VK.query_pool.concurrent_queries.primary_command_buffer
+dEQP-VK.query_pool.concurrent_queries.secondary_command_buffer
 dEQP-VK.draw.concurrent.compute_and_triangle_list
 dEQP-VK.draw.simple_draw.simple_draw_triangle_list
 dEQP-VK.draw.simple_draw.simple_draw_triangle_strip
index 8d6c3fd..dff4afb 100644 (file)
@@ -12,6 +12,8 @@ set(DEQP_VK_QUERY_POOL_SRCS
        vktQueryPoolPerformanceTests.cpp
        vktQueryPoolStatisticsTests.hpp
        vktQueryPoolStatisticsTests.cpp
+       vktQueryPoolConcurrentTests.hpp
+       vktQueryPoolConcurrentTests.cpp
 )
 
 set(DEQP_VK_QUERY_POOL_LIBS
@@ -24,4 +26,3 @@ PCH(DEQP_VK_QUERY_POOL_SRCS ../pch.cpp)
 
 add_library(deqp-vk-query-pool STATIC ${DEQP_VK_QUERY_POOL_SRCS})
 target_link_libraries(deqp-vk-query-pool ${DEQP_VK_QUERY_POOL_LIBS})
-
diff --git a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolConcurrentTests.cpp b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolConcurrentTests.cpp
new file mode 100644 (file)
index 0000000..07c6fce
--- /dev/null
@@ -0,0 +1,895 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2020 The Khronos Group Inc.
+ * Copyright (c) 2020 Valve Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Concurrent Query Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktQueryPoolConcurrentTests.hpp"
+
+#include "vktTestCase.hpp"
+
+#include "vktDrawImageObjectUtil.hpp"
+#include "vktDrawBufferObjectUtil.hpp"
+#include "vktDrawCreateInfoUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkQueryUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuImageCompare.hpp"
+
+#include <memory>
+
+namespace vkt
+{
+
+namespace QueryPool
+{
+
+using namespace Draw;
+
+namespace
+{
+
+enum QueryType
+{
+       QUERY_TYPE_OCCLUSION = vk::VK_QUERY_TYPE_OCCLUSION,
+       QUERY_TYPE_PIPELINE_STATISTICS = vk::VK_QUERY_TYPE_PIPELINE_STATISTICS,
+       QUERY_TYPE_TIMESTAMP = vk::VK_QUERY_TYPE_TIMESTAMP,
+       NUM_QUERY_POOLS = 3
+};
+
+struct StateObjects
+{
+                       StateObjects    (const vk::DeviceInterface&vk, vkt::Context &context, const int numVertices, vk::VkPrimitiveTopology primitive);
+       void    setVertices             (const vk::DeviceInterface&vk, std::vector<tcu::Vec4> vertices);
+
+       enum
+       {
+               WIDTH   = 128,
+               HEIGHT  = 128
+       };
+
+       vkt::Context &m_context;
+
+       vk::Move<vk::VkPipeline>                m_pipeline;
+       vk::Move<vk::VkPipelineLayout>  m_pipelineLayout;
+
+       de::SharedPtr<Image>                    m_colorAttachmentImage, m_DepthImage;
+       vk::Move<vk::VkImageView>               m_attachmentView;
+       vk::Move<vk::VkImageView>               m_depthiew;
+
+       vk::Move<vk::VkRenderPass>              m_renderPass;
+       vk::Move<vk::VkFramebuffer>             m_framebuffer;
+
+       de::SharedPtr<Buffer>                   m_vertexBuffer;
+
+       vk::VkFormat                                    m_colorAttachmentFormat;
+};
+
+StateObjects::StateObjects (const vk::DeviceInterface&vk, vkt::Context &context, const int numVertices, vk::VkPrimitiveTopology primitive)
+       : m_context(context)
+       , m_colorAttachmentFormat(vk::VK_FORMAT_R8G8B8A8_UNORM)
+
+{
+       vk::VkFormat            depthFormat = vk::VK_FORMAT_D16_UNORM;
+       const vk::VkDevice      device          = m_context.getDevice();
+
+       //attachment images and views
+       {
+               vk::VkExtent3D imageExtent =
+               {
+                       WIDTH,  // width;
+                       HEIGHT, // height;
+                       1               // depth;
+               };
+
+               const ImageCreateInfo colorImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
+                                                                                                  vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+
+               m_colorAttachmentImage  = Image::createAndAlloc(vk, device, colorImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
+
+               const ImageViewCreateInfo attachmentViewInfo(m_colorAttachmentImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
+               m_attachmentView                = vk::createImageView(vk, device, &attachmentViewInfo);
+
+               ImageCreateInfo depthImageCreateInfo(vk::VK_IMAGE_TYPE_2D, depthFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
+                       vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+
+               m_DepthImage                    = Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
+
+               // Construct a depth  view from depth image
+               const ImageViewCreateInfo depthViewInfo(m_DepthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, depthFormat);
+               m_depthiew                              = vk::createImageView(vk, device, &depthViewInfo);
+       }
+
+       {
+               // Renderpass and Framebuffer
+
+               RenderPassCreateInfo renderPassCreateInfo;
+               renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,                                                                       // format
+                                                                                                                                       vk::VK_SAMPLE_COUNT_1_BIT,                                                              // samples
+                                                                                                                                       vk::VK_ATTACHMENT_LOAD_OP_CLEAR,                                                // loadOp
+                                                                                                                                       vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                                   // storeOp
+                                                                                                                                       vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                    // stencilLoadOp
+                                                                                                                                       vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                                   // stencilLoadOp
+                                                                                                                                       vk::VK_IMAGE_LAYOUT_GENERAL,                                                    // initialLauout
+                                                                                                                                       vk::VK_IMAGE_LAYOUT_GENERAL));                                                  // finalLayout
+
+               renderPassCreateInfo.addAttachment(AttachmentDescription(depthFormat,                                                                                           // format
+                                                                                                                                vk::VK_SAMPLE_COUNT_1_BIT,                                                                     // samples
+                                                                                                                                vk::VK_ATTACHMENT_LOAD_OP_CLEAR,                                                       // loadOp
+                                                                                                                                vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                                          // storeOp
+                                                                                                                                vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                           // stencilLoadOp
+                                                                                                                                vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                                          // stencilLoadOp
+                                                                                                                                vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,          // initialLauout
+                                                                                                                                vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));        // finalLayout
+
+               const vk::VkAttachmentReference colorAttachmentReference =
+               {
+                       0,                                                                                                                      // attachment
+                       vk::VK_IMAGE_LAYOUT_GENERAL                                                                     // layout
+               };
+
+               const vk::VkAttachmentReference depthAttachmentReference =
+               {
+                       1,                                                                                                                      // attachment
+                       vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL            // layout
+               };
+
+               renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,                                 // pipelineBindPoint
+                                                                                                                  0,                                                                                                   // flags
+                                                                                                                  0,                                                                                                   // inputCount
+                                                                                                                  DE_NULL,                                                                                             // pInputAttachments
+                                                                                                                  1,                                                                                                   // colorCount
+                                                                                                                  &colorAttachmentReference,                                                   // pColorAttachments
+                                                                                                                  DE_NULL,                                                                                             // pResolveAttachments
+                                                                                                                  depthAttachmentReference,                                                    // depthStencilAttachment
+                                                                                                                  0,                                                                                                   // preserveCount
+                                                                                                                  DE_NULL));                                                                                   // preserveAttachments
+
+               m_renderPass = vk::createRenderPass(vk, device, &renderPassCreateInfo);
+
+               std::vector<vk::VkImageView> attachments(2);
+               attachments[0] = *m_attachmentView;
+               attachments[1] = *m_depthiew;
+
+               FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
+               m_framebuffer = vk::createFramebuffer(vk, device, &framebufferCreateInfo);
+       }
+
+       {
+               // Pipeline
+
+               vk::Unique<vk::VkShaderModule> vs(vk::createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
+               vk::Unique<vk::VkShaderModule> fs(vk::createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
+
+               const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
+
+               const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
+               m_pipelineLayout = vk::createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
+
+               const vk::VkVertexInputBindingDescription vf_binding_desc               =
+               {
+                       0,                                                                                                                              // binding;
+                       4 * (deUint32)sizeof(float),                                                                    // stride;
+                       vk::VK_VERTEX_INPUT_RATE_VERTEX                                                                 // inputRate
+               };
+
+               const vk::VkVertexInputAttributeDescription vf_attribute_desc   =
+               {
+                       0,                                                                                                                              // location;
+                       0,                                                                                                                              // binding;
+                       vk::VK_FORMAT_R32G32B32A32_SFLOAT,                                                              // format;
+                       0                                                                                                                               // offset;
+               };
+
+               const vk::VkPipelineVertexInputStateCreateInfo vf_info                  =
+               {                                                                                                                                       // sType;
+                       vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,  // pNext;
+                       NULL,                                                                                                                   // flags;
+                       0u,                                                                                                                             // vertexBindingDescriptionCount;
+                       1,                                                                                                                              // pVertexBindingDescriptions;
+                       &vf_binding_desc,                                                                                               // vertexAttributeDescriptionCount;
+                       1,                                                                                                                              // pVertexAttributeDescriptions;
+                       &vf_attribute_desc
+               };
+
+               PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
+               pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
+               pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
+               pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(primitive));
+               pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &attachmentState));
+               const vk::VkViewport viewport   = vk::makeViewport(WIDTH, HEIGHT);
+               const vk::VkRect2D scissor              = vk::makeRect2D(WIDTH, HEIGHT);
+               pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<vk::VkViewport>(1, viewport), std::vector<vk::VkRect2D>(1, scissor)));
+               pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState(true, true, vk::VK_COMPARE_OP_GREATER_OR_EQUAL));
+               pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
+               pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
+               pipelineCreateInfo.addState(vf_info);
+               m_pipeline = vk::createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
+       }
+
+       {
+               // Vertex buffer
+               const size_t kBufferSize = numVertices * sizeof(tcu::Vec4);
+               m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(kBufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
+       }
+}
+
+void StateObjects::setVertices (const vk::DeviceInterface&vk, std::vector<tcu::Vec4> vertices)
+{
+       const vk::VkDevice device                       = m_context.getDevice();
+
+       tcu::Vec4 *ptr = reinterpret_cast<tcu::Vec4*>(m_vertexBuffer->getBoundMemory().getHostPtr());
+       std::copy(vertices.begin(), vertices.end(), ptr);
+
+       vk::flushAlloc(vk, device,      m_vertexBuffer->getBoundMemory());
+}
+
+class PrimaryCommandBufferConcurrentTestInstance : public vkt::TestInstance
+{
+public:
+       PrimaryCommandBufferConcurrentTestInstance              (vkt::Context &context);
+       ~PrimaryCommandBufferConcurrentTestInstance             (void);
+private:
+       tcu::TestStatus                                 iterate                                                 (void);
+
+       enum
+       {
+               NUM_QUERIES_IN_POOL                             = 2,
+               QUERY_INDEX_CAPTURE_EMPTY               = 0,
+               QUERY_INDEX_CAPTURE_DRAWCALL    = 1,
+               NUM_VERTICES_IN_DRAWCALL                = 3
+       };
+
+       std::unique_ptr<StateObjects>           m_stateObjects;
+       vk::Move<vk::VkQueryPool>                       m_queryPools[NUM_QUERY_POOLS];
+       deBool                                                          m_supportedQueryType[NUM_QUERY_POOLS];
+};
+
+PrimaryCommandBufferConcurrentTestInstance::PrimaryCommandBufferConcurrentTestInstance (vkt::Context &context)
+       : TestInstance          (context)
+{
+       // Check support for multiple query types
+       {
+               for(deUint32 poolNdx = 0; poolNdx < NUM_QUERY_POOLS; poolNdx++)
+                       m_supportedQueryType[poolNdx] = DE_FALSE;
+
+               deUint32 numSupportedQueryTypes = 0;
+               m_supportedQueryType[QUERY_TYPE_OCCLUSION] = DE_TRUE;
+               numSupportedQueryTypes++;
+
+               if (context.getDeviceFeatures().pipelineStatisticsQuery)
+               {
+                       m_supportedQueryType[QUERY_TYPE_PIPELINE_STATISTICS] = DE_TRUE;
+                       numSupportedQueryTypes++;
+               }
+
+               // Check support for timestamp queries
+               {
+                       const deUint32                                                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
+                       const std::vector<vk::VkQueueFamilyProperties>  queueProperties         = vk::getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
+
+                       DE_ASSERT(queueFamilyIndex < (deUint32)queueProperties.size());
+
+                       if (queueProperties[queueFamilyIndex].timestampValidBits)
+                        {
+                                m_supportedQueryType[QUERY_TYPE_TIMESTAMP] = DE_TRUE;
+                                numSupportedQueryTypes++;
+                        }
+               }
+               if (numSupportedQueryTypes < 2)
+                       throw tcu::NotSupportedError("Device does not support multiple query types");
+       }
+
+       m_stateObjects = std::unique_ptr<StateObjects>(new StateObjects(m_context.getDeviceInterface(), m_context, NUM_VERTICES_IN_DRAWCALL, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
+
+       const vk::VkDevice                      device  = m_context.getDevice();
+       const vk::DeviceInterface&      vk              = m_context.getDeviceInterface();
+
+       for(deUint32 poolNdx = 0; poolNdx < NUM_QUERY_POOLS; poolNdx++)
+       {
+               if (!m_supportedQueryType[poolNdx])
+                       continue;
+
+               vk::VkQueryPoolCreateInfo queryPoolCreateInfo =
+               {
+                       vk::VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
+                       DE_NULL,
+                       0u,
+                       static_cast<vk::VkQueryType>(poolNdx),
+                       NUM_QUERIES_IN_POOL,
+                       0u,
+               };
+               if (poolNdx == QUERY_TYPE_PIPELINE_STATISTICS)
+                       queryPoolCreateInfo.pipelineStatistics = vk::VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT;
+
+               m_queryPools[poolNdx] = createQueryPool(vk, device, &queryPoolCreateInfo, /*pAllocator*/ DE_NULL);
+       }
+
+       std::vector<tcu::Vec4> vertices(NUM_VERTICES_IN_DRAWCALL);
+       vertices[0] = tcu::Vec4(0.5, 0.5, 0.0, 1.0);
+       vertices[1] = tcu::Vec4(0.5, 0.0, 0.0, 1.0);
+       vertices[2] = tcu::Vec4(0.0, 0.5, 0.0, 1.0);
+       m_stateObjects->setVertices(vk, vertices);
+}
+
+PrimaryCommandBufferConcurrentTestInstance::~PrimaryCommandBufferConcurrentTestInstance (void)
+{
+}
+
+tcu::TestStatus        PrimaryCommandBufferConcurrentTestInstance::iterate (void)
+{
+       tcu::TestLog &log                               = m_context.getTestContext().getLog();
+       const vk::VkDevice device               = m_context.getDevice();
+       const vk::VkQueue queue                 = m_context.getUniversalQueue();
+       const vk::DeviceInterface& vk   = m_context.getDeviceInterface();
+
+       const CmdPoolCreateInfo                 cmdPoolCreateInfo       (m_context.getUniversalQueueFamilyIndex());
+       vk::Move<vk::VkCommandPool>             cmdPool                         = vk::createCommandPool(vk, device, &cmdPoolCreateInfo);
+
+       vk::Unique<vk::VkCommandBuffer> cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
+       beginCommandBuffer(vk, *cmdBuffer);
+
+       initialTransitionColor2DImage(vk, *cmdBuffer, m_stateObjects->m_colorAttachmentImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
+                                                                 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+       initialTransitionDepth2DImage(vk, *cmdBuffer, m_stateObjects->m_DepthImage->object(), vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                                                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
+
+       std::vector<vk::VkClearValue> renderPassClearValues(2);
+       deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(vk::VkClearValue));
+
+       for (deUint32 poolNdx = 0u; poolNdx < NUM_QUERY_POOLS; poolNdx++)
+       {
+               if (m_supportedQueryType[poolNdx])
+                       vk.cmdResetQueryPool(*cmdBuffer, *m_queryPools[poolNdx], 0u, NUM_QUERIES_IN_POOL);
+       }
+
+       beginRenderPass(vk, *cmdBuffer, *m_stateObjects->m_renderPass, *m_stateObjects->m_framebuffer, vk::makeRect2D(0, 0, StateObjects::WIDTH, StateObjects::HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0]);
+
+       vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_stateObjects->m_pipeline);
+
+       vk::VkBuffer vertexBuffer = m_stateObjects->m_vertexBuffer->object();
+       const vk::VkDeviceSize vertexBufferOffset = 0;
+       vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+       // Begin all queries
+       for (deUint32 poolNdx = 0u; poolNdx < QUERY_TYPE_TIMESTAMP; poolNdx++)
+       {
+               if (m_supportedQueryType[poolNdx])
+                       vk.cmdBeginQuery(*cmdBuffer, *m_queryPools[poolNdx], QUERY_INDEX_CAPTURE_EMPTY, 0u);
+       }
+
+       // End first capture (should not have any result). Start the second one.
+       for (deUint32 poolNdx = 0u; poolNdx < QUERY_TYPE_TIMESTAMP; poolNdx++)
+       {
+               if (m_supportedQueryType[poolNdx])
+               {
+                       vk.cmdEndQuery(*cmdBuffer, *m_queryPools[poolNdx],      QUERY_INDEX_CAPTURE_EMPTY);
+                       vk.cmdBeginQuery(*cmdBuffer, *m_queryPools[poolNdx], QUERY_INDEX_CAPTURE_DRAWCALL, 0u);
+               }
+       }
+
+       vk.cmdDraw(*cmdBuffer, NUM_VERTICES_IN_DRAWCALL, 1, 0, 0);
+
+       if (m_supportedQueryType[QUERY_TYPE_TIMESTAMP])
+               vk.cmdWriteTimestamp(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, *m_queryPools[QUERY_TYPE_TIMESTAMP], QUERY_INDEX_CAPTURE_DRAWCALL);
+
+       for (deUint32 poolNdx = 0u; poolNdx < QUERY_TYPE_TIMESTAMP; poolNdx++)
+       {
+               if (m_supportedQueryType[poolNdx])
+                       vk.cmdEndQuery(*cmdBuffer, *m_queryPools[poolNdx],      QUERY_INDEX_CAPTURE_DRAWCALL);
+       }
+
+       endRenderPass(vk, *cmdBuffer);
+
+       transition2DImage(vk, *cmdBuffer, m_stateObjects->m_colorAttachmentImage->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT,
+                                         vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+                                         vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+       endCommandBuffer(vk, *cmdBuffer);
+
+       submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
+
+       deUint64 queryResults[NUM_QUERIES_IN_POOL] = { 0 };
+       size_t queryResultsSize         = sizeof(queryResults);
+       bool passed = true;
+
+       // Occlusion and pipeline statistics queries verification
+       for (deUint32 poolNdx = 0; poolNdx < QUERY_TYPE_TIMESTAMP; poolNdx++)
+       {
+               if (m_supportedQueryType[poolNdx] == DE_FALSE)
+                       continue;
+               vk::VkResult queryResult        = vk.getQueryPoolResults(device, *m_queryPools[poolNdx], 0, NUM_QUERIES_IN_POOL, queryResultsSize, queryResults, sizeof(queryResults[0]), vk::VK_QUERY_RESULT_64_BIT);
+
+               if (queryResult == vk::VK_NOT_READY)
+               {
+                       TCU_FAIL("Query result not available, but vkWaitIdle() was called.");
+               }
+
+               VK_CHECK(queryResult);
+               std::string name = (poolNdx == QUERY_TYPE_OCCLUSION) ? "OcclusionQueryResults" : "PipelineStatisticsQueryResults";
+               std::string desc = (poolNdx == QUERY_TYPE_OCCLUSION) ? "Occlusion query results" : "PipelineStatistics query results";
+               log << tcu::TestLog::Section(name, desc);
+               for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(queryResults); ++ndx)
+               {
+                       log << tcu::TestLog::Message << "query[slot == " << ndx
+                               << "] result == " << queryResults[ndx] << tcu::TestLog::EndMessage;
+               }
+
+
+               for (deUint32 queryNdx = 0; queryNdx < DE_LENGTH_OF_ARRAY(queryResults); ++queryNdx)
+               {
+                       if (queryNdx == QUERY_INDEX_CAPTURE_EMPTY && queryResults[queryNdx] != 0u)
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "wrong value of query for index "
+                                       << queryNdx << ", expected any zero value, got "
+                                       << queryResults[0] << "." << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+
+                       if (queryNdx != QUERY_INDEX_CAPTURE_EMPTY && queryResults[queryNdx] == 0)
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "wrong value of query for index "
+                                       << queryNdx << ", expected any non-zero value, got "
+                                       << queryResults[0] << "." << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+               }
+               log << tcu::TestLog::EndSection;
+       }
+
+       // Timestamp query verification
+       if (m_supportedQueryType[QUERY_TYPE_TIMESTAMP])
+       {
+               std::pair<deUint64, deUint64>   queryResultsWithAvailabilityBit[NUM_QUERIES_IN_POOL];
+               size_t queryResultsWithAvailabilityBitSize              = sizeof(queryResultsWithAvailabilityBit);
+               vk::VkResult queryResult        = vk.getQueryPoolResults(device, *m_queryPools[QUERY_TYPE_TIMESTAMP], 0, NUM_QUERIES_IN_POOL, queryResultsWithAvailabilityBitSize, &queryResultsWithAvailabilityBit[0], sizeof(queryResultsWithAvailabilityBit[0]), vk::VK_QUERY_RESULT_64_BIT | vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
+
+               if (queryResult != vk::VK_NOT_READY)
+               {
+                       TCU_FAIL("We don't have available one query, it should return VK_NOT_READY");
+               }
+
+               log << tcu::TestLog::Section("TimestampQueryResults",
+                                                                        "Timestamp query results");
+               for (int ndx = 0; ndx < NUM_QUERIES_IN_POOL; ++ndx)
+               {
+                       log << tcu::TestLog::Message << "query[slot == " << ndx
+                               << "] result == " << queryResultsWithAvailabilityBit[ndx].first << tcu::TestLog::EndMessage;
+               }
+
+
+               for (deUint32 queryNdx = 0; queryNdx < NUM_QUERIES_IN_POOL; ++queryNdx)
+               {
+                       if (queryNdx == QUERY_INDEX_CAPTURE_EMPTY && (queryResultsWithAvailabilityBit[queryNdx].first != 0u || queryResultsWithAvailabilityBit[queryNdx].second != 0u))
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "either wrong value of query for index "
+                                       << queryNdx << " (expected any zero value, got "
+                                       << queryResultsWithAvailabilityBit[queryNdx].first << ") or the result is available (" << queryResultsWithAvailabilityBit[queryNdx].second << ")"
+                                       << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+
+                       if (queryNdx != QUERY_INDEX_CAPTURE_EMPTY && (queryResultsWithAvailabilityBit[queryNdx].first == 0u || queryResultsWithAvailabilityBit[queryNdx].second == 0u))
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "either wrong value of query for index "
+                                       << queryNdx << " (expected any non-zero value, got "
+                                       << queryResults[0] << ") or result is unavailable." << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+               }
+               log << tcu::TestLog::EndSection;
+       }
+
+       if (passed)
+       {
+               return tcu::TestStatus(QP_TEST_RESULT_PASS, "Query result verification passed");
+       }
+       return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Query result verification failed");
+}
+
+class SecondaryCommandBufferConcurrentTestInstance : public vkt::TestInstance
+{
+public:
+       SecondaryCommandBufferConcurrentTestInstance            (vkt::Context &context);
+       ~SecondaryCommandBufferConcurrentTestInstance           (void);
+private:
+       tcu::TestStatus                                 iterate                                                 (void);
+
+       enum
+       {
+               NUM_QUERIES_IN_POOL                             = 2,
+               QUERY_INDEX_CAPTURE_EMPTY               = 0,
+               QUERY_INDEX_CAPTURE_DRAWCALL    = 1,
+               NUM_VERTICES_IN_DRAWCALL                = 3
+       };
+
+       std::unique_ptr<StateObjects>                   m_stateObjects;
+       vk::Move<vk::VkQueryPool>                               m_queryPools[NUM_QUERY_POOLS];
+       deBool                                                                  m_supportedQueryType[NUM_QUERY_POOLS];
+
+};
+
+SecondaryCommandBufferConcurrentTestInstance::SecondaryCommandBufferConcurrentTestInstance (vkt::Context &context)
+       : TestInstance          (context)
+{
+       // Check support for multiple query types
+       {
+               for(deUint32 poolNdx = 0; poolNdx < NUM_QUERY_POOLS; poolNdx++)
+                       m_supportedQueryType[poolNdx] = DE_FALSE;
+
+               deUint32 numSupportedQueryTypes = 0;
+               m_supportedQueryType[QUERY_TYPE_OCCLUSION] = DE_TRUE;
+               numSupportedQueryTypes++;
+
+               if (context.getDeviceFeatures().pipelineStatisticsQuery)
+               {
+                       m_supportedQueryType[QUERY_TYPE_PIPELINE_STATISTICS] = DE_TRUE;
+                       numSupportedQueryTypes++;
+               }
+
+               // Check support for timestamp queries
+               {
+                       const deUint32                                                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
+                       const std::vector<vk::VkQueueFamilyProperties>  queueProperties         = vk::getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
+
+                       DE_ASSERT(queueFamilyIndex < (deUint32)queueProperties.size());
+
+                       if (queueProperties[queueFamilyIndex].timestampValidBits)
+                        {
+                                m_supportedQueryType[QUERY_TYPE_TIMESTAMP] = DE_TRUE;
+                                numSupportedQueryTypes++;
+                        }
+               }
+               if (numSupportedQueryTypes < 2)
+                       throw tcu::NotSupportedError("Device does not support multiple query types");
+       }
+
+       m_stateObjects = std::unique_ptr<StateObjects>(new StateObjects(m_context.getDeviceInterface(), m_context, NUM_VERTICES_IN_DRAWCALL, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
+
+       const vk::VkDevice                      device  = m_context.getDevice();
+       const vk::DeviceInterface&      vk              = m_context.getDeviceInterface();
+
+       for(deUint32 poolNdx = 0; poolNdx < NUM_QUERY_POOLS; poolNdx++)
+       {
+               if (!m_supportedQueryType[poolNdx])
+                       continue;
+
+               vk::VkQueryPoolCreateInfo queryPoolCreateInfo =
+               {
+                       vk::VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
+                       DE_NULL,
+                       0u,
+                       static_cast<vk::VkQueryType>(poolNdx),
+                       NUM_QUERIES_IN_POOL,
+                       0u,
+               };
+               if (poolNdx == QUERY_TYPE_PIPELINE_STATISTICS)
+                       queryPoolCreateInfo.pipelineStatistics = vk::VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT;
+
+               m_queryPools[poolNdx] = createQueryPool(vk, device, &queryPoolCreateInfo, /*pAllocator*/ DE_NULL);
+       }
+
+       std::vector<tcu::Vec4> vertices(NUM_VERTICES_IN_DRAWCALL);
+       vertices[0] = tcu::Vec4(0.5, 0.5, 0.0, 1.0);
+       vertices[1] = tcu::Vec4(0.5, 0.0, 0.0, 1.0);
+       vertices[2] = tcu::Vec4(0.0, 0.5, 0.0, 1.0);
+       m_stateObjects->setVertices(vk, vertices);
+}
+
+SecondaryCommandBufferConcurrentTestInstance::~SecondaryCommandBufferConcurrentTestInstance (void)
+{
+}
+
+void beginSecondaryCommandBuffer (const vk::DeviceInterface&                           vk,
+                                                                 const vk::VkCommandBuffer                                     secondaryCmdBuffer,
+                                                                 const vk::VkCommandBufferInheritanceInfo      bufferInheritanceInfo)
+{
+       const vk::VkCommandBufferUsageFlags     flags           = bufferInheritanceInfo.renderPass != DE_NULL
+                                                                                                         ? (vk::VkCommandBufferUsageFlags)vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
+                                                                                                         : (vk::VkCommandBufferUsageFlags)0u;
+       const vk::VkCommandBufferBeginInfo      beginInfo       =
+       {
+               vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                        // sType
+               DE_NULL,                                                                                                        // pNext
+               flags,                                                                                                          // flags
+               &bufferInheritanceInfo,                                                                         // pInheritanceInfo
+       };
+       VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
+}
+
+tcu::TestStatus        SecondaryCommandBufferConcurrentTestInstance::iterate (void)
+{
+       tcu::TestLog &log                               = m_context.getTestContext().getLog();
+       const vk::VkDevice device               = m_context.getDevice();
+       const vk::VkQueue queue                 = m_context.getUniversalQueue();
+       const vk::DeviceInterface& vk   = m_context.getDeviceInterface();
+
+       const CmdPoolCreateInfo                 cmdPoolCreateInfo       (m_context.getUniversalQueueFamilyIndex());
+       vk::Move<vk::VkCommandPool>             cmdPool                         = vk::createCommandPool(vk, device, &cmdPoolCreateInfo);
+
+       vk::Unique<vk::VkCommandBuffer> cmdBufferPrimary                        (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+       vk::Unique<vk::VkCommandBuffer> cmdBufferSecondary                      (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
+
+       // Secondary command buffer recording.
+       {
+               // Begin secondary command buffer
+               const vk::VkCommandBufferInheritanceInfo        secCmdBufInheritInfo    =
+               {
+                       vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
+                       DE_NULL,
+                       *m_stateObjects->m_renderPass,                                                          // renderPass
+                       0u,                                                                                                                     // subpass
+                       *m_stateObjects->m_framebuffer,                                                         // framebuffer
+                       VK_TRUE,                                                                                                        // occlusionQueryEnable
+                       (vk::VkQueryControlFlags)0u,                                                            // queryFlags
+                       (vk::VkQueryPipelineStatisticFlags)0u,                                          // pipelineStatistics
+               };
+               beginSecondaryCommandBuffer(vk, *cmdBufferSecondary, secCmdBufInheritInfo);
+
+               vk.cmdBindPipeline(*cmdBufferSecondary, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_stateObjects->m_pipeline);
+               vk::VkBuffer vertexBuffer = m_stateObjects->m_vertexBuffer->object();
+               const vk::VkDeviceSize vertexBufferOffset = 0;
+               vk.cmdBindVertexBuffers(*cmdBufferSecondary, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+               // Run pipeline statistics queries capture in the second command buffer
+               if (m_supportedQueryType[QUERY_TYPE_PIPELINE_STATISTICS])
+                       vk.cmdBeginQuery(*cmdBufferSecondary, *m_queryPools[QUERY_TYPE_PIPELINE_STATISTICS], QUERY_INDEX_CAPTURE_DRAWCALL, 0u);
+
+               // Timestamp query happening in the secondary command buffer
+               if (m_supportedQueryType[QUERY_TYPE_TIMESTAMP])
+                       vk.cmdWriteTimestamp(*cmdBufferSecondary, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, *m_queryPools[QUERY_TYPE_TIMESTAMP], QUERY_INDEX_CAPTURE_DRAWCALL);
+
+               vk.cmdDraw(*cmdBufferSecondary, NUM_VERTICES_IN_DRAWCALL, 1, 0, 0);
+
+               if (m_supportedQueryType[QUERY_TYPE_PIPELINE_STATISTICS])
+                       vk.cmdEndQuery(*cmdBufferSecondary, *m_queryPools[QUERY_TYPE_PIPELINE_STATISTICS], QUERY_INDEX_CAPTURE_DRAWCALL);
+
+               endCommandBuffer(vk, *cmdBufferSecondary);
+       }
+
+       // Primary command buffer recording
+       {
+               beginCommandBuffer(vk, *cmdBufferPrimary);
+
+               initialTransitionColor2DImage(vk, *cmdBufferPrimary, m_stateObjects->m_colorAttachmentImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
+                                                                         vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+               initialTransitionDepth2DImage(vk, *cmdBufferPrimary, m_stateObjects->m_DepthImage->object(), vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                                                                         vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
+
+               std::vector<vk::VkClearValue> renderPassClearValues(2);
+               deMemset(&renderPassClearValues[0], 0, static_cast<int>(renderPassClearValues.size()) * sizeof(vk::VkClearValue));
+
+               for (deUint32 poolNdx = 0u; poolNdx < NUM_QUERY_POOLS; poolNdx++)
+               {
+                       if (m_supportedQueryType[poolNdx])
+                               vk.cmdResetQueryPool(*cmdBufferPrimary, *m_queryPools[poolNdx], 0u, NUM_QUERIES_IN_POOL);
+               }
+
+               for (deUint32 poolNdx = 0u; poolNdx < QUERY_TYPE_TIMESTAMP; poolNdx++)
+               {
+                       if (m_supportedQueryType[poolNdx])
+                               vk.cmdBeginQuery(*cmdBufferPrimary, *m_queryPools[poolNdx], QUERY_INDEX_CAPTURE_EMPTY, 0u);
+               }
+
+               for (deUint32 poolNdx = 0u; poolNdx < QUERY_TYPE_TIMESTAMP; poolNdx++)
+               {
+                       if (m_supportedQueryType[poolNdx])
+                               vk.cmdEndQuery(*cmdBufferPrimary, *m_queryPools[poolNdx], QUERY_INDEX_CAPTURE_EMPTY);
+               }
+
+               // Run oclussion queries capture in the primary command buffer, inherit the counters for the secondary command buffer
+               if (m_supportedQueryType[QUERY_TYPE_OCCLUSION])
+                       vk.cmdBeginQuery(*cmdBufferPrimary, *m_queryPools[QUERY_TYPE_OCCLUSION], QUERY_INDEX_CAPTURE_DRAWCALL, 0u);
+
+               beginRenderPass(vk, *cmdBufferPrimary, *m_stateObjects->m_renderPass, *m_stateObjects->m_framebuffer, vk::makeRect2D(0, 0, StateObjects::WIDTH, StateObjects::HEIGHT), (deUint32)renderPassClearValues.size(), &renderPassClearValues[0], vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
+
+               vk.cmdExecuteCommands(*cmdBufferPrimary, 1u, &cmdBufferSecondary.get());
+
+               endRenderPass(vk, *cmdBufferPrimary);
+
+               if (m_supportedQueryType[QUERY_TYPE_OCCLUSION])
+                       vk.cmdEndQuery(*cmdBufferPrimary, *m_queryPools[QUERY_TYPE_OCCLUSION], QUERY_INDEX_CAPTURE_DRAWCALL);
+
+               transition2DImage(vk, *cmdBufferPrimary,
+                                                 m_stateObjects->m_colorAttachmentImage->object(),
+                                                 vk::VK_IMAGE_ASPECT_COLOR_BIT,
+                                                 vk::VK_IMAGE_LAYOUT_GENERAL,
+                                                 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                                 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+                                                 vk::VK_ACCESS_TRANSFER_READ_BIT,
+                                                 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                                                 vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+               endCommandBuffer(vk, *cmdBufferPrimary);
+       }
+
+       submitCommandsAndWait(vk, device, queue, cmdBufferPrimary.get());
+
+       deUint64 queryResults[NUM_QUERIES_IN_POOL] = { 0 };
+       size_t queryResultsSize         = sizeof(queryResults);
+       bool passed = true;
+
+       // Occlusion and pipeline statistics queries verification
+       for (deUint32 poolNdx = 0; poolNdx < QUERY_TYPE_TIMESTAMP; poolNdx++)
+       {
+               if (!m_supportedQueryType[poolNdx])
+                       continue;
+               vk::VkResult queryResult        = vk.getQueryPoolResults(device, *m_queryPools[poolNdx], 0, NUM_QUERIES_IN_POOL, queryResultsSize, queryResults, sizeof(queryResults[0]), vk::VK_QUERY_RESULT_64_BIT);
+
+               if (queryResult == vk::VK_NOT_READY)
+               {
+                       TCU_FAIL("Query result not available, but vkWaitIdle() was called.");
+               }
+
+               VK_CHECK(queryResult);
+               std::string name = (poolNdx == QUERY_TYPE_OCCLUSION) ? "OcclusionQueryResults" : "PipelineStatisticsQueryResults";
+               std::string desc = (poolNdx == QUERY_TYPE_OCCLUSION) ? "Occlusion query results" : "PipelineStatistics query results";
+               log << tcu::TestLog::Section(name, desc);
+               for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(queryResults); ++ndx)
+               {
+                       log << tcu::TestLog::Message << "query[slot == " << ndx
+                               << "] result == " << queryResults[ndx] << tcu::TestLog::EndMessage;
+               }
+
+               for (deUint32 queryNdx = 0; queryNdx < DE_LENGTH_OF_ARRAY(queryResults); ++queryNdx)
+               {
+                       if (queryNdx == QUERY_INDEX_CAPTURE_EMPTY && queryResults[queryNdx] != 0u)
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "wrong value of query for index "
+                                       << queryNdx << ", expected any zero value, got "
+                                       << queryResults[0] << "." << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+
+                       if (queryNdx != QUERY_INDEX_CAPTURE_EMPTY && queryResults[queryNdx] == 0)
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "wrong value of query for index "
+                                       << queryNdx << ", expected any non-zero value, got "
+                                       << queryResults[0] << "." << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+               }
+               log << tcu::TestLog::EndSection;
+       }
+
+       // Timestamp query verification
+       if (m_supportedQueryType[QUERY_TYPE_TIMESTAMP])
+       {
+               std::pair<deUint64, deUint64>   queryResultsWithAvailabilityBit[NUM_QUERIES_IN_POOL];
+               size_t queryResultsWithAvailabilityBitSize              = sizeof(queryResultsWithAvailabilityBit);
+               vk::VkResult queryResult        = vk.getQueryPoolResults(device, *m_queryPools[QUERY_TYPE_TIMESTAMP], 0, NUM_QUERIES_IN_POOL, queryResultsWithAvailabilityBitSize, &queryResultsWithAvailabilityBit[0], sizeof(queryResultsWithAvailabilityBit[0]), vk::VK_QUERY_RESULT_64_BIT | vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
+
+               if (queryResult != vk::VK_NOT_READY)
+               {
+                       TCU_FAIL("We don't have available one query, it should return VK_NOT_READY");
+               }
+
+               log << tcu::TestLog::Section("TimestampQueryResults",
+                                                                        "Timestamp query results");
+               for (int ndx = 0; ndx < NUM_QUERIES_IN_POOL; ++ndx)
+               {
+                       log << tcu::TestLog::Message << "query[slot == " << ndx
+                               << "] result == " << queryResultsWithAvailabilityBit[ndx].first << tcu::TestLog::EndMessage;
+               }
+
+
+               for (deUint32 queryNdx = 0; queryNdx < NUM_QUERIES_IN_POOL; ++queryNdx)
+               {
+                       if (queryNdx == QUERY_INDEX_CAPTURE_EMPTY && (queryResultsWithAvailabilityBit[queryNdx].first != 0u || queryResultsWithAvailabilityBit[queryNdx].second != 0u))
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "either wrong value of query for index "
+                                       << queryNdx << " (expected any zero value, got "
+                                       << queryResultsWithAvailabilityBit[queryNdx].first << ") or the result is available (" << queryResultsWithAvailabilityBit[queryNdx].second << ")"
+                                       << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+
+                       if (queryNdx != QUERY_INDEX_CAPTURE_EMPTY && (queryResultsWithAvailabilityBit[queryNdx].first == 0u || queryResultsWithAvailabilityBit[queryNdx].second == 0u))
+                       {
+                               log << tcu::TestLog::Message << "vkGetQueryPoolResults returned "
+                                       "either wrong value of query for index "
+                                       << queryNdx << " (expected any non-zero value, got "
+                                       << queryResults[0] << ") or result is unavailable." << tcu::TestLog::EndMessage;
+                               passed = false;
+                       }
+               }
+               log << tcu::TestLog::EndSection;
+       }
+
+       if (passed)
+       {
+               return tcu::TestStatus(QP_TEST_RESULT_PASS, "Query result verification passed");
+       }
+       return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Query result verification failed");
+}
+
+template<class Instance>
+class QueryPoolConcurrentTest : public vkt::TestCase
+{
+public:
+       QueryPoolConcurrentTest (tcu::TestContext &context, const char *name, const char *description)
+               : TestCase                      (context, name, description)
+       {
+       }
+private:
+       vkt::TestInstance* createInstance (vkt::Context& context) const
+       {
+               return new Instance(context);
+       }
+
+       void initPrograms(vk::SourceCollections& programCollection) const
+       {
+               const std::string fragSrc = std::string(
+                       "#version 400\n"
+                       "layout(location = 0) out vec4 out_FragColor;\n"
+                       "void main()\n"
+                       "{\n"
+                       "       out_FragColor = vec4(0.07, 0.48, 0.75, 1.0);\n"
+                       "       if ((int(gl_FragCoord.x) % 2) == (int(gl_FragCoord.y) % 2))\n"
+                       "               discard;\n"
+                       "}");
+
+               programCollection.glslSources.add("frag") << glu::FragmentSource(fragSrc.c_str());
+
+               programCollection.glslSources.add("vert") << glu::VertexSource("#version 430\n"
+                                                                                                                                                "layout(location = 0) in vec4 in_Position;\n"
+                                                                                                                                                "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
+                                                                                                                                                "void main() {\n"
+                                                                                                                                                "      gl_Position  = in_Position;\n"
+                                                                                                                                                "      gl_PointSize = 1.0;\n"
+                                                                                                                                                "}\n");
+       }
+};
+
+} //anonymous
+
+QueryPoolConcurrentTests::QueryPoolConcurrentTests (tcu::TestContext &testCtx)
+       : TestCaseGroup(testCtx, "concurrent_queries", "Tests for concurrent queries")
+{
+       /* Left blank on purpose */
+}
+
+QueryPoolConcurrentTests::~QueryPoolConcurrentTests (void)
+{
+       /* Left blank on purpose */
+}
+
+void QueryPoolConcurrentTests::init (void)
+{
+       addChild(new QueryPoolConcurrentTest<PrimaryCommandBufferConcurrentTestInstance>(m_testCtx, "primary_command_buffer", ""));
+       addChild(new QueryPoolConcurrentTest<SecondaryCommandBufferConcurrentTestInstance>(m_testCtx, "secondary_command_buffer", ""));
+}
+
+} //QueryPool
+} //vkt
diff --git a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolConcurrentTests.hpp b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolConcurrentTests.hpp
new file mode 100644 (file)
index 0000000..6c49c12
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef _VKTQUERYPOOLCONCURRENTTESTS_HPP
+#define _VKTQUERYPOOLCONCURRENTTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2020 The Khronos Group Inc.
+ * Copyright (c) 2020 Valve Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Concurrent Query Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace QueryPool
+{
+
+class QueryPoolConcurrentTests : public tcu::TestCaseGroup
+{
+public:
+       QueryPoolConcurrentTests        (tcu::TestContext &testCtx);
+       ~QueryPoolConcurrentTests       (void);
+       void init                                       (void);
+
+private:
+       QueryPoolConcurrentTests                                (const QueryPoolConcurrentTests &other);
+       // TODO: Do I need this operator?
+       QueryPoolConcurrentTests&       operator=       (const QueryPoolConcurrentTests &other);
+};
+
+} // QueryPool
+} // vkt
+
+#endif // _VKTQUERYPOOLCONCURRENTTESTS_HPP
index 4ba8cd2..b28475e 100644 (file)
@@ -28,6 +28,7 @@
 #include "vktQueryPoolOcclusionTests.hpp"
 #include "vktQueryPoolStatisticsTests.hpp"
 #include "vktQueryPoolPerformanceTests.hpp"
+#include "vktQueryPoolConcurrentTests.hpp"
 
 namespace vkt
 {
@@ -44,6 +45,7 @@ void createChildren (tcu::TestCaseGroup* queryPoolTests)
        queryPoolTests->addChild(new QueryPoolOcclusionTests(testCtx));
        queryPoolTests->addChild(new QueryPoolStatisticsTests(testCtx));
        queryPoolTests->addChild(new QueryPoolPerformanceTests(testCtx));
+       queryPoolTests->addChild(new QueryPoolConcurrentTests(testCtx));
 }
 
 } // anonymous
index 9fb1cf3..b96d480 100644 (file)
@@ -411189,6 +411189,8 @@ dEQP-VK.query_pool.performance_query.query_graphic
 dEQP-VK.query_pool.performance_query.query_compute
 dEQP-VK.query_pool.performance_query.multiple_pools_graphic
 dEQP-VK.query_pool.performance_query.multiple_pools_compute
+dEQP-VK.query_pool.concurrent_queries.primary_command_buffer
+dEQP-VK.query_pool.concurrent_queries.secondary_command_buffer
 dEQP-VK.draw.concurrent.compute_and_triangle_list
 dEQP-VK.draw.simple_draw.simple_draw_triangle_list
 dEQP-VK.draw.simple_draw.simple_draw_triangle_strip
index a293515..bd5aceb 100644 (file)
@@ -411151,6 +411151,8 @@ dEQP-VK.query_pool.performance_query.query_graphic
 dEQP-VK.query_pool.performance_query.query_compute
 dEQP-VK.query_pool.performance_query.multiple_pools_graphic
 dEQP-VK.query_pool.performance_query.multiple_pools_compute
+dEQP-VK.query_pool.concurrent_queries.primary_command_buffer
+dEQP-VK.query_pool.concurrent_queries.secondary_command_buffer
 dEQP-VK.draw.concurrent.compute_and_triangle_list
 dEQP-VK.draw.simple_draw.simple_draw_triangle_list
 dEQP-VK.draw.simple_draw.simple_draw_triangle_strip