diff options
author | Brian Ho <[email protected]> | 2020-01-24 16:39:47 -0500 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-01-30 20:30:46 +0000 |
commit | 1a3e2a7fa8bf184b5f9214d4c404e4c2c754aa58 (patch) | |
tree | 54990863aaba23ce5db5cdda5dfe8efceac85f83 | |
parent | 1c3319cf81779ba6a17223d22ddd3afc68acab1e (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.c | 52 |
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; } |