# vkGetQueryPoolResults(3) Manual Page

## Name

vkGetQueryPoolResults - Copy results of queries in a query pool to a host memory region

## C Specification

To retrieve status and results for a set of queries, call:

    VkResult vkGetQueryPoolResults(
        VkDevice                                    device,
        VkQueryPool                                 queryPool,
        uint32_t                                    firstQuery,
        uint32_t                                    queryCount,
        size_t                                      dataSize,
        void*                                       pData,
        VkDeviceSize                                stride,
        VkQueryResultFlags                          flags);

## Parameters

- `device` is the logical device that owns the query pool.

- `queryPool` is the query pool managing the queries containing the desired results.

- `firstQuery` is the initial query index.

- `queryCount` is the number of queries to read.

- `dataSize` is the size in bytes of the buffer pointed to by `pData`.

- `pData` is a pointer to a user-allocated buffer where the results will be written

- `stride` is the stride in bytes between results for individual queries within `pData`.

- `flags` is a bitmask of VkQueryResultFlagBits specifying how and when results are returned.

## Description

The range of queries read is defined by [`firstQuery`, `firstQuery` + `queryCount` - 1]. For pipeline statistics queries, each query index in the pool contains one integer value for each bit that is enabled in VkQueryPoolCreateInfo::`pipelineStatistics` when the pool is created.

If no bits are set in `flags`, and all requested queries are in the available state, results are written as an array of 32-bit unsigned integer values. The behavior when not all queries are available, is described below.

If `VK_QUERY_RESULT_64_BIT` is not set and the result overflows a 32-bit value, the value may either wrap or saturate. Similarly, if `VK_QUERY_RESULT_64_BIT` is set and the result overflows a 64-bit value, the value may either wrap or saturate.

If `VK_QUERY_RESULT_WAIT_BIT` is set, Vulkan will wait for each query to be in the available state before retrieving the numerical results for that query. In this case, `vkGetQueryPoolResults` is guaranteed to succeed and return `VK_SUCCESS` if the queries become available in a finite time (i.e. if they have been issued and not reset). If queries will never finish (e.g. due to being reset but not issued), then `vkGetQueryPoolResults` may not return in finite time.

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.

| Note Applications must take care to ensure that use of the `VK_QUERY_RESULT_WAIT_BIT` bit has the desired effect. For example, if a query has been used previously and a command buffer records the commands `vkCmdResetQueryPool`, `vkCmdBeginQuery`, and `vkCmdEndQuery` for that query, then the query will remain in the available state until `vkResetQueryPool` is called or the `vkCmdResetQueryPool` 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. The above also applies when `VK_QUERY_RESULT_WAIT_BIT` is used in combination with `VK_QUERY_RESULT_WITH_AVAILABILITY_BIT`. In this case, the returned availability status may reflect the result of a previous use of the query unless `vkResetQueryPool` is called or the `vkCmdResetQueryPool` command has been executed since the last use of the query.

| Note Applications can double-buffer query pool usage, with a pool per frame, and reset queries at the end of the frame in which they are read.

If `VK_QUERY_RESULT_PARTIAL_BIT` is set, `VK_QUERY_RESULT_WAIT_BIT` is not set, and the query’s status is unavailable, an intermediate result value between zero and the final result value is written to `pData` for that query.

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. When `VK_QUERY_RESULT_WITH_AVAILABILITY_BIT` is used, implementations must guarantee that if they return a non-zero availability value then the numerical results must be valid, assuming the results are not reset by a subsequent command.

| Note Satisfying this guarantee may require careful ordering by the application, e.g. to read the availability status before reading the results.

Valid Usage

- `firstQuery` must be less than the number of queries in `queryPool`

- If `VK_QUERY_RESULT_64_BIT` is not set in `flags`, then `pData` and `stride` must be multiples of `4`

- If `VK_QUERY_RESULT_64_BIT` is not set in `flags` and the `queryType` used to create `queryPool` was not `VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR`, then `pData` and `stride` must be multiples of `4`

- If `VK_QUERY_RESULT_64_BIT` is set in `flags` then `pData` and `stride` must be multiples of `8`

- If the `queryType` used to create `queryPool` was `VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR`, then `pData` and `stride` must be multiples of the size of VkPerformanceCounterResultKHR

- The sum of `firstQuery` and `queryCount` must be less than or equal to the number of queries in `queryPool`

- `dataSize` must be large enough to contain the result of each query, as described here

- If the `queryType` used to create `queryPool` was `VK_QUERY_TYPE_TIMESTAMP`, `flags` must not contain `VK_QUERY_RESULT_PARTIAL_BIT`

- If the `queryType` used to create `queryPool` was `VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR`, `flags` must not contain `VK_QUERY_RESULT_WITH_AVAILABILITY_BIT`, `VK_QUERY_RESULT_PARTIAL_BIT` or `VK_QUERY_RESULT_64_BIT`

- If the `queryType` used to create `queryPool` was `VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR`, the `queryPool` must have been recorded once for each pass as retrieved via a call to vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR

Valid Usage (Implicit)

- `device` must be a valid VkDevice handle

- `queryPool` must be a valid VkQueryPool handle

- `pData` must be a valid pointer to an array of `dataSize` bytes

- `flags` must be a valid combination of VkQueryResultFlagBits values

- `dataSize` must be greater than `0`

- `queryPool` must have been created, allocated, or retrieved from `device`

Return Codes

On success, this command returns

  - `VK_SUCCESS`

  - `VK_NOT_READY`

On failure, this command returns

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

  - `VK_ERROR_DEVICE_LOST`

## See Also

VkDevice, `VkDeviceSize`, VkQueryPool, VkQueryResultFlags

## Document Notes

For more information, see the Vulkan Specification

This page is extracted from the Vulkan Specification. Fixes and changes should be made to the Specification, not directly.

## Copyright

Copyright (c) 2014-2020 Khronos Group. This work is licensed under a Creative Commons Attribution 4.0 International License.