Class KHRPerformanceQuery

java.lang.Object
org.lwjgl.vulkan.KHRPerformanceQuery

public class KHRPerformanceQuery extends Object
The VK_KHR_performance_query extension adds a mechanism to allow querying of performance counters for use in applications and by profiling tools.

Each queue family may expose counters that can be enabled on a queue of that family. We extend VkQueryType to add a new query type for performance queries, and chain a structure on VkQueryPoolCreateInfo to specify the performance queries to enable.

Examples

The following example shows how to find what performance counters a queue family supports, setup a query pool to record these performance counters, how to add the query pool to the command buffer to record information, and how to get the results from the query pool.


 // A previously created physical device
 VkPhysicalDevice physicalDevice;
 
 // One of the queue families our device supports
 uint32_t queueFamilyIndex;
 
 uint32_t counterCount;
 
 // Get the count of counters supported
 vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
   physicalDevice,
   queueFamilyIndex,
   &counterCount,
   NULL,
   NULL);
 
 VkPerformanceCounterKHR* counters =
   malloc(sizeof(VkPerformanceCounterKHR) * counterCount);
 VkPerformanceCounterDescriptionKHR* counterDescriptions =
   malloc(sizeof(VkPerformanceCounterDescriptionKHR) * counterCount);
 
 // Get the counters supported
 vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
   physicalDevice,
   queueFamilyIndex,
   &counterCount,
   counters,
   counterDescriptions);
 
 // Try to enable the first 8 counters
 uint32_t enabledCounters[8];
 
 const uint32_t enabledCounterCount = min(counterCount, 8));
 
 for (uint32_t i = 0; i < enabledCounterCount; i++) {
   enabledCounters[i] = i;
 }
 
 // A previously created device that had the performanceCounterQueryPools feature
 // set to VK_TRUE
 VkDevice device;
 
 VkQueryPoolPerformanceCreateInfoKHR performanceQueryCreateInfo = {
   .sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR,
   .pNext = NULL,
 
   // Specify the queue family that this performance query is performed on
   .queueFamilyIndex = queueFamilyIndex,
 
   // The number of counters to enable
   .counterIndexCount = enabledCounterCount,
 
   // The array of indices of counters to enable
   .pCounterIndices = enabledCounters
 };
 
 
 // Get the number of passes our counters will require.
 uint32_t numPasses;
 
 vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(
   physicalDevice,
   &performanceQueryCreateInfo,
   &numPasses);
 
 VkQueryPoolCreateInfo queryPoolCreateInfo = {
   .sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
   .pNext = &performanceQueryCreateInfo,
   .flags = 0,
   // Using our new query type here
   .queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR,
   .queryCount = 1,
   .pipelineStatistics = 0
 };
 
 VkQueryPool queryPool;
 
 VkResult result = vkCreateQueryPool(
   device,
   &queryPoolCreateInfo,
   NULL,
   &queryPool);
 
 assert(VK_SUCCESS == result);
 
 // A queue from queueFamilyIndex
 VkQueue queue;
 
 // A command buffer we want to record counters on
 VkCommandBuffer commandBuffer;
 
 VkCommandBufferBeginInfo commandBufferBeginInfo = {
   .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
   .pNext = NULL,
   .flags = 0,
   .pInheritanceInfo = NULL
 };
 
 VkAcquireProfilingLockInfoKHR lockInfo = {
   .sType = VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR,
   .pNext = NULL,
   .flags = 0,
   .timeout = UINT64_MAX // Wait forever for the lock
 };
 
 // Acquire the profiling lock before we record command buffers
 // that will use performance queries
 
 result = vkAcquireProfilingLockKHR(device, &lockInfo);
 
 assert(VK_SUCCESS == result);
 
 result = vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo);
 
 assert(VK_SUCCESS == result);
 
 vkCmdResetQueryPool(
   commandBuffer,
   queryPool,
   0,
   1);
 
 vkCmdBeginQuery(
   commandBuffer,
   queryPool,
   0,
   0);
 
 // Perform the commands you want to get performance information on
 // ...
 
 // Perform a barrier to ensure all previous commands were complete before
 // ending the query
 vkCmdPipelineBarrier(commandBuffer,
   VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
   VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
   0,
   0,
   NULL,
   0,
   NULL,
   0,
   NULL);
 
 vkCmdEndQuery(
   commandBuffer,
   queryPool,
   0);
 
 result = vkEndCommandBuffer(commandBuffer);
 
 assert(VK_SUCCESS == result);
 
 for (uint32_t counterPass = 0; counterPass < numPasses; counterPass++) {
 
   VkPerformanceQuerySubmitInfoKHR performanceQuerySubmitInfo = {
     VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR,
     NULL,
     counterPass
   };
 
 
   // Submit the command buffer and wait for its completion
   // ...
 }
 
 // Release the profiling lock after the command buffer is no longer in the
 // pending state.
 vkReleaseProfilingLockKHR(device);
 
 result = vkResetCommandBuffer(commandBuffer, 0);
 
 assert(VK_SUCCESS == result);
 
 // Create an array to hold the results of all counters
 VkPerformanceCounterResultKHR* recordedCounters = malloc(
   sizeof(VkPerformanceCounterResultKHR) * enabledCounterCount);
 
 result = vkGetQueryPoolResults(
   device,
   queryPool,
   0,
   1,
   sizeof(VkPerformanceCounterResultKHR) * enabledCounterCount,
   recordedCounters,
   sizeof(VkPerformanceCounterResultKHR) * enabledCounterCount,
   NULL);
 
 // recordedCounters is filled with our counters, we will look at one for posterity
 switch (counters[0].storage) {
   case VK_PERFORMANCE_COUNTER_STORAGE_INT32:
     // use recordCounters[0].int32 to get at the counter result!
     break;
   case VK_PERFORMANCE_COUNTER_STORAGE_INT64:
     // use recordCounters[0].int64 to get at the counter result!
     break;
   case VK_PERFORMANCE_COUNTER_STORAGE_UINT32:
     // use recordCounters[0].uint32 to get at the counter result!
     break;
   case VK_PERFORMANCE_COUNTER_STORAGE_UINT64:
     // use recordCounters[0].uint64 to get at the counter result!
     break;
   case VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32:
     // use recordCounters[0].float32 to get at the counter result!
     break;
   case VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64:
     // use recordCounters[0].float64 to get at the counter result!
     break;
 }
Name String
VK_KHR_performance_query
Extension Type
Device extension
Registered Extension Number
117
Revision
1
Extension and Version Dependencies
VK_KHR_get_physical_device_properties2 or Version 1.1
Special Use
Contact
Other Extension Metadata
Last Modified Date
2019-10-08
IP Status
No known IP claims.
Contributors
  • Jesse Barker, Unity Technologies
  • Kenneth Benzie, Codeplay
  • Jan-Harald Fredriksen, ARM
  • Jeff Leger, Qualcomm
  • Jesse Hall, Google
  • Tobias Hector, AMD
  • Neil Henning, Codeplay
  • Baldur Karlsson
  • Lionel Landwerlin, Intel
  • Peter Lohrmann, AMD
  • Alon Or-bach, Samsung
  • Daniel Rakos, AMD
  • Niklas Smedberg, Unity Technologies
  • Igor Ostrowski, Intel