[Mesa-dev] [PATCH v2 03/16] anv/GetQueryPoolResults: Actually implement the spec

Jason Ekstrand jason at jlekstrand.net
Thu Mar 16 21:33:58 UTC 2017


The Vulkan spec is fairly clear about when we should and should not
write query pool results.  We're also supposed to return VK_NOT_READY if
VK_QUERY_RESULT_PARTIAL_BIT is not set and we come across any queries
which are not yet finished.  This fixes rendering corruptions on The
Talos Principle where geometry flickers in and out due to bogus query
results being returned by the driver.  These issues are most noticable
on Sky Lake GT4 2hen running on "ultra" settings.

Reviewed-By: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100182
Cc: "17.0 13.0" <mesa-stable at lists.freedesktop.org>
---
 src/intel/vulkan/genX_query.c | 52 ++++++++++++++++++++++++++++++-------------
 1 file changed, 36 insertions(+), 16 deletions(-)

diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c
index 72ac2cb..b5955d3 100644
--- a/src/intel/vulkan/genX_query.c
+++ b/src/intel/vulkan/genX_query.c
@@ -139,32 +139,52 @@ VkResult genX(GetQueryPoolResults)(
                            MIN2(size, pool->bo.size - offset));
    }
 
+   VkResult status = VK_SUCCESS;
    for (uint32_t i = 0; i < queryCount; i++) {
-      switch (pool->type) {
-      case VK_QUERY_TYPE_OCCLUSION: {
-         result = slot[firstQuery + i].end - slot[firstQuery + i].begin;
-         break;
-      }
-      case VK_QUERY_TYPE_PIPELINE_STATISTICS:
-         unreachable("pipeline stats not supported");
-      case VK_QUERY_TYPE_TIMESTAMP: {
-         result = slot[firstQuery + i].begin;
-         break;
-      }
-      default:
-         unreachable("invalid pool type");
+      bool available = slot[firstQuery + i].available;
+
+      /* From the Vulkan 1.0.42 spec:
+       *
+       *    "If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are
+       *    both not set then no result values are written to pData for
+       *    queries that are in the unavailable state at the time of the call,
+       *    and vkGetQueryPoolResults returns VK_NOT_READY. However,
+       *    availability state is still written to pData for those queries if
+       *    VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set."
+       */
+      bool write_results = available || (flags & VK_QUERY_RESULT_PARTIAL_BIT);
+
+      if (write_results) {
+         switch (pool->type) {
+         case VK_QUERY_TYPE_OCCLUSION: {
+            result = slot[firstQuery + i].end - slot[firstQuery + i].begin;
+            break;
+         }
+         case VK_QUERY_TYPE_PIPELINE_STATISTICS:
+            unreachable("pipeline stats not supported");
+         case VK_QUERY_TYPE_TIMESTAMP: {
+            result = slot[firstQuery + i].begin;
+            break;
+         }
+         default:
+            unreachable("invalid pool type");
+         }
+      } else {
+         status = VK_NOT_READY;
       }
 
       if (flags & VK_QUERY_RESULT_64_BIT) {
          uint64_t *dst = pData;
-         dst[0] = result;
+         if (write_results)
+            dst[0] = result;
          if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
             dst[1] = slot[firstQuery + i].available;
       } else {
          uint32_t *dst = pData;
          if (result > UINT32_MAX)
             result = UINT32_MAX;
-         dst[0] = result;
+         if (write_results)
+            dst[0] = result;
          if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
             dst[1] = slot[firstQuery + i].available;
       }
@@ -174,7 +194,7 @@ VkResult genX(GetQueryPoolResults)(
          break;
    }
 
-   return VK_SUCCESS;
+   return status;
 }
 
 static void
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list