// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[debugging]]
= Debugging

To aid developers in tracking down errors in the application's use of
Vulkan, particularly in combination with an external debugger or profiler,
_debugging extensions_ may be available.

[open,refpage='VkObjectType',desc='Specify an enumeration to track object handle types',type='enums']
--
The elink:VkObjectType enumeration defines values, each of which corresponds
to a specific Vulkan handle type.
These values can: be used to associate debug information with a particular
type of object through one or more extensions.

include::{generated}/api/enums/VkObjectType.adoc[]

[[debugging-object-types]]
.`VkObjectType` and Vulkan Handle Relationship
[width="80%",cols="<35,<23",options="header"]
|====
| elink:VkObjectType                         | Vulkan Handle Type
| ename:VK_OBJECT_TYPE_UNKNOWN               | Unknown/Undefined Handle
| ename:VK_OBJECT_TYPE_INSTANCE              | slink:VkInstance
| ename:VK_OBJECT_TYPE_PHYSICAL_DEVICE       | slink:VkPhysicalDevice
| ename:VK_OBJECT_TYPE_DEVICE                | slink:VkDevice
| ename:VK_OBJECT_TYPE_QUEUE                 | slink:VkQueue
| ename:VK_OBJECT_TYPE_SEMAPHORE             | slink:VkSemaphore
| ename:VK_OBJECT_TYPE_COMMAND_BUFFER        | slink:VkCommandBuffer
| ename:VK_OBJECT_TYPE_FENCE                 | slink:VkFence
| ename:VK_OBJECT_TYPE_DEVICE_MEMORY         | slink:VkDeviceMemory
| ename:VK_OBJECT_TYPE_BUFFER                | slink:VkBuffer
| ename:VK_OBJECT_TYPE_IMAGE                 | slink:VkImage
| ename:VK_OBJECT_TYPE_EVENT                 | slink:VkEvent
| ename:VK_OBJECT_TYPE_QUERY_POOL            | slink:VkQueryPool
| ename:VK_OBJECT_TYPE_BUFFER_VIEW           | slink:VkBufferView
| ename:VK_OBJECT_TYPE_IMAGE_VIEW            | slink:VkImageView
ifndef::VKSC_VERSION_1_0[]
| ename:VK_OBJECT_TYPE_SHADER_MODULE         | slink:VkShaderModule
endif::VKSC_VERSION_1_0[]
| ename:VK_OBJECT_TYPE_PIPELINE_CACHE        | slink:VkPipelineCache
| ename:VK_OBJECT_TYPE_PIPELINE_LAYOUT       | slink:VkPipelineLayout
| ename:VK_OBJECT_TYPE_RENDER_PASS           | slink:VkRenderPass
| ename:VK_OBJECT_TYPE_PIPELINE              | slink:VkPipeline
| ename:VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT | slink:VkDescriptorSetLayout
| ename:VK_OBJECT_TYPE_SAMPLER               | slink:VkSampler
| ename:VK_OBJECT_TYPE_DESCRIPTOR_POOL       | slink:VkDescriptorPool
| ename:VK_OBJECT_TYPE_DESCRIPTOR_SET        | slink:VkDescriptorSet
| ename:VK_OBJECT_TYPE_FRAMEBUFFER           | slink:VkFramebuffer
| ename:VK_OBJECT_TYPE_COMMAND_POOL          | slink:VkCommandPool
ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[]
| ename:VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION | slink:VkSamplerYcbcrConversion
endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[]
ifdef::VK_VERSION_1_1,VK_KHR_descriptor_update_template[]
ifndef::VKSC_VERSION_1_0[]
| ename:VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE | slink:VkDescriptorUpdateTemplate
endif::VKSC_VERSION_1_0[]
endif::VK_VERSION_1_1,VK_KHR_descriptor_update_template[]
ifdef::VK_VERSION_1_3,VK_EXT_private_data[]
| ename:VK_OBJECT_TYPE_PRIVATE_DATA_SLOT | slink:VkPrivateDataSlot
endif::VK_VERSION_1_3,VK_EXT_private_data[]
ifdef::VK_KHR_surface[]
| ename:VK_OBJECT_TYPE_SURFACE_KHR           | slink:VkSurfaceKHR
endif::VK_KHR_surface[]
ifdef::VK_KHR_swapchain[]
| ename:VK_OBJECT_TYPE_SWAPCHAIN_KHR         | slink:VkSwapchainKHR
endif::VK_KHR_swapchain[]
ifdef::VK_KHR_display[]
| ename:VK_OBJECT_TYPE_DISPLAY_KHR           | slink:VkDisplayKHR
| ename:VK_OBJECT_TYPE_DISPLAY_MODE_KHR      | slink:VkDisplayModeKHR
endif::VK_KHR_display[]
ifdef::VK_EXT_debug_report[]
| ename:VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT | slink:VkDebugReportCallbackEXT
endif::VK_EXT_debug_report[]
ifdef::VK_KHR_video_queue[]
| ename:VK_OBJECT_TYPE_VIDEO_SESSION_KHR | slink:VkVideoSessionKHR
| ename:VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR | slink:VkVideoSessionParametersKHR
endif::VK_KHR_video_queue[]
ifdef::VK_EXT_debug_utils[]
| ename:VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT | slink:VkDebugUtilsMessengerEXT
endif::VK_EXT_debug_utils[]
ifdef::VK_KHR_acceleration_structure[]
| ename:VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR | slink:VkAccelerationStructureKHR
endif::VK_KHR_acceleration_structure[]
ifdef::VK_EXT_validation_cache[]
| ename:VK_OBJECT_TYPE_VALIDATION_CACHE_EXT | slink:VkValidationCacheEXT
endif::VK_EXT_validation_cache[]
ifdef::VK_NV_ray_tracing[]
| ename:VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV | slink:VkAccelerationStructureNV
endif::VK_NV_ray_tracing[]
ifdef::VK_INTEL_performance_query[]
| ename:VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL | slink:VkPerformanceConfigurationINTEL
endif::VK_INTEL_performance_query[]
ifdef::VK_KHR_deferred_host_operations[]
| ename:VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR | slink:VkDeferredOperationKHR
endif::VK_KHR_deferred_host_operations[]
ifdef::VK_NV_device_generated_commands[]
| ename:VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV | slink:VkIndirectCommandsLayoutNV
endif::VK_NV_device_generated_commands[]
ifdef::VK_FUCHSIA_buffer_collection[]
| ename:VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA | slink:VkBufferCollectionFUCHSIA
endif::VK_FUCHSIA_buffer_collection[]
ifdef::VK_EXT_opacity_micromap[]
| ename:VK_OBJECT_TYPE_MICROMAP_EXT | slink:VkMicromapEXT
endif::VK_EXT_opacity_micromap[]
ifdef::VK_NV_optical_flow[]
| ename:VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV | slink:VkOpticalFlowSessionNV
endif::VK_NV_optical_flow[]
ifdef::VK_EXT_shader_object[]
| ename:VK_OBJECT_TYPE_SHADER_EXT | slink:VkShaderEXT
endif::VK_EXT_shader_object[]
|====
--

If this Specification was generated with any such extensions included, they
will be described in the remainder of this chapter.

ifdef::VK_EXT_debug_utils[]
include::{chapters}/VK_EXT_debug_utils.adoc[]
endif::VK_EXT_debug_utils[]

ifdef::VK_EXT_debug_marker[]
include::{chapters}/VK_EXT_debug_marker.adoc[]
endif::VK_EXT_debug_marker[]

ifdef::VK_EXT_debug_report[]
include::{chapters}/VK_EXT_debug_report.adoc[]
endif::VK_EXT_debug_report[]

ifdef::VK_NV_device_diagnostic_checkpoints,VK_EXT_device_fault[]
== Device Loss Debugging
endif::VK_NV_device_diagnostic_checkpoints,VK_EXT_device_fault[]

ifdef::VK_NV_device_diagnostic_checkpoints[]
include::{chapters}/VK_NV_device_diagnostic_checkpoints/device_diagnostic_checkpoints.adoc[]
endif::VK_NV_device_diagnostic_checkpoints[]

ifdef::VKSC_VERSION_1_0[]
include::{chapters}/fault_handling.adoc[]
endif::VKSC_VERSION_1_0[]

ifdef::VK_EXT_device_fault[]
=== Device Fault Diagnosis

[open,refpage='vkGetDeviceFaultInfoEXT',desc='Reports diagnostic fault information on the specified logical device',type='protos']
--
To retrieve diagnostic information about faults that may: have caused device
loss, call:

include::{generated}/api/protos/vkGetDeviceFaultInfoEXT.adoc[]

  * pname:device is the logical device from which to query the diagnostic
    fault information.
  * pname:pFaultCounts is a pointer to a slink:VkDeviceFaultCountsEXT
    structure in which counts for structures describing additional fault
    information are returned.
  * pname:pFaultInfo is `NULL` or a pointer to a slink:VkDeviceFaultInfoEXT
    structure in which fault information is returned.

If pname:pFaultInfo is `NULL`, then the counts of corresponding additional
fault information structures available are returned in the
pname:addressInfoCount and pname:vendorInfoCount members of
pname:pFaultCounts.
Additionally, the size of any vendor-specific binary crash dump is returned
in the pname:vendorBinarySize member of pname:pFaultCounts.

If pname:pFaultInfo is not `NULL`, pname:pFaultCounts must: point to a
slink:VkDeviceFaultCountsEXT structure with each structure count or size
member (pname:addressInfoCount, pname:vendorInfoCount,
pname:vendorBinarySize) set by the user to the number of elements in the
corresponding output array member of pname:pFaultInfo (pname:pAddressInfos
and pname:pVendorInfos), or to the size of the output buffer in bytes
(pname:pVendorBinaryData).
On return, each structure count member is overwritten with the number of
structures actually written to the corresponding output array member of
pname:pFaultInfo.
Similarly, pname:vendorBinarySize is overwritten with the number of bytes
actually written to the pname:pVendorBinaryData member of pname:pFaultInfo.

If the <<features-deviceFaultVendorBinary, vendor-specific crash dumps>>
feature is not enabled, then implementations must: set
pname:pFaultCounts\->vendorBinarySize to zero and must: not modify
pname:pFaultInfo\->pVendorBinaryData.

If any pname:pFaultCounts structure count member is less than the number of
corresponding fault properties available, at most structure count
(pname:addressInfoCount, pname:vendorInfoCount) elements will be written to
the associated pname:pFaultInfo output array.
Similarly, if pname:vendorBinarySize is less than the size in bytes of the
available crash dump data, at most pname:vendorBinarySize elements will be
written to pname:pVendorBinaryData.

If pname:pFaultInfo is `NULL`, then subsequent calls to
flink:vkGetDeviceFaultInfoEXT for the same pname:device must: return
identical values in the pname:addressInfoCount, pname:vendorInfoCount and
pname:vendorBinarySize members of pname:pFaultCounts.

If pname:pFaultInfo is not `NULL`, then subsequent calls to
flink:vkGetDeviceFaultInfoEXT for the same pname:device must: return
identical values in the output members of pname:pFaultInfo
(pname:pAddressInfos, pname:pVendorInfos, pname:pVendorBinaryData), up to
the limits described by the structure count and buffer size members of
pname:pFaultCounts (pname:addressInfoCount, pname:vendorInfoCount,
pname:vendorBinarySize).
If the sizes of the output members of pname:pFaultInfo increase for a
subsequent call to flink:vkGetDeviceFaultInfoEXT, then supplementary
information may: be returned in the additional available space.

If any pname:pFaultCounts structure count member is smaller than the number
of corresponding fault properties available, or if
pname:pFaultCounts\->vendorBinarySize is smaller than the size in bytes of
the generated binary crash dump data, ename:VK_INCOMPLETE will be returned
instead of ename:VK_SUCCESS, to indicate that not all the available
properties were returned.

If pname:pFaultCounts\->vendorBinarySize is less than what is necessary to
store the <<vendor-binary-crash-dumps, binary crash dump header>>, nothing
will be written to pname:pFaultInfo\->pVendorBinaryData and zero will be
written to pname:pFaultCounts\->vendorBinarySize.

.Valid Usage
****
  * [[VUID-vkGetDeviceFaultInfoEXT-device-07336]]
    pname:device must: be in the _lost_ state
  * [[VUID-vkGetDeviceFaultInfoEXT-pFaultCounts-07337]]
    If the value referenced by pname:pFaultCounts->addressInfoCount is not
    `0`, and pname:pFaultInfo->pAddressInfos is not `NULL`,
    pname:pFaultInfo->pAddressInfos must: be a valid pointer to an array of
    pname:pFaultCounts->addressInfoCount slink:VkDeviceFaultAddressInfoEXT
    structures
  * [[VUID-vkGetDeviceFaultInfoEXT-pFaultCounts-07338]]
    If the value referenced by pname:pFaultCounts->vendorInfoCount is not
    `0`, and pname:pFaultInfo->pVendorInfos is not `NULL`,
    pname:pFaultInfo->pVendorInfos must: be a valid pointer to an array of
    pname:pFaultCounts->vendorInfoCount slink:VkDeviceFaultVendorInfoEXT
    structures
  * [[VUID-vkGetDeviceFaultInfoEXT-pFaultCounts-07339]]
    If the value referenced by pname:pFaultCounts->vendorBinarySize is not
    `0`, and pname:pFaultInfo->pVendorBinaryData is not `NULL`,
    pname:pFaultInfo->pVendorBinaryData must: be a valid pointer to an array
    of pname:pFaultCounts->vendorBinarySize bytes
****

include::{generated}/validity/protos/vkGetDeviceFaultInfoEXT.adoc[]
--

[open,refpage='VkDeviceFaultCountsEXT',desc='Structure specifying device fault information',type='structs']
--
The sname:VkDeviceFaultCountsEXT structure is defined as:

include::{generated}/api/structs/VkDeviceFaultCountsEXT.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:addressInfoCount is the number of
    slink:VkDeviceFaultAddressInfoEXT structures describing either memory
    accesses which may: have caused a page fault, or the addresses of active
    instructions at the time of the fault.
  * pname:vendorInfoCount is the number of slink:VkDeviceFaultVendorInfoEXT
    structures describing vendor-specific fault information.
  * pname:vendorBinarySize is the size in bytes of a vendor-specific binary
    crash dump, which may provide additional information when imported into
    external tools.

include::{generated}/validity/structs/VkDeviceFaultCountsEXT.adoc[]
--

[open,refpage='VkDeviceFaultInfoEXT',desc='Structure specifying device fault information',type='structs']
--
The sname:VkDeviceFaultInfoEXT structure is defined as:

include::{generated}/api/structs/VkDeviceFaultInfoEXT.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:description is an array of ename:VK_MAX_DESCRIPTION_SIZE code:char
    containing a null-terminated UTF-8 string which is a human readable
    description of the fault.
  * pname:pAddressInfos is `NULL` or a pointer to an array of
    slink:VkDeviceFaultAddressInfoEXT structures describing either memory
    accesses which may: have caused a page fault, or describing active
    instruction pointers at the time of the fault.
    If not `NULL`, each element of pname:pAddressInfos describes the a
    bounded region of GPU virtual address space containing either the GPU
    virtual address accessed, or the value of an active instruction pointer.
  * pname:pVendorInfos is `NULL` or a pointer to an array of
    slink:VkDeviceFaultVendorInfoEXT structures describing vendor-specific
    fault information.
  * pname:pVendorBinaryData is `NULL` or a pointer to pname:vendorBinarySize
    number of bytes of data, which will be populated with a vendor-specific
    binary crash dump, as described in <<vendor-binary-crash-dumps, Vendor
    Binary Crash Dumps>>.

An implementation should: populate as many members of
slink:VkDeviceFaultInfoEXT as possible, given the information available at
the time of the fault and the constraints of the implementation itself.

Due to hardware limitations, pname:pAddressInfos describes ranges of GPU
virtual address space, rather than precise addresses.
The precise memory address accessed or the precise value of the instruction
pointer must: lie within the region described.

ifdef::VK_EXT_device_address_binding_report[]
[NOTE]
.Note
====
Each element of pname:pAddressInfos describes either:

  * A memory access which may have triggered a page fault and may have
    contributed to device loss
  * The value of an active instruction pointer at the time a fault occurred.
    This value may be indicative of the active pipeline or shader at the
    time of device loss

Comparison of the GPU virtual addresses described by pname:pAddressInfos to
GPU virtual address ranges reported by the
`apiext:VK_EXT_device_address_binding_report` extension may allow
applications to correlate between these addresses and Vulkan objects.
Applications should be aware that these addresses may also correspond to
resources internal to an implementation, which will not be reported via the
`apiext:VK_EXT_device_address_binding_report` extension.
====
endif::VK_EXT_device_address_binding_report[]

include::{generated}/validity/structs/VkDeviceFaultInfoEXT.adoc[]
--

[open,refpage='VkDeviceFaultAddressInfoEXT',desc='Structure specifying GPU virtual address information',type='structs']
--
The sname:VkDeviceFaultAddressInfoEXT structure is defined as:

include::{generated}/api/structs/VkDeviceFaultAddressInfoEXT.adoc[]

  * pname:addressType is either the type of memory operation that triggered
    a page fault, or the type of association between an instruction pointer
    and a fault.
  * pname:reportedAddress is the GPU virtual address recorded by the device.
  * pname:addressPrecision is a power of two value that specifies how
    precisely the device can report the address.

The combination of pname:reportedAddress and pname:addressPrecision allow
the possible range of addresses to be calculated, such that:

[source,c++]
----
lower_address = (pInfo->reportedAddress & ~(pInfo->addressPrecision-1))
upper_address = (pInfo->reportedAddress |  (pInfo->addressPrecision-1))
----

[NOTE]
.Note
====
It is valid for the pname:reportedAddress to contain a more precise address
than indicated by pname:addressPrecision.
In this case, the value of pname:reportedAddress should be treated as an
additional hint as to the value of the address that triggered the page
fault, or to the value of an instruction pointer.
====

include::{generated}/validity/structs/VkDeviceFaultAddressInfoEXT.adoc[]
--

[open,refpage='VkDeviceFaultAddressTypeEXT',desc='Page fault access types',type='enums']
--
Possible values of slink:VkDeviceFaultAddressInfoEXT::pname:addressType are:

include::{generated}/api/enums/VkDeviceFaultAddressTypeEXT.adoc[]

  * ename:VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT specifies that
    slink:VkDeviceFaultAddressInfoEXT does not describe a page fault, or an
    instruction address.
  * ename:VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT specifies that
    slink:VkDeviceFaultAddressInfoEXT describes a page fault triggered by an
    invalid read operation.
  * ename:VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT specifies that
    slink:VkDeviceFaultAddressInfoEXT describes a page fault triggered by an
    invalid write operation.
  * ename:VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT describes a page
    fault triggered by an attempt to execute non-executable memory.
  * ename:VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT
    specifies an instruction pointer value at the time the fault occurred.
    This may or may not be related to a fault.
  * ename:VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT
    specifies an instruction pointer value associated with an invalid
    instruction fault.
  * ename:VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT
    specifies an instruction pointer value associated with a fault.

[NOTE]
.Note
====
The instruction pointer values recorded may not identify the specific
instruction(s) that triggered the fault.
The relationship between the instruction pointer reported and triggering
instruction will be vendor-specific.
====
--

[open,refpage='VkDeviceFaultVendorInfoEXT',desc='Structure specifying vendor-specific fault information',type='structs']
--
The sname:VkDeviceFaultVendorInfoEXT structure is defined as:

include::{generated}/api/structs/VkDeviceFaultVendorInfoEXT.adoc[]

  * pname:description is an array of ename:VK_MAX_DESCRIPTION_SIZE code:char
    containing a null-terminated UTF-8 string which is a human readable
    description of the fault.
  * pname:vendorFaultCode is the vendor-specific fault code for this fault.
  * pname:vendorFaultData is the vendor-specific fault data associated with
    this fault.

include::{generated}/validity/structs/VkDeviceFaultVendorInfoEXT.adoc[]
--


[[vendor-binary-crash-dumps]]
==== Vendor Binary Crash Dumps

Applications can: store the vendor-specific binary crash dump data retrieved
by calling flink:vkGetDeviceFaultInfoEXT for later analysis using external
tools.

However, the format of this data may: depend on the vendor ID, device ID,
driver version, and other details of the device.
To enable external applications to identify the original device from which a
crash dump was generated, the initial bytes written to
sname:VkDeviceFaultInfoEXT::pname:pVendorBinaryData must: begin with a valid
crash dump header.

[open,refpage='VkDeviceFaultVendorBinaryHeaderVersionOneEXT',desc='Structure describing the layout of the vendor binary crash dump header',type='structs']
--
Version one of the crash dump header is defined as:

include::{generated}/api/structs/VkDeviceFaultVendorBinaryHeaderVersionOneEXT.adoc[]

  * pname:headerSize is the length in bytes of the crash dump header.
  * pname:headerVersion is a elink:VkDeviceFaultVendorBinaryHeaderVersionEXT
    enum value specifying the version of the header.
    A consumer of the crash dump should: use the header version to interpret
    the remainder of the header.
  * pname:vendorID is the sname:VkPhysicalDeviceProperties::pname:vendorID
    of the implementation.
  * pname:deviceID is the sname:VkPhysicalDeviceProperties::pname:deviceID
    of the implementation.
  * pname:driverVersion is the
    sname:VkPhysicalDeviceProperties::pname:driverVersion of the
    implementation.
  * pname:pipelineCacheUUID is an array of ename:VK_UUID_SIZE code:uint8_t
    values matching the
    sname:VkPhysicalDeviceProperties::pname:pipelineCacheUUID property of
    the implementation.
  * pname:applicationNameOffset is zero, or an offset from the base address
    of the crash dump header to a null-terminated UTF-8 string containing
    the name of the application.
    If pname:applicationNameOffset is non-zero, this string must: match the
    application name specified via
    slink:VkApplicationInfo::pname:pApplicationName during instance
    creation.
  * pname:applicationVersion must: be zero or the value specified by
    slink:VkApplicationInfo::pname:applicationVersion during instance
    creation.
  * pname:engineNameOffset is zero, or an offset from the base address of
    the crash dump header to a null-terminated UTF-8 string containing the
    name of the engine (if any) used to create the application.
    If pname:engineNameOffset is non-zero, this string must: match the
    engine name specified via slink:VkApplicationInfo::pname:pEngineName
    during instance creation.
  * pname:engineVersion must: be zero or the value specified by
    slink:VkApplicationInfo::pname:engineVersion during instance creation.
  * pname:apiVersion must: be zero or the value specified by
    slink:VkApplicationInfo::pname:apiVersion during instance creation.

Unlike most structures declared by the Vulkan API, all fields of this
structure are written with the least significant byte first, regardless of
host byte-order.

The C language specification does not define the packing of structure
members.
This layout assumes tight structure member packing, with members laid out in
the order listed in the structure, and the intended size of the structure is
56 bytes.
If a compiler produces code that diverges from that pattern, applications
must: employ another method to set values at the correct offsets.

.Valid Usage
****
  * [[VUID-VkDeviceFaultVendorBinaryHeaderVersionOneEXT-headerSize-07340]]
    pname:headerSize must: be 56
  * [[VUID-VkDeviceFaultVendorBinaryHeaderVersionOneEXT-headerVersion-07341]]
    pname:headerVersion must: be
    ename:VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT
****

include::{generated}/validity/structs/VkDeviceFaultVendorBinaryHeaderVersionOneEXT.adoc[]
--

[open,refpage='VkDeviceFaultVendorBinaryHeaderVersionEXT',desc='Encode vendor binary crash dump version',type='enums',xrefs='vkGetDeviceFaultInfoEXT']
--
Possible values of the pname:headerVersion value of the crash dump header
are:

include::{generated}/api/enums/VkDeviceFaultVendorBinaryHeaderVersionEXT.adoc[]

  * ename:VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT specifies
    version one of the binary crash dump header.
--
endif::VK_EXT_device_fault[]


ifdef::VK_VERSION_1_3,VK_EXT_tooling_info[]
[[debugging-tooling-info]]
== Active Tooling Information

[open,refpage='vkGetPhysicalDeviceToolProperties',desc='Reports properties of tools active on the specified physical device',type='protos',alias='vkGetPhysicalDeviceToolPropertiesEXT']
--
Information about tools providing debugging, profiling, or similar services,
active for a given physical device, can be obtained by calling:

ifdef::VK_VERSION_1_3[]
include::{generated}/api/protos/vkGetPhysicalDeviceToolProperties.adoc[]
endif::VK_VERSION_1_3[]

ifdef::VK_VERSION_1_3+VK_EXT_tooling_info[or the equivalent command]

ifdef::VK_EXT_tooling_info[]
include::{generated}/api/protos/vkGetPhysicalDeviceToolPropertiesEXT.adoc[]
endif::VK_EXT_tooling_info[]

  * pname:physicalDevice is the handle to the physical device to query for
    active tools.
  * pname:pToolCount is a pointer to an integer describing the number of
    tools active on pname:physicalDevice.
  * pname:pToolProperties is either `NULL` or a pointer to an array of
    slink:VkPhysicalDeviceToolProperties structures.

If pname:pToolProperties is `NULL`, then the number of tools currently
active on pname:physicalDevice is returned in pname:pToolCount.
Otherwise, pname:pToolCount must: point to a variable set by the user to the
number of elements in the pname:pToolProperties array, and on return the
variable is overwritten with the number of structures actually written to
pname:pToolProperties.
If pname:pToolCount is less than the number of currently active tools, at
most pname:pToolCount structures will be written.

The count and properties of active tools may: change in response to events
outside the scope of the specification.
An application should: assume these properties might change at any given
time.

include::{generated}/validity/protos/vkGetPhysicalDeviceToolProperties.adoc[]
--

[open,refpage='VkPhysicalDeviceToolProperties',desc='Structure providing information about an active tool',type='structs',alias='VkPhysicalDeviceToolPropertiesEXT']
--
The slink:VkPhysicalDeviceToolProperties structure is defined as:

include::{generated}/api/structs/VkPhysicalDeviceToolProperties.adoc[]

ifdef::VK_EXT_tooling_info[]
or the equivalent

include::{generated}/api/structs/VkPhysicalDeviceToolPropertiesEXT.adoc[]
endif::VK_EXT_tooling_info[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:name is a null-terminated UTF-8 string containing the name of the
    tool.
  * pname:version is a null-terminated UTF-8 string containing the version
    of the tool.
  * pname:purposes is a bitmask of elink:VkToolPurposeFlagBits which is
    populated with purposes supported by the tool.
  * pname:description is a null-terminated UTF-8 string containing a
    description of the tool.
  * pname:layer is a null-terminated UTF-8 string containing the name of the
    layer implementing the tool, if the tool is implemented in a layer -
    otherwise it may: be an empty string.

include::{generated}/validity/structs/VkPhysicalDeviceToolProperties.adoc[]
--

[open,refpage='VkToolPurposeFlagBits',desc='Bitmask specifying the purposes of an active tool',type='enums',alias='VkToolPurposeFlagBitsEXT']
--
Bits which can: be set in
slink:VkPhysicalDeviceToolProperties::pname:purposes, specifying the
purposes of an active tool, are:

include::{generated}/api/enums/VkToolPurposeFlagBits.adoc[]

ifdef::VK_EXT_tooling_info[]
or the equivalent

include::{generated}/api/enums/VkToolPurposeFlagBitsEXT.adoc[]
endif::VK_EXT_tooling_info[]

  * ename:VK_TOOL_PURPOSE_VALIDATION_BIT specifies that the tool provides
    validation of API usage.
  * ename:VK_TOOL_PURPOSE_PROFILING_BIT specifies that the tool provides
    profiling of API usage.
  * ename:VK_TOOL_PURPOSE_TRACING_BIT specifies that the tool is capturing
    data about the application's API usage, including anything from simple
    logging to capturing data for later replay.
  * ename:VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT specifies that the tool
    provides additional API features/extensions on top of the underlying
    implementation.
  * ename:VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT specifies that the tool
    modifies the API features/limits/extensions presented to the
    application.
ifdef::VK_EXT_debug_report,VK_EXT_debug_utils[]
  * ename:VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT specifies that the tool
    reports additional information to the application via callbacks
    specified by
ifdef::VK_EXT_debug_report[]
    flink:vkCreateDebugReportCallbackEXT
endif::VK_EXT_debug_report[]
ifdef::VK_EXT_debug_report+VK_EXT_debug_utils[]
    or
endif::VK_EXT_debug_report+VK_EXT_debug_utils[]
ifdef::VK_EXT_debug_utils[]
    flink:vkCreateDebugUtilsMessengerEXT
endif::VK_EXT_debug_utils[]
endif::VK_EXT_debug_report,VK_EXT_debug_utils[]
ifdef::VK_EXT_debug_marker,VK_EXT_debug_utils[]
  * ename:VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT specifies that the tool
    consumes
ifdef::VK_EXT_debug_marker[]
    <<debugging-debug-markers,debug markers>>
endif::VK_EXT_debug_marker[]
ifdef::VK_EXT_debug_marker+VK_EXT_debug_utils[]
    or
endif::VK_EXT_debug_marker+VK_EXT_debug_utils[]
ifdef::VK_EXT_debug_utils[]
    <<debugging-object-debug-annotation,object debug annotation>>,
    <<debugging-queue-labels, queue labels>>, or
    <<debugging-command-buffer-labels, command buffer labels>>
endif::VK_EXT_debug_utils[]
endif::VK_EXT_debug_marker,VK_EXT_debug_utils[]
--

[open,refpage='VkToolPurposeFlags',desc='Bitmask of VkToolPurposeFlagBits',type='flags',alias='VkToolPurposeFlagsEXT']
--
include::{generated}/api/flags/VkToolPurposeFlags.adoc[]

ifdef::VK_EXT_tooling_info[]
or the equivalent

include::{generated}/api/flags/VkToolPurposeFlagsEXT.adoc[]
endif::VK_EXT_tooling_info[]

tlink:VkToolPurposeFlags is a bitmask type for setting a mask of zero or
more elink:VkToolPurposeFlagBits.
--
endif::VK_VERSION_1_3,VK_EXT_tooling_info[]


ifdef::VK_EXT_frame_boundary[]
== Frame Boundary

[open,refpage='VkFrameBoundaryEXT',desc='Add frame boundary information to queue submissions',type='structs']
--
The sname:VkFrameBoundaryEXT structure is defined as:

include::{generated}/api/structs/VkFrameBoundaryEXT.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:flags is a bitmask of elink:VkFrameBoundaryFlagBitsEXT that can
    flag the last submission of a frame identifier.
  * pname:frameID is the frame identifier.
  * pname:imageCount is the number of images that store frame results.
  * pname:pImages is a pointer to an array of VkImage objects with
    imageCount entries.
  * pname:bufferCount is the number of buffers the store the frame results.
  * pname:pBuffers is a pointer to an array of VkBuffer objects with
    bufferCount entries.
  * pname:tagName is a numerical identifier for tag data.
  * pname:tagSize is the number of bytes of tag data.
  * pname:pTag is a pointer to an array of pname:tagSize bytes containing
    tag data.

The application can: associate frame boundary information to a queue
submission call by adding a sname:VkFrameBoundaryEXT structure to the
pname:pNext chain of <<devsandqueues-submission,queue submission>>,
ifdef::VK_KHR_swapchain[slink:VkPresentInfoKHR,]
or slink:VkBindSparseInfo.

The frame identifier is used to associate one or more queue submission to a
frame, it is thus meant to be unique within a frame lifetime, i.e. it is
possible (but not recommended) to reuse frame identifiers, as long as any
two frames with any chance of having overlapping queue submissions (as in
the example above) use two different frame identifiers.

[NOTE]
.Note
====
Since the concept of frame is application-dependent, there is no way to
validate the use of frame identifier.
It is good practice to use a monotonically increasing counter as the frame
identifier and not reuse identifiers between frames.
====

The pname:pImages and pname:pBuffers arrays contain a list of images and
buffers which store the "end result" of the frame.
As the concept of frame is application-dependent, not all frames may:
produce their results in images or buffers, yet this is a sufficiently
common case to be handled by sname:VkFrameBoundaryEXT.
Note that no extra information, such as image layout is being provided,
since the images are meant to be used by tools which would already be
tracking this required information.
ifdef::VK_KHR_swapchain[]
Having the possibility of passing a list of end-result images makes
sname:VkFrameBoundaryEXT as expressive as flink:vkQueuePresentKHR, which is
often the default frame boundary delimiter.
endif::VK_KHR_swapchain[]

The application can: also associate arbitrary extra information via tag data
using pname:tagName, pname:tagSize and pname:pTag.
This extra information is typically tool-specific.

include::{generated}/validity/structs/VkFrameBoundaryEXT.adoc[]
--

[open,refpage='VkFrameBoundaryFlagBitsEXT',desc='Bitmask specifying whether a queue submission is the last one for a given frame',type='enums']
--
The bit which can: be set in slink:VkFrameBoundaryEXT::pname:flags is:

include::{generated}/api/enums/VkFrameBoundaryFlagBitsEXT.adoc[]

  * ename:VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT specifies that this queue
    submission is the last one for this frame, i.e. once this queue
    submission has terminated, then the work for this frame is completed.
--

ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
Note that in the presence of timeline semaphores, the last queue submission
might not be the last one to be submitted, as timeline semaphores allow for
wait-before-signal submissions.
In the context of frame boundary, the queue submission that should be done
flagged as the last one is the one that is meant to be executed last, even
if it may: not be the last one to be submitted.
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]

[open,refpage='VkFrameBoundaryFlagsEXT',desc='Bitmask of VkFrameBoundaryFlagBitsEXT',type='flags']
--
include::{generated}/api/flags/VkFrameBoundaryFlagsEXT.adoc[]

tlink:VkFrameBoundaryFlagsEXT is a bitmask type for setting a mask of zero
or more elink:VkFrameBoundaryFlagBitsEXT.
--

endif::VK_EXT_frame_boundary[]
