venus: ensure consistency of query overflow behavior
authorYiwei Zhang <zzyiwei@chromium.org>
Wed, 12 Jul 2023 17:09:22 +0000 (17:09 +0000)
committerMarge Bot <emma+marge@anholt.net>
Wed, 12 Jul 2023 21:18:06 +0000 (21:18 +0000)
Fixes: e6cffa1f0e4e ("venus: use feedback for vkGetQueryPoolResults")
Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24123>

src/virtio/vulkan/vn_physical_device.c
src/virtio/vulkan/vn_physical_device.h
src/virtio/vulkan/vn_query_pool.c
src/virtio/vulkan/vn_query_pool.h

index bc7a428d0a45dad9afffa9dd7f58e2e7b495a182..98eec8c74f5e4b44c7a7eaca3cfc99199e079d0f 100644 (file)
@@ -738,6 +738,8 @@ vn_physical_device_init_properties(struct vn_physical_device *physical_dev)
    }
    memcpy(vk10_props->deviceName, device_name, device_name_len + 1);
 
+   /* store renderer VkDriverId for implementation specific workarounds */
+   physical_dev->renderer_driver_id = vk12_props->driverID;
    VN_SET_CORE_VALUE(vk12_props, driverID, VK_DRIVER_ID_MESA_VENUS);
 
    snprintf(vk12_props->driverName, sizeof(vk12_props->driverName), "venus");
index 729bd18fd5c38554b7d997397e40eb9fd29590a3..1915d9d7a9ac5b5faf38589bb99071c6ee127904 100644 (file)
@@ -117,6 +117,7 @@ struct vn_physical_device {
 
    struct vn_physical_device_features features;
    struct vn_physical_device_properties properties;
+   enum VkDriverId renderer_driver_id;
 
    VkQueueFamilyProperties2 *queue_family_properties;
    uint32_t queue_family_count;
index 3973f3020d4e6a220b3d841786142b82d106aa10..e8bca85a8bf8b3fb1c42ddbb6e944dfe0c25920f 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "vn_device.h"
 #include "vn_feedback.h"
+#include "vn_physical_device.h"
 
 /* query pool commands */
 
@@ -100,6 +101,26 @@ vn_CreateQueryPool(VkDevice device,
       }
    }
 
+   /* Venus has to handle overflow behavior with query feedback to keep
+    * consistency between vkCmdCopyQueryPoolResults and vkGetQueryPoolResults.
+    * The default query feedback behavior is to wrap on overflow. However, per
+    * spec:
+    *
+    * If an unsigned integer query’s value overflows the result type, the
+    * value may either wrap or saturate.
+    *
+    * We detect the renderer side implementation to align with the
+    * implementation specific behavior.
+    */
+   switch (dev->physical_device->renderer_driver_id) {
+   case VK_DRIVER_ID_ARM_PROPRIETARY:
+   case VK_DRIVER_ID_MESA_TURNIP:
+      pool->saturate_on_overflow = true;
+      break;
+   default:
+      break;
+   };
+
    VkQueryPool pool_handle = vn_query_pool_to_handle(pool);
    vn_async_vkCreateQueryPool(dev->instance, device, pCreateInfo, NULL,
                               &pool_handle);
@@ -205,8 +226,13 @@ vn_get_query_pool_feedback(struct vn_query_pool *pool,
          const uint32_t avail =
             (uint32_t)src[src_index + pool->result_array_size];
          if (avail) {
-            for (uint32_t j = 0; j < pool->result_array_size; j++)
-               dst[dst_index + j] = (uint32_t)src[src_index + j];
+            for (uint32_t j = 0; j < pool->result_array_size; j++) {
+               const uint64_t src_val = src[src_index + j];
+               dst[dst_index + j] =
+                  src_val > UINT32_MAX && pool->saturate_on_overflow
+                     ? UINT32_MAX
+                     : (uint32_t)src_val;
+            }
          } else {
             result = VK_NOT_READY;
             /* valid to return result of 0 if partial bit is set */
index efaad02734b94056db3893e0fbd83dbf682612e1..9246b7d3c86f98530ddc4a8ff5508f8e9eee3bbe 100644 (file)
@@ -23,6 +23,7 @@ struct vn_query_pool {
    /* non-NULL if VN_PERF_NO_QUERY_FEEDBACK is disabled */
    struct vn_feedback_buffer *feedback;
    uint32_t result_array_size;
+   bool saturate_on_overflow;
 };
 VK_DEFINE_NONDISP_HANDLE_CASTS(vn_query_pool,
                                base.base,