summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Ho <brian@brkho.com>2020-01-24 16:39:47 -0500
committerMarge Bot <eric+marge@anholt.net>2020-01-30 20:30:46 +0000
commit1a3e2a7fa8bf184b5f9214d4c404e4c2c754aa58 (patch)
tree54990863aaba23ce5db5cdda5dfe8efceac85f83
parent1c3319cf81779ba6a17223d22ddd3afc68acab1e (diff)
turnip: Fix vkGetQueryPoolResults with available flag
Previously, calling vkGetQueryPoolResults with the VK_QUERY_RESULT_WITH_AVAILABILITY_BIT flag set the query result field in *pData to 0 if unavailable and the query result if available. This was a misunderstanding of the Vulkan spec, and this commit corrects the behavior to eriting a separate available result in addition to the query result. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3560>
-rw-r--r--src/freedreno/vulkan/tu_query.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/src/freedreno/vulkan/tu_query.c b/src/freedreno/vulkan/tu_query.c
index bb6cc2247ff..c37647154f7 100644
--- a/src/freedreno/vulkan/tu_query.c
+++ b/src/freedreno/vulkan/tu_query.c
@@ -168,6 +168,20 @@ wait_for_available(struct tu_device *device, struct tu_query_pool *pool,
return vk_error(device->instance, VK_TIMEOUT);
}
+/* Writes a query value to a buffer from the CPU. */
+static void
+write_query_value_cpu(char* base,
+ uint32_t offset,
+ uint64_t value,
+ VkQueryResultFlags flags)
+{
+ if (flags & VK_QUERY_RESULT_64_BIT) {
+ *(uint64_t*)(base + (offset * sizeof(uint64_t))) = value;
+ } else {
+ *(uint32_t*)(base + (offset * sizeof(uint32_t))) = value;
+ }
+}
+
static VkResult
get_occlusion_query_pool_results(struct tu_device *device,
struct tu_query_pool *pool,
@@ -180,7 +194,7 @@ get_occlusion_query_pool_results(struct tu_device *device,
{
assert(dataSize >= stride * queryCount);
- char *query_result = pData;
+ char *result_base = pData;
VkResult result = VK_SUCCESS;
for (uint32_t i = 0; i < queryCount; i++) {
uint32_t query = firstQuery + i;
@@ -203,23 +217,14 @@ get_occlusion_query_pool_results(struct tu_device *device,
*/
result = VK_NOT_READY;
if (!(flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)) {
- query_result += stride;
+ result_base += stride;
continue;
}
}
- uint64_t value;
- if (available) {
- value = slot->result.value;
- } else if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
- /* From the Vulkan 1.1.130 spec:
- *
- * If VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set, the final
- * integer value written for each query is non-zero if the query’s
- * status was available or zero if the status was unavailable.
- */
- value = 0;
- } else if (flags & VK_QUERY_RESULT_PARTIAL_BIT) {
+ if (available)
+ write_query_value_cpu(result_base, 0, slot->result.value, flags);
+ else if (flags & VK_QUERY_RESULT_PARTIAL_BIT)
/* From the Vulkan 1.1.130 spec:
*
* If VK_QUERY_RESULT_PARTIAL_BIT is set, VK_QUERY_RESULT_WAIT_BIT
@@ -229,15 +234,18 @@ get_occlusion_query_pool_results(struct tu_device *device,
*
* Just return 0 here for simplicity since it's a valid result.
*/
- value = 0;
- }
+ write_query_value_cpu(result_base, 0, 0, flags);
- if (flags & VK_QUERY_RESULT_64_BIT) {
- *(uint64_t*)query_result = value;
- } else {
- *(uint32_t*)query_result = value;
- }
- query_result += stride;
+ if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
+ /* From the Vulkan 1.1.130 spec:
+ *
+ * If VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set, the final
+ * integer value written for each query is non-zero if the query’s
+ * status was available or zero if the status was unavailable.
+ */
+ write_query_value_cpu(result_base, 1, available, flags);
+
+ result_base += stride;
}
return result;
}