// Copyright 2019-2021 The Khronos Group, Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[queries-performance]]
== Performance Queries

_Performance queries_ provide applications with a mechanism for getting
performance counter information about the execution of command buffers,
render passes, and commands.

Each queue family advertises the performance counters that can: be queried
on a queue of that family via a call to
flink:vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR.
Implementations may: limit access to performance counters based on platform
requirements or only to specialized drivers for development purposes.

[NOTE]
.Note
====
This may include no performance counters being enumerated, or a reduced set.
Please refer to platform-specific documentation for guidance on any such
restrictions.
====

Performance queries use the existing flink:vkCmdBeginQuery and
flink:vkCmdEndQuery to control what command buffers, render passes, or
commands to get performance information for.

Implementations may: require multiple passes where the command buffer,
render passes, or commands being recorded are the same and are executed on
the same queue to record performance counter data.
This is achieved by submitting the same batch and providing a
slink:VkPerformanceQuerySubmitInfoKHR structure containing a counter pass
index.
The number of passes required for a given performance query pool can: be
queried via a call to
flink:vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR.

[NOTE]
.Note
====
Command buffers created with
ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT must: not be re-submitted.
Changing command buffer usage bits may: affect performance.
To avoid this, the application should: re-record any command buffers with
the ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT when multiple counter
passes are required.
====

Performance counter results from a performance query pool can: be obtained
with the command flink:vkGetQueryPoolResults.

[open,refpage='VkPerformanceCounterResultKHR',desc='Union containing a performance counter result',type='structs']
--
Performance query results are returned in an array of
sname:VkPerformanceCounterResultKHR unions containing the data associated
with each counter in the query, stored in the same order as the counters
supplied in pname:pCounterIndices when creating the performance query.
The slink:VkPerformanceCounterKHR::pname:unit enumeration specifies how to
parse the counter data.

include::{generated}/api/structs/VkPerformanceCounterResultKHR.txt[]
--


[[profiling-lock]]
=== Profiling Lock

[open,refpage='vkAcquireProfilingLockKHR',desc='Acquires the profiling lock',type='protos']
--
To record and submit a command buffer that contains a performance query pool
the profiling lock must: be held.
The profiling lock must: be acquired prior to any call to
flink:vkBeginCommandBuffer that will be using a performance query pool.
The profiling lock must: be held while any command buffer that contains a
performance query pool is in the _recording_, _executable_, or _pending
state_.
To acquire the profiling lock, call:

include::{generated}/api/protos/vkAcquireProfilingLockKHR.txt[]

  * pname:device is the logical device to profile.
  * pname:pInfo is a pointer to a sname:VkAcquireProfilingLockInfoKHR
    structure which contains information about how the profiling is to be
    acquired.

Implementations may: allow multiple actors to hold the profiling lock
concurrently.

include::{generated}/validity/protos/vkAcquireProfilingLockKHR.txt[]
--

[open,refpage='VkAcquireProfilingLockInfoKHR',desc='Structure specifying parameters to acquire the profiling lock',type='structs']
--
The sname:VkAcquireProfilingLockInfoKHR structure is defined as:

include::{generated}/api/structs/VkAcquireProfilingLockInfoKHR.txt[]

  * pname:sType is the type of this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:flags is reserved for future use.
  * pname:timeout indicates how long the function waits, in nanoseconds, if
    the profiling lock is not available.

include::{generated}/validity/structs/VkAcquireProfilingLockInfoKHR.txt[]

If pname:timeout is 0, fname:vkAcquireProfilingLockKHR will not block while
attempting to acquire the profling lock.
If pname:timeout is code:UINT64_MAX, the function will not return until the
profiling lock was acquired.
--

[open,refpage='VkAcquireProfilingLockFlagBitsKHR',desc='Reserved for future use',type='enums']
--
include::{generated}/api/enums/VkAcquireProfilingLockFlagBitsKHR.txt[]
--

[open,refpage='VkAcquireProfilingLockFlagsKHR',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkAcquireProfilingLockFlagsKHR.txt[]

tlink:VkAcquireProfilingLockFlagsKHR is a bitmask type for setting a mask,
but is currently reserved for future use.
--

[open,refpage='vkReleaseProfilingLockKHR',desc='Releases the profiling lock',type='protos']
--
To release the profiling lock, call:

include::{generated}/api/protos/vkReleaseProfilingLockKHR.txt[]

  * pname:device is the logical device to cease profiling on.

.Valid Usage
****
  * [[VUID-vkReleaseProfilingLockKHR-device-03235]]
    The profiling lock of pname:device must: have been held via a previous
    successful call to flink:vkAcquireProfilingLockKHR
****

include::{generated}/validity/protos/vkReleaseProfilingLockKHR.txt[]
--
