From d8d71912ba7fa97069a10535b175eb6dddf67e9c Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 5 Jan 2020 22:42:34 -0800 Subject: Vulkan backend: few improvements to query operation --- .../include/VulkanUtilities/VulkanCommandBuffer.h | 14 +++++++++----- Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp | 3 ++- Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp | 17 ++++++++++------- 3 files changed, 21 insertions(+), 13 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h index 811a1671..ef454910 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h @@ -453,16 +453,20 @@ public: VkQueryControlFlags flags, uint32_t queryFlag) { + // queryPool must have been created with a queryType that differs from that of any queries that + // are active within commandBuffer (17.2). In other words, only one query of given type can be active + // in the command buffer. + if ((m_State.InsidePassQueries | m_State.OutsidePassQueries) & queryFlag) { - LOG_ERROR_MESSAGE("Another query of the same type is already active. " - "Overlapping queries do not work in Vulkan. The command will be ignored."); + LOG_ERROR_MESSAGE("Another query of the same type is already active in the command buffer. " + "Overlapping queries are not allowed in Vulkan. The command will be ignored."); return; } - // A query must either begin and end inside the same subpass of a render - // pass instance, or must both begin and end outside of a render pass instance - // (i.e. contain entire render pass instances) (17.2). + // A query must either begin and end inside the same subpass of a render pass instance, or must both + // begin and end outside of a render pass instance (i.e. contain entire render pass instances) (17.2). + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdBeginQuery(m_VkCmdBuffer, queryPool, query, flags); if (m_State.RenderPass != VK_NULL_HANDLE) diff --git a/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp b/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp index a3d0b92b..d7a47a6d 100644 --- a/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp @@ -110,7 +110,8 @@ QueryManagerVk::QueryManagerVk(RenderDeviceVkImpl* pRenderDeviceVk, HeapInfo.vkQueryPool = LogicalDevice.CreateQueryPool(QueryPoolCI, "QueryManagerVk: query pool"); - // Queries must be reset before first use. + // After query pool creation, each query must be reset before it is used. + // Queries must also be reset between uses (17.2). vkCmdResetQueryPool(vkCmdBuff, HeapInfo.vkQueryPool, 0, QueryPoolCI.queryCount); HeapInfo.AvailableQueries.resize(HeapInfo.PoolSize); diff --git a/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp index f1f670d6..3eb95eba 100644 --- a/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp @@ -135,8 +135,8 @@ bool QueryVkImpl::GetData(void* pData, Uint32 DataSize) // command executes on a queue. Applications can use fences or events to ensure that a query has // already been reset before checking for its results or availability status. Otherwise, a stale // value could be returned from a previous use of the query. - LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); - if (Results[1] == 0) + auto res = LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); + if (res != VK_SUCCESS || Results[1] == 0) return false; auto& QueryData = *reinterpret_cast(pData); @@ -147,8 +147,8 @@ bool QueryVkImpl::GetData(void* pData, Uint32 DataSize) case QUERY_TYPE_BINARY_OCCLUSION: { uint64_t Results[2]; - LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); - if (Results[1] == 0) + auto res = LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); + if (res != VK_SUCCESS || Results[1] == 0) return false; auto& QueryData = *reinterpret_cast(pData); @@ -159,8 +159,8 @@ bool QueryVkImpl::GetData(void* pData, Uint32 DataSize) case QUERY_TYPE_TIMESTAMP: { uint64_t Results[2]; - LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); - if (Results[1] == 0) + auto res = LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); + if (res != VK_SUCCESS || Results[1] == 0) return false; auto& QueryData = *reinterpret_cast(pData); @@ -176,7 +176,10 @@ bool QueryVkImpl::GetData(void* pData, Uint32 DataSize) // order starting from the least significant bit. (17.2) Uint64 Results[12]; - LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); + auto res = LogicalDevice.GetQueryPoolResults(vkQueryPool, m_QueryPoolIndex, 1, sizeof(Results), Results, 0, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); + if (res != VK_SUCCESS) + return false; + auto& QueryData = *reinterpret_cast(pData); const auto EnabledShaderStages = LogicalDevice.GetEnabledGraphicsShaderStages(); -- cgit v1.2.3