| // Copyright 2015-2023 The Khronos Group Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[fundamentals]] |
| = Fundamentals |
| |
| This chapter introduces fundamental concepts including the Vulkan |
| architecture and execution model, API syntax, queues, pipeline |
| configurations, numeric representation, state and state queries, and the |
| different types of objects and shaders. |
| It provides a framework for interpreting more specific descriptions of |
| commands and behavior in the remainder of the Specification. |
| |
| |
| [[fundamentals-host-environment]] |
| == Host and Device Environment |
| |
| The Vulkan Specification assumes and requires: the following properties of |
| the host environment with respect to Vulkan implementations: |
| |
| * The host must: have runtime support for 8, 16, 32 and 64-bit signed and |
| unsigned twos-complement integers, all addressable at the granularity of |
| their size in bytes. |
| * The host must: have runtime support for 32- and 64-bit floating-point |
| types satisfying the range and precision constraints in the |
| <<fundamentals-floatingpoint,Floating Point Computation>> section. |
| * The representation and endianness of these types on the host must: match |
| the representation and endianness of the same types on every physical |
| device supported. |
| |
| [NOTE] |
| .Note |
| ==== |
| Since a variety of data types and structures in Vulkan may: be accessible by |
| both host and physical device operations, the implementation should: be able |
| to access such data efficiently in both paths in order to facilitate writing |
| portable and performant applications. |
| ==== |
| |
| |
| [[fundamentals-execmodel]] |
| == Execution Model |
| |
| This section outlines the execution model of a Vulkan system. |
| |
| Vulkan exposes one or more _devices_, each of which exposes one or more |
| _queues_ which may: process work asynchronously to one another. |
| The set of queues supported by a device is partitioned into _families_. |
| Each family supports one or more types of functionality and may: contain |
| multiple queues with similar characteristics. |
| Queues within a single family are considered _compatible_ with one another, |
| and work produced for a family of queues can: be executed on any queue |
| within that family. |
| This specification defines the following types of functionality that queues |
| may: support: graphics, compute, |
| ifdef::VK_KHR_video_decode_queue[] |
| video decode, |
| endif::VK_KHR_video_decode_queue[] |
| ifdef::VK_KHR_video_encode_queue[] |
| video encode, |
| endif::VK_KHR_video_encode_queue[] |
| ifdef::VK_VERSION_1_1[protected memory management,] |
| ifndef::VKSC_VERSION_1_0[sparse memory management,] |
| and transfer. |
| |
| [NOTE] |
| .Note |
| ==== |
| A single device may: report multiple similar queue families rather than, or |
| as well as, reporting multiple members of one or more of those families. |
| This indicates that while members of those families have similar |
| capabilities, they are _not_ directly compatible with one another. |
| ==== |
| |
| Device memory is explicitly managed by the application. |
| Each device may: advertise one or more heaps, representing different areas |
| of memory. |
| Memory heaps are either device-local or host-local, but are always visible |
| to the device. |
| Further detail about memory heaps is exposed via memory types available on |
| that heap. |
| Examples of memory areas that may: be available on an implementation |
| include: |
| |
| * _device-local_ is memory that is physically connected to the device. |
| * _device-local, host visible_ is device-local memory that is visible to |
| the host. |
| * _host-local, host visible_ is memory that is local to the host and |
| visible to the device and host. |
| |
| On other architectures, there may: only be a single heap that can: be used |
| for any purpose. |
| |
| |
| [[fundamentals-queueoperation]] |
| === Queue Operation |
| |
| Vulkan queues provide an interface to the execution engines of a device. |
| Commands for these execution engines are recorded into command buffers ahead |
| of execution time, and then submitted to a queue for execution. |
| Once submitted to a queue, command buffers will begin and complete execution |
| without further application intervention, though the order of this execution |
| is dependent on a number of <<synchronization, implicit and explicit |
| ordering constraints>>. |
| |
| Work is submitted to queues using _queue submission commands_ that typically |
| take the form ftext:vkQueue* (e.g. flink:vkQueueSubmit |
| ifndef::VKSC_VERSION_1_0[, flink:vkQueueBindSparse] |
| ), and can: take a list of semaphores upon which to wait before work begins |
| and a list of semaphores to signal once work has completed. |
| The work itself, as well as signaling and waiting on the semaphores are all |
| _queue operations_. |
| Queue submission commands return control to the application once queue |
| operations have been submitted - they do not wait for completion. |
| |
| There are no implicit ordering constraints between queue operations on |
| different queues, or between queues and the host, so these may: operate in |
| any order with respect to each other. |
| Explicit ordering constraints between different queues or with the host can: |
| be expressed with <<synchronization-semaphores,semaphores>> and |
| <<synchronization-fences,fences>>. |
| |
| Command buffer submissions to a single queue respect |
| <<synchronization-submission-order, submission order>> and other |
| <<synchronization-implicit, implicit ordering guarantees>>, but otherwise |
| may: overlap or execute out of order. |
| Other types of batches and queue submissions against a single queue |
| ifndef::VKSC_VERSION_1_0[(e.g. <<sparsemem-memory-binding, sparse memory binding>>)] |
| have no implicit ordering constraints with any other queue submission or |
| batch. |
| Additional explicit ordering constraints between queue submissions and |
| individual batches can be expressed with |
| <<synchronization-semaphores,semaphores>> and |
| <<synchronization-fences,fences>>. |
| |
| Before a fence or semaphore is signaled, it is guaranteed that any |
| previously submitted queue operations have completed execution, and that |
| memory writes from those queue operations are |
| <<synchronization-dependencies-available-and-visible,available>> to future |
| queue operations. |
| Waiting on a signaled semaphore or fence guarantees that previous writes |
| that are available are also |
| <<synchronization-dependencies-available-and-visible,visible>> to subsequent |
| commands. |
| |
| Command buffer boundaries, both between primary command buffers of the same |
| or different batches or submissions as well as between primary and secondary |
| command buffers, do not introduce any additional ordering constraints. |
| In other words, submitting the set of command buffers (which can: include |
| executing secondary command buffers) between any semaphore or fence |
| operations execute the recorded commands as if they had all been recorded |
| into a single primary command buffer, except that the current state is |
| <<commandbuffers-statereset,reset>> on each boundary. |
| Explicit ordering constraints can: be expressed with <<synchronization, |
| explicit synchronization primitives>>. |
| |
| There are a few <<synchronization-implicit, implicit ordering guarantees>> |
| between commands within a command buffer, but only covering a subset of |
| execution. |
| Additional explicit ordering constraints can be expressed with the various |
| <<synchronization, explicit synchronization primitives>>. |
| |
| [NOTE] |
| .Note |
| ==== |
| Implementations have significant freedom to overlap execution of work |
| submitted to a queue, and this is common due to deep pipelining and |
| parallelism in Vulkan devices. |
| ==== |
| |
| [[fundamentals-queueoperation-command-types]] |
| Commands recorded in command buffers can perform actions, set state that |
| persists across commands, synchronize other commands, or indirectly launch |
| other commands, with some commands fulfilling several of these roles. |
| The "`Command Properties`" section for each such command lists which of |
| these roles the command takes. |
| State setting commands update the _current state_ of the command buffer. |
| Some commands that perform actions (e.g. draw/dispatch) do so based on the |
| current state set cumulatively since the start of the command buffer. |
| The work involved in performing action commands is often allowed to overlap |
| or to be reordered, but doing so must: not alter the state to be used by |
| each action command. |
| In general, action commands are those commands that alter framebuffer |
| attachments, read/write buffer or image memory, or write to query pools. |
| |
| Synchronization commands introduce explicit |
| <<synchronization-dependencies,execution and memory dependencies>> between |
| two sets of action commands, where the second set of commands depends on the |
| first set of commands. |
| These dependencies enforce both that the execution of certain |
| <<synchronization-pipeline-stages, pipeline stages>> in the later set occurs |
| after the execution of certain stages in the source set, and that the |
| effects of <<synchronization-global-memory-barriers,memory accesses>> |
| performed by certain pipeline stages occur in order and are visible to each |
| other. |
| When not enforced by an explicit dependency or <<synchronization-implicit, |
| implicit ordering guarantees>>, action commands may: overlap execution or |
| execute out of order, and may: not see the side effects of each other's |
| memory accesses. |
| |
| |
| [[fundamentals-objectmodel-overview]] |
| == Object Model |
| |
| The devices, queues, and other entities in Vulkan are represented by Vulkan |
| objects. |
| At the API level, all objects are referred to by handles. |
| There are two classes of handles, dispatchable and non-dispatchable. |
| _Dispatchable_ handle types are a pointer to an opaque type. |
| This pointer may: be used by layers as part of intercepting API commands, |
| and thus each API command takes a dispatchable type as its first parameter. |
| Each object of a dispatchable type must: have a unique handle value during |
| its lifetime. |
| |
| _Non-dispatchable_ handle types are a 64-bit integer type whose meaning is |
| implementation-dependent. |
| ifdef::VK_VERSION_1_3,VK_EXT_private_data[] |
| If the <<features-privateData, pname:privateData>> feature is enabled for a |
| slink:VkDevice, each object of a non-dispatchable type created on that |
| device must: have a handle value that is unique among objects created on |
| that device, for the duration of the object's lifetime. |
| Otherwise, non-dispatchable |
| endif::VK_VERSION_1_3,VK_EXT_private_data[] |
| ifndef::VK_VERSION_1_3,VK_EXT_private_data[Non-dispatchable] |
| handles may: encode object information directly in the handle rather than |
| acting as a reference to an underlying object, and thus may: not have unique |
| handle values. |
| If handle values are not unique, then destroying one such handle must: not |
| cause identical handles of other types to become invalid, and must: not |
| cause identical handles of the same type to become invalid if that handle |
| value has been created more times than it has been destroyed. |
| |
| All objects created or allocated from a sname:VkDevice (i.e. with a |
| sname:VkDevice as the first parameter) are private to that device, and must: |
| not be used on other devices. |
| |
| |
| [[fundamentals-objectmodel-lifetime]] |
| === Object Lifetime |
| |
| Objects are created or allocated by ftext:vkCreate* and ftext:vkAllocate* |
| commands, respectively. |
| Once an object is created or allocated, its "`structure`" is considered to |
| be immutable, though the contents of certain object types is still free to |
| change. |
| Objects are destroyed or freed by ftext:vkDestroy* and ftext:vkFree* |
| commands, respectively. |
| |
| Objects that are allocated (rather than created) take resources from an |
| existing pool object or memory heap, and when freed return resources to that |
| pool or heap. |
| While object creation and destruction are generally expected to be |
| low-frequency occurrences during runtime, allocating and freeing objects |
| can: occur at high frequency. |
| Pool objects help accommodate improved performance of the allocations and |
| frees. |
| |
| ifdef::VKSC_VERSION_1_0[] |
| In Vulkan SC, data structures for objects are reserved by the implementation |
| at device creation time in order to enable implementations to rely solely on |
| static memory management at run-time. |
| The slink:VkDeviceObjectReservationCreateInfo structure provides upper |
| bounds on the simultaneous number of objects of each type that can: be |
| allocated during the lifetime of the slink:VkDevice. |
| Most objects can be created and destroyed as needed, provided that no more |
| than the requested number are in existence at any point in time. |
| endif::VKSC_VERSION_1_0[] |
| |
| It is an application's responsibility to track the lifetime of Vulkan |
| objects, and not to destroy them while they are still in use. |
| |
| [[fundamentals-objectmodel-lifetime-acquire]] |
| The ownership of application-owned memory is immediately acquired by any |
| Vulkan command it is passed |
| ifndef::VKSC_VERSION_1_0[into.] |
| ifdef::VKSC_VERSION_1_0[into, unless otherwise noted below.] |
| Ownership of such memory must: be released back to the application at the |
| end of the duration of the command, |
| ifdef::VK_KHR_deferred_host_operations[] |
| unless that command was deferred, |
| endif::VK_KHR_deferred_host_operations[] |
| so that the application can: alter or free this memory as soon as all the |
| commands that acquired it have returned. |
| ifdef::VK_KHR_deferred_host_operations[] |
| If the command was <<deferred-host-operations-requesting, deferred>>, |
| ownership of such memory is released back to the application when the |
| deferred operation is complete. |
| endif::VK_KHR_deferred_host_operations[] |
| |
| The following object types are consumed when they are passed into a Vulkan |
| command and not further accessed by the objects they are used to create. |
| They must: not be destroyed in the duration of any API command they are |
| passed into: |
| |
| ifndef::VKSC_VERSION_1_0[] |
| * sname:VkShaderModule |
| endif::VKSC_VERSION_1_0[] |
| * sname:VkPipelineCache |
| ifdef::VK_EXT_validation_cache[] |
| * sname:VkValidationCacheEXT |
| endif::VK_EXT_validation_cache[] |
| |
| ifdef::VKSC_VERSION_1_0[] |
| A sname:VkPipelineCache object created with |
| ename:VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT requires the |
| application to maintain the memory contents pointed to by |
| sname:VkPipelineCacheCreateInfo::pname:pInitialData for the lifetime of the |
| pipeline cache object. |
| endif::VKSC_VERSION_1_0[] |
| |
| A sname:VkRenderPass |
| ifdef::VK_VERSION_1_3,VK_KHR_maintenance4[] |
| or sname:VkPipelineLayout |
| endif::VK_VERSION_1_3,VK_KHR_maintenance4[] |
| object passed as a parameter to create another object is not further |
| accessed by that object after the duration of the command it is passed into. |
| A sname:VkRenderPass used in a command buffer follows the rules described |
| below. |
| |
| ifndef::VK_VERSION_1_3,VK_KHR_maintenance4[] |
| A sname:VkPipelineLayout object must: not be destroyed while any command |
| buffer that uses it is in the recording state. |
| endif::VK_VERSION_1_3,VK_KHR_maintenance4[] |
| |
| sname:VkDescriptorSetLayout objects may: be accessed by commands that |
| operate on descriptor sets allocated using that layout, and those descriptor |
| sets must: not be updated with flink:vkUpdateDescriptorSets after the |
| descriptor set layout has been destroyed. |
| Otherwise, a sname:VkDescriptorSetLayout object passed as a parameter to |
| create another object is not further accessed by that object after the |
| duration of the command it is passed into. |
| |
| The application must: not destroy any other type of Vulkan object until all |
| uses of that object by the device (such as via command buffer execution) |
| have completed. |
| |
| [[fundamentals-objectmodel-lifetime-cmdbuffers]] |
| The following Vulkan objects must: not be destroyed while any command |
| buffers using the object are in the <<commandbuffers-lifecycle, pending |
| state>>: |
| |
| * sname:VkEvent |
| ifndef::VKSC_VERSION_1_0[] |
| * sname:VkQueryPool |
| endif::VKSC_VERSION_1_0[] |
| * sname:VkBuffer |
| * sname:VkBufferView |
| * sname:VkImage |
| * sname:VkImageView |
| * sname:VkPipeline |
| * sname:VkSampler |
| ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| * sname:VkSamplerYcbcrConversion |
| endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| ifndef::VKSC_VERSION_1_0[] |
| * sname:VkDescriptorPool |
| endif::VKSC_VERSION_1_0[] |
| * sname:VkFramebuffer |
| * sname:VkRenderPass |
| * sname:VkCommandBuffer |
| ifndef::VKSC_VERSION_1_0[] |
| * sname:VkCommandPool |
| * sname:VkDeviceMemory |
| endif::VKSC_VERSION_1_0[] |
| * sname:VkDescriptorSet |
| ifdef::VK_NV_device_generated_commands[] |
| * sname:VkIndirectCommandsLayoutNV |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_NV_ray_tracing[] |
| * sname:VkAccelerationStructureNV |
| endif::VK_NV_ray_tracing[] |
| ifdef::VK_KHR_acceleration_structure[] |
| * sname:VkAccelerationStructureKHR |
| endif::VK_KHR_acceleration_structure[] |
| ifdef::VK_KHR_video_queue[] |
| * sname:VkVideoSessionKHR |
| * sname:VkVideoSessionParametersKHR |
| endif::VK_KHR_video_queue[] |
| |
| Destroying these objects will move any command buffers that are in the |
| <<commandbuffers-lifecycle, recording or executable state>>, and are using |
| those objects, to the <<commandbuffers-lifecycle, invalid state>>. |
| |
| The following Vulkan objects must: not be destroyed while any queue is |
| executing commands that use the object: |
| |
| * sname:VkFence |
| * sname:VkSemaphore |
| * sname:VkCommandBuffer |
| ifndef::VKSC_VERSION_1_0[] |
| * sname:VkCommandPool |
| ifdef::VK_NV_external_sci_sync2[] |
| * sname:VkSemaphoreSciSyncPoolNV |
| endif::VK_NV_external_sci_sync2[] |
| endif::VKSC_VERSION_1_0[] |
| |
| In general, objects can: be destroyed or freed in any order, even if the |
| object being freed is involved in the use of another object (e.g. use of a |
| resource in a view, use of a view in a descriptor set, |
| ifdef::VK_KHR_pipeline_library[] |
| use of a <<pipelines-library,pipeline library>> in another pipeline, |
| endif::VK_KHR_pipeline_library[] |
| ifdef::VK_NV_device_generated_commands[] |
| use of a <<graphics-shadergroups,referenced pipeline>> for additional |
| graphics shader groups in another pipeline, |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_KHR_acceleration_structure[] |
| use of a <<acceleration-structure-bottom-level, bottom level acceleration |
| structure>> in an instance referenced by a |
| <<acceleration-structure-top-level, top level acceleration structure>>, |
| endif::VK_KHR_acceleration_structure[] |
| use of an object in a command buffer, binding of a memory allocation to a |
| resource), as long as any object that uses the freed object is not further |
| used in any way except to be destroyed or to be reset in such a way that it |
| no longer uses the other object (such as resetting a command buffer). |
| If the object has been reset, then it can: be used as if it never used the |
| freed object. |
| An exception to this is when there is a parent/child relationship between |
| objects. |
| In this case, the application must: not destroy a parent object before its |
| children, except when the parent is explicitly defined to free its children |
| when it is destroyed (e.g. for pool objects, as defined below). |
| |
| sname:VkCommandPool objects are parents of sname:VkCommandBuffer objects. |
| sname:VkDescriptorPool objects are parents of sname:VkDescriptorSet objects. |
| sname:VkDevice objects are parents of many object types (all that take a |
| sname:VkDevice as a parameter to their creation). |
| |
| The following Vulkan objects have specific restrictions for when they can: |
| be destroyed: |
| |
| * sname:VkQueue objects cannot: be explicitly destroyed. |
| Instead, they are implicitly destroyed when the sname:VkDevice object |
| they are retrieved from is destroyed. |
| ifndef::VKSC_VERSION_1_0[] |
| * Destroying a pool object implicitly frees all objects allocated from |
| that pool. |
| Specifically, destroying sname:VkCommandPool frees all |
| sname:VkCommandBuffer objects that were allocated from it, and |
| destroying sname:VkDescriptorPool frees all sname:VkDescriptorSet |
| objects that were allocated from it. |
| endif::VKSC_VERSION_1_0[] |
| ifdef::VKSC_VERSION_1_0[] |
| * [[fundamentals-objectmodel-no-destroy]] Device memory |
| (slink:VkDeviceMemory) allocations, |
| ifdef::VK_KHR_swapchain[swapchains (slink:VkSwapchainKHR),] |
| and pool objects (slink:VkCommandPool, slink:VkDescriptorPool, |
| ifdef::VK_NV_external_sci_sync2[slink:VkSemaphoreSciSyncPoolNV,] |
| slink:VkQueryPool) cannot: be explicitly freed or destroyed. |
| Instead, they are implicitly freed or destroyed when the sname:VkDevice |
| object they are created from is destroyed. |
| endif::VKSC_VERSION_1_0[] |
| * sname:VkDevice objects can: be destroyed when all sname:VkQueue objects |
| retrieved from them are idle, and all objects created from them have |
| been destroyed. |
| ** This includes the following objects: |
| + |
| -- |
| ** sname:VkFence |
| ** sname:VkSemaphore |
| ** sname:VkEvent |
| ifndef::VKSC_VERSION_1_0[] |
| ** sname:VkQueryPool |
| endif::VKSC_VERSION_1_0[] |
| ** sname:VkBuffer |
| ** sname:VkBufferView |
| ** sname:VkImage |
| ** sname:VkImageView |
| ifndef::VKSC_VERSION_1_0[] |
| ** sname:VkShaderModule |
| endif::VKSC_VERSION_1_0[] |
| ** sname:VkPipelineCache |
| ** sname:VkPipeline |
| ** sname:VkPipelineLayout |
| ** sname:VkSampler |
| ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| ** sname:VkSamplerYcbcrConversion |
| endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| ** sname:VkDescriptorSetLayout |
| ifndef::VKSC_VERSION_1_0[] |
| ** sname:VkDescriptorPool |
| endif::VKSC_VERSION_1_0[] |
| ** sname:VkFramebuffer |
| ** sname:VkRenderPass |
| ifndef::VKSC_VERSION_1_0[] |
| ** sname:VkCommandPool |
| endif::VKSC_VERSION_1_0[] |
| ** sname:VkCommandBuffer |
| ifndef::VKSC_VERSION_1_0[] |
| ** sname:VkDeviceMemory |
| endif::VKSC_VERSION_1_0[] |
| ifdef::VK_EXT_validation_cache[] |
| ** sname:VkValidationCacheEXT |
| endif::VK_EXT_validation_cache[] |
| ifdef::VK_NV_ray_tracing[] |
| ** sname:VkAccelerationStructureNV |
| endif::VK_NV_ray_tracing[] |
| ifdef::VK_KHR_acceleration_structure[] |
| ** sname:VkAccelerationStructureKHR |
| endif::VK_KHR_acceleration_structure[] |
| ifdef::VK_KHR_video_queue[] |
| ** sname:VkVideoSessionKHR |
| ** sname:VkVideoSessionParametersKHR |
| endif::VK_KHR_video_queue[] |
| -- |
| ifdef::VKSC_VERSION_1_0[] |
| ** This does not include objects that do not have corresponding free or |
| destroy commands. |
| If |
| slink:VkPhysicalDeviceVulkanSC10Properties::<<limits-deviceDestroyFreesMemory, |
| pname:deviceDestroyFreesMemory>> is ename:VK_TRUE, the memory from |
| these objects is returned to the system when the device is destroyed, |
| otherwise it may: not be returned to the system until the process is |
| terminated. |
| endif::VKSC_VERSION_1_0[] |
| * sname:VkPhysicalDevice objects cannot: be explicitly destroyed. |
| Instead, they are implicitly destroyed when the sname:VkInstance object |
| they are retrieved from is destroyed. |
| * sname:VkInstance objects can: be destroyed once all sname:VkDevice |
| objects created from any of its sname:VkPhysicalDevice objects have been |
| destroyed. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_memory_capabilities,VK_KHR_external_semaphore_capabilities,VK_KHR_external_fence_capabilities[] |
| [[fundamentals-objectmodel-external]] |
| === External Object Handles |
| |
| As defined above, the scope of object handles created or allocated from a |
| sname:VkDevice is limited to that logical device. |
| Objects which are not in scope are said to be external. |
| To bring an external object into scope, an external handle must: be exported |
| from the object in the source scope and imported into the destination scope. |
| |
| [NOTE] |
| .Note |
| ==== |
| The scope of external handles and their associated resources may: vary |
| according to their type, but they can: generally be shared across process |
| and API boundaries. |
| ==== |
| endif::VK_VERSION_1_1,VK_KHR_external_memory_capabilities,VK_KHR_external_semaphore_capabilities,VK_KHR_external_fence_capabilities[] |
| |
| |
| [[fundamentals-abi]] |
| == Application Binary Interface |
| |
| The mechanism by which Vulkan is made available to applications is platform- |
| or implementation- defined. |
| On many platforms the C interface described in this Specification is |
| provided by a shared library. |
| Since shared libraries can be changed independently of the applications that |
| use them, they present particular compatibility challenges, and this |
| Specification places some requirements on them. |
| |
| Shared library implementations must: use the default Application Binary |
| Interface (ABI) of the standard C compiler for the platform, or provide |
| customized API headers that cause application code to use the |
| implementation's non-default ABI. |
| An ABI in this context means the size, alignment, and layout of C data |
| types; the procedure calling convention; and the naming convention for |
| shared library symbols corresponding to C functions. |
| Customizing the calling convention for a platform is usually accomplished by |
| defining <<boilerplate-platform-specific-calling-conventions,calling |
| convention macros>> appropriately in `vk_platform.h`. |
| |
| On platforms where Vulkan is provided as a shared library, library symbols |
| beginning with "`vk`" and followed by a digit or uppercase letter are |
| reserved for use by the implementation. |
| Applications which use Vulkan must: not provide definitions of these |
| symbols. |
| This allows the Vulkan shared library to be updated with additional symbols |
| for new API versions or extensions without causing symbol conflicts with |
| existing applications. |
| |
| Shared library implementations should: provide library symbols for commands |
| in the highest version of this Specification they support, and for |
| ifdef::VK_KHR_surface[] |
| <<wsi,Window System Integration>> |
| endif::VK_KHR_surface[] |
| ifndef::VK_KHR_surface[] |
| Window System Integration |
| endif::VK_KHR_surface[] |
| extensions relevant to the platform. |
| They may: also provide library symbols for commands defined by additional |
| extensions. |
| |
| [NOTE] |
| .Note |
| ==== |
| These requirements and recommendations are intended to allow implementors to |
| take advantage of platform-specific conventions for SDKs, ABIs, library |
| versioning mechanisms, etc. |
| while still minimizing the code changes necessary to port applications or |
| libraries between platforms. |
| Platform vendors, or providers of the _de facto_ standard Vulkan shared |
| library for a platform, are encouraged to document what symbols the shared |
| library provides and how it will be versioned when new symbols are added. |
| |
| Applications should: only rely on shared library symbols for commands in the |
| minimum core version required by the application. |
| flink:vkGetInstanceProcAddr and flink:vkGetDeviceProcAddr should: be used to |
| obtain function pointers for commands in core versions beyond the |
| application's minimum required version. |
| ==== |
| |
| |
| [[fundamentals-commandsyntax]] |
| == Command Syntax and Duration |
| |
| The Specification describes Vulkan commands as functions or procedures using |
| C99 syntax. |
| Language bindings for other languages such as C++ and JavaScript may: allow |
| for stricter parameter passing, or object-oriented interfaces. |
| |
| Vulkan uses the standard C types for the base type of scalar parameters |
| (e.g. types from `<stdint.h>`), with exceptions described below, or |
| elsewhere in the text when appropriate: |
| |
| [open,refpage='VkBool32',desc='Vulkan boolean type',type='basetypes',xrefs='VK_TRUE VK_FALSE'] |
| -- |
| basetype:VkBool32 represents boolean `True` and `False` values, since C does |
| not have a sufficiently portable built-in boolean type: |
| |
| include::{generated}/api/basetypes/VkBool32.adoc[] |
| |
| ename:VK_TRUE represents a boolean *True* (unsigned integer 1) value, and |
| ename:VK_FALSE a boolean *False* (unsigned integer 0) value. |
| |
| All values returned from a Vulkan implementation in a basetype:VkBool32 will |
| be either ename:VK_TRUE or ename:VK_FALSE. |
| |
| Applications must: not pass any other values than ename:VK_TRUE or |
| ename:VK_FALSE into a Vulkan implementation where a basetype:VkBool32 is |
| expected. |
| -- |
| |
| [open,refpage='VK_TRUE',desc='Boolean true value',type='consts',xrefs='VkBool32 VK_FALSE'] |
| -- |
| ename:VK_TRUE is a constant representing a basetype:VkBool32 *True* value. |
| |
| include::{generated}/api/enums/VK_TRUE.adoc[] |
| -- |
| |
| [open,refpage='VK_FALSE',desc='Boolean false value',type='consts',xrefs='VkBool32 VK_TRUE'] |
| -- |
| ename:VK_FALSE is a constant representing a basetype:VkBool32 *False* value. |
| |
| include::{generated}/api/enums/VK_FALSE.adoc[] |
| -- |
| |
| |
| [open,refpage='VkDeviceSize',desc='Vulkan device memory size and offsets',type='basetypes'] |
| -- |
| basetype:VkDeviceSize represents device memory size and offset values: |
| |
| include::{generated}/api/basetypes/VkDeviceSize.adoc[] |
| -- |
| |
| ifdef::VK_VERSION_1_0,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| [open,refpage='VkDeviceAddress',desc='Vulkan device address type',type='basetypes'] |
| -- |
| basetype:VkDeviceAddress represents device buffer address values: |
| |
| include::{generated}/api/basetypes/VkDeviceAddress.adoc[] |
| -- |
| endif::VK_VERSION_1_0,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| |
| Commands that create Vulkan objects are of the form ftext:vkCreate* and take |
| stext:Vk*CreateInfo structures with the parameters needed to create the |
| object. |
| These Vulkan objects are destroyed with commands of the form |
| ftext:vkDestroy*. |
| |
| The last in-parameter to each command that creates or destroys a Vulkan |
| object is pname:pAllocator. |
| ifndef::VKSC_VERSION_1_0[] |
| The pname:pAllocator parameter can: be set to a non-`NULL` value such that |
| allocations for the given object are delegated to an application provided |
| callback; refer to the <<memory-allocation,Memory Allocation>> chapter for |
| further details. |
| endif::VKSC_VERSION_1_0[] |
| ifdef::VKSC_VERSION_1_0[] |
| The pname:pAllocator parameter must: be set to `NULL`. |
| Refer to the <<memory-allocation,Memory Allocation>> chapter for further |
| details. |
| endif::VKSC_VERSION_1_0[] |
| |
| Commands that allocate Vulkan objects owned by pool objects are of the form |
| ftext:vkAllocate*, and take stext:Vk*AllocateInfo structures. |
| These Vulkan objects are freed with commands of the form ftext:vkFree*. |
| These objects do not take allocators; if host memory is needed, they will |
| use the allocator that was specified when their parent pool was created. |
| |
| Commands are recorded into a command buffer by calling API commands of the |
| form ftext:vkCmd*. |
| Each such command may: have different restrictions on where it can: be used: |
| in a primary and/or secondary command buffer, inside and/or outside a render |
| pass, and in one or more of the supported queue types. |
| These restrictions are documented together with the definition of each such |
| command. |
| |
| The _duration_ of a Vulkan command refers to the interval between calling |
| the command and its return to the caller. |
| |
| |
| [[fundamentals-commandsyntax-results-lifetime]] |
| === Lifetime of Retrieved Results |
| |
| Information is retrieved from the implementation with commands of the form |
| ftext:vkGet* and ftext:vkEnumerate*. |
| |
| Unless otherwise specified for an individual command, the results are |
| _invariant_; that is, they will remain unchanged when retrieved again by |
| calling the same command with the same parameters, so long as those |
| parameters themselves all remain valid. |
| |
| |
| [[fundamentals-threadingbehavior]] |
| == Threading Behavior |
| |
| Vulkan is intended to provide scalable performance when used on multiple |
| host threads. |
| All commands support being called concurrently from multiple threads, but |
| certain parameters, or components of parameters are defined to be |
| _externally synchronized_. |
| This means that the caller must: guarantee that no more than one thread is |
| using such a parameter at a given time. |
| |
| More precisely, Vulkan commands use simple stores to update the state of |
| Vulkan objects. |
| A parameter declared as externally synchronized may: have its contents |
| updated at any time during the host execution of the command. |
| If two commands operate on the same object and at least one of the commands |
| declares the object to be externally synchronized, then the caller must: |
| guarantee not only that the commands do not execute simultaneously, but also |
| that the two commands are separated by an appropriate memory barrier (if |
| needed). |
| |
| [NOTE] |
| .Note |
| ==== |
| Memory barriers are particularly relevant for hosts based on the ARM CPU |
| architecture, which is more weakly ordered than many developers are |
| accustomed to from x86/x64 programming. |
| Fortunately, most higher-level synchronization primitives (like the pthread |
| library) perform memory barriers as a part of mutual exclusion, so mutexing |
| Vulkan objects via these primitives will have the desired effect. |
| ==== |
| |
| Similarly the application must: avoid any potential data hazard of |
| application-owned memory that has its |
| <<fundamentals-objectmodel-lifetime-acquire,ownership temporarily acquired>> |
| by a Vulkan command. |
| While the ownership of application-owned memory remains acquired by a |
| command the implementation may: read the memory at any point, and it may: |
| write non-code:const qualified memory at any point. |
| Parameters referring to non-code:const qualified application-owned memory |
| are not marked explicitly as _externally synchronized_ in the Specification. |
| |
| ifdef::VK_KHR_deferred_host_operations[] |
| If an application is using <<deferred-host-operations, deferred host |
| operations>> in a command, and that operation is successfully deferred, |
| object parameters and application-owned memory passed to that command may: |
| be accessed at any time until the deferred operation is complete. |
| endif::VK_KHR_deferred_host_operations[] |
| |
| Many object types are _immutable_, meaning the objects cannot: change once |
| they have been created. |
| These types of objects never need external synchronization, except that they |
| must: not be destroyed while they are in use on another thread. |
| In certain special cases mutable object parameters are internally |
| synchronized, making external synchronization unnecessary. |
| Any command parameters that are not labeled as externally synchronized are |
| either not mutated by the command or are internally synchronized. |
| Additionally, certain objects related to a command's parameters (e.g. |
| command pools and descriptor pools) may: be affected by a command, and must: |
| also be externally synchronized. |
| These implicit parameters are documented as described below. |
| |
| Parameters of commands that are externally synchronized are listed below. |
| |
| include::{generated}/hostsynctable/parameters.adoc[] |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_pipeline_creation_cache_control[] |
| For slink:VkPipelineCache objects created with pname:flags containing |
| ename:VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, the above table |
| is extended with the pname:pipelineCache parameter to |
| ftext:vkCreate*Pipelines being externally synchronized. |
| endif::VK_VERSION_1_3,VK_EXT_pipeline_creation_cache_control[] |
| |
| There are also a few instances where a command can: take in a user allocated |
| list whose contents are externally synchronized parameters. |
| In these cases, the caller must: guarantee that at most one thread is using |
| a given element within the list at a given time. |
| These parameters are listed below. |
| |
| include::{generated}/hostsynctable/parameterlists.adoc[] |
| |
| In addition, there are some implicit parameters that need to be externally |
| synchronized. |
| For example, when a pname:commandBuffer parameter needs to be externally |
| synchronized, it implies that the pname:commandPool from which that command |
| buffer was allocated also needs to be externally synchronized. |
| The implicit parameters and their associated object are listed below. |
| |
| include::{generated}/hostsynctable/implicit.adoc[] |
| |
| |
| [[fundamentals-validusage]] |
| == Valid Usage |
| |
| // preserving old id for permalinking |
| [[fundamentals-errors]] |
| Valid usage defines a set of conditions which must: be met in order to |
| achieve well-defined runtime behavior in an application. |
| These conditions depend only on Vulkan state, and the parameters or objects |
| whose usage is constrained by the condition. |
| |
| The core layer assumes applications are using the API correctly. |
| Except as documented elsewhere in the Specification, the behavior of the |
| core layer to an application using the API incorrectly is undefined:, and |
| may: include program termination. |
| However, implementations must: ensure that incorrect usage by an application |
| does not affect the integrity of the operating system, the Vulkan |
| implementation, or other Vulkan client applications in the system. |
| In particular, any guarantees made by an operating system about whether |
| memory from one process can: be visible to another process or not must: not |
| be violated by a Vulkan implementation for *any memory allocation*. |
| Vulkan implementations are not required: to make additional security or |
| integrity guarantees beyond those provided by the OS unless explicitly |
| directed by the application's use of a particular feature or extension. |
| |
| [NOTE] |
| .Note |
| ==== |
| For instance, if an operating system guarantees that data in all its memory |
| allocations are set to zero when newly allocated, the Vulkan implementation |
| must: make the same guarantees for any allocations it controls (e.g. |
| slink:VkDeviceMemory). |
| |
| Similarly, if an operating system guarantees that use-after-free of host |
| allocations will not result in values written by another process becoming |
| visible, the same guarantees must: be made by the Vulkan implementation for |
| device memory. |
| ==== |
| |
| ifdef::VK_VERSION_1_1[] |
| If the <<features-protectedMemory, pname:protectedMemory>> feature is |
| supported, the implementation provides additional guarantees when invalid |
| usage occurs to prevent values in protected memory from being accessed or |
| inferred outside of protected operations, as described in |
| <<memory-protected-access-rules>>. |
| endif::VK_VERSION_1_1[] |
| |
| Some valid usage conditions have dependencies on runtime limits or feature |
| availability. |
| It is possible to validate these conditions against Vulkan's minimum |
| supported values for these limits and features, or some subset of other |
| known values. |
| |
| Valid usage conditions do not cover conditions where well-defined behavior |
| (including returning an error code) exists. |
| |
| Valid usage conditions should: apply to the command or structure where |
| complete information about the condition would be known during execution of |
| an application. |
| This is such that a validation layer or linter can: be written directly |
| against these statements at the point they are specified. |
| |
| [NOTE] |
| .Note |
| ==== |
| This does lead to some non-obvious places for valid usage statements. |
| For instance, the valid values for a structure might depend on a separate |
| value in the calling command. |
| In this case, the structure itself will not reference this valid usage as it |
| is impossible to determine validity from the structure that it is invalid - |
| instead this valid usage would be attached to the calling command. |
| |
| Another example is draw state - the state setters are independent, and can |
| cause a legitimately invalid state configuration between draw calls; so the |
| valid usage statements are attached to the place where all state needs to be |
| valid - at the drawing command. |
| ==== |
| |
| Valid usage conditions are described in a block labelled "`Valid Usage`" |
| following each command or structure they apply to. |
| |
| |
| [[fundamentals-validation]] |
| === Usage Validation |
| |
| Vulkan is a layered API. |
| The lowest layer is the core Vulkan layer, as defined by this Specification. |
| The application can: use additional layers above the core for debugging, |
| validation, and other purposes. |
| |
| One of the core principles of Vulkan is that building and submitting command |
| buffers should: be highly efficient. |
| Thus error checking and validation of state in the core layer is minimal, |
| although more rigorous validation can: be enabled through the use of layers. |
| |
| Validation of correct API usage is left to validation layers. |
| Applications should: be developed with validation layers enabled, to help |
| catch and eliminate errors. |
| ifndef::VKSC_VERSION_1_0[] |
| Once validated, released applications should: not enable validation layers |
| by default. |
| endif::VKSC_VERSION_1_0[] |
| |
| |
| [[fundamentals-implicit-validity]] |
| === Implicit Valid Usage |
| |
| Some valid usage conditions apply to all commands and structures in the API, |
| unless explicitly denoted otherwise for a specific command or structure. |
| These conditions are considered _implicit_, and are described in a block |
| labelled "`Valid Usage (Implicit)`" following each command or structure they |
| apply to. |
| Implicit valid usage conditions are described in detail below. |
| |
| |
| [[fundamentals-validusage-handles]] |
| ==== Valid Usage for Object Handles |
| |
| Any input parameter to a command that is an object handle must: be a valid |
| object handle, unless otherwise specified. |
| An object handle is valid if: |
| |
| * It has been created or allocated by a previous, successful call to the |
| API. |
| Such calls are noted in the Specification. |
| * It has not been deleted or freed by a previous call to the API. |
| Such calls are noted in the Specification. |
| * Any objects used by that object, either as part of creation or |
| execution, must: also be valid. |
| |
| The reserved values dlink:VK_NULL_HANDLE and `NULL` can: be used in place of |
| valid non-dispatchable handles and dispatchable handles, respectively, when |
| _explicitly called out in the Specification_. |
| Any command that creates an object successfully must: not return these |
| values. |
| It is valid to pass these values to ftext:vkDestroy* or ftext:vkFree* |
| commands, which will silently ignore these values. |
| |
| |
| [[fundamentals-validusage-pointers]] |
| ==== Valid Usage for Pointers |
| |
| Any parameter that is a pointer must: be a _valid pointer_ only if it is |
| explicitly called out by a Valid Usage statement. |
| |
| A pointer is "`valid`" if it points at memory containing values of the |
| number and type(s) expected by the command, and all fundamental types |
| accessed through the pointer (e.g. as elements of an array or as members of |
| a structure) satisfy the alignment requirements of the host processor. |
| |
| |
| [[fundamentals-validusage-strings]] |
| ==== Valid Usage for Strings |
| |
| Any parameter that is a pointer to `char` must: be a finite sequence of |
| values terminated by a null character, or if _explicitly called out in the |
| Specification_, can: be `NULL`. |
| |
| |
| [[fundamentals-validusage-enums]] |
| ==== Valid Usage for Enumerated Types |
| |
| Any parameter of an enumerated type must: be a valid enumerant for that |
| type. |
| Use of an enumerant is valid if the following conditions are true: |
| |
| * The enumerant is defined as part of the enumerated type. |
| * The enumerant is not a value suffixed with etext:_MAX_ENUM. |
| ** This value exists only to ensure that C `enum` types are 32 bits in |
| size and must: not be used by applications. |
| * If the enumerant is used in a function that has a slink:VkInstance as |
| its first parameter and either: |
| ** it was added by a core version that is supported |
| ifdef::VK_VERSION_1_1[] |
| (as reported by flink:vkEnumerateInstanceVersion) |
| endif::VK_VERSION_1_1[] |
| and the value of slink:VkApplicationInfo::pname:apiVersion is greater |
| than or equal to the version that added it; or |
| ** it was added by an <<extensions, instance extension>> that was enabled |
| for the instance. |
| * If the enumerant is used in a function that has a slink:VkPhysicalDevice |
| object as its first parameter and either: |
| ** it was added by a core version that is supported by that device (as |
| reported by slink:VkPhysicalDeviceProperties::pname:apiVersion); |
| ** it was added by an <<extensions, instance extension>> that was enabled |
| for the instance; or |
| ** it was added by a <<extensions, device extension>> that is supported by |
| that device. |
| * If the enumerant is used in a function that has any other dispatchable |
| object as its first parameter and either: |
| ** it was added by a core version that is supported for the device (as |
| reported by slink:VkPhysicalDeviceProperties::pname:apiVersion); or |
| ** it was added by a <<extensions, device extension>> that was enabled for |
| the device. |
| |
| ifdef::VK_KHR_maintenance5[] |
| Additionally, if <<features-maintenance5,pname:maintenance5>> is supported, |
| any integer value representable in the range valid for the defined type is |
| valid when used in a function that has a slink:VkPhysicalDevice object as |
| its first parameter. |
| Physical device queries will either return results indicating lack of |
| support, or ignore unsupported values when used as a bit flag in a |
| etext:Vk*Flags* parameter. |
| endif::VK_KHR_maintenance5[] |
| |
| Any enumerated type returned from a query command or otherwise output from |
| Vulkan to the application must: not have a reserved value. |
| Reserved values are values not defined by any extension for that enumerated |
| type. |
| |
| [NOTE] |
| .Note |
| ==== |
| In some special cases, an enumerant is only meaningful if a feature defined |
| by an extension is also enabled, as well as the extension itself. |
| The global "`valid enumerant`" rule described here does not address such |
| cases. |
| ==== |
| |
| [NOTE] |
| .Note |
| ==== |
| This language is intended to accommodate cases such as "`hidden`" extensions |
| known only to driver internals, or layers enabling extensions without |
| knowledge of the application, without allowing return of values not defined |
| by any extension. |
| ==== |
| |
| [NOTE] |
| .Note |
| ==== |
| Application developers are encouraged to be careful when using `switch` |
| statements with Vulkan API enums. |
| This is because new extensions can add new values to existing enums. |
| Using a `default:` statement within a `switch` may avoid future compilation |
| issues. |
| |
| ifdef::VK_VERSION_1_2[] |
| This is particularly true for enums such as elink:VkDriverId, which may have |
| values added that do not belong to a corresponding new extension. |
| endif::VK_VERSION_1_2[] |
| ==== |
| |
| |
| [[fundamentals-validusage-flags]] |
| ==== Valid Usage for Flags |
| |
| [open,refpage='VkFlags',desc='Vulkan bitmasks',type='basetypes',xrefs='VkColorComponentFlags VkFlags64'] |
| -- |
| A collection of flags is represented by a bitmask using the type |
| basetype:VkFlags: |
| |
| include::{generated}/api/basetypes/VkFlags.adoc[] |
| |
| Bitmasks are passed to many commands and structures to compactly represent |
| options, but basetype:VkFlags is not used directly in the API. |
| Instead, a etext:Vk*Flags type which is an alias of basetype:VkFlags, and |
| whose name matches the corresponding etext:Vk*FlagBits that are valid for |
| that type, is used. |
| |
| Any etext:Vk*Flags member or parameter used in the API as an input must: be |
| a valid combination of bit flags. |
| A valid combination is either zero or the bitwise OR of valid bit flags. |
| |
| An individual bit flag is valid for a etext:Vk*Flags type if it would be a |
| <<fundamentals-validusage-enums,valid enumerant>> when used with the |
| equivalent etext:Vk*FlagBits type, where the bits type is obtained by taking |
| the flag type and replacing the trailing etext:Flags with etext:FlagBits. |
| For example, a flag value of type tlink:VkColorComponentFlags must: contain |
| only bit flags defined by elink:VkColorComponentFlagBits. |
| |
| Any etext:Vk*Flags member or parameter returned from a query command or |
| otherwise output from Vulkan to the application may: contain bit flags |
| undefined: in its corresponding etext:Vk*FlagBits type. |
| An application cannot: rely on the state of these unspecified bits. |
| |
| Only the low-order 31 bits (bit positions zero through 30) are available for |
| use as flag bits. |
| |
| [NOTE] |
| .Note |
| ==== |
| This restriction is due to poorly defined behavior by C compilers given a C |
| enumerant value of `0x80000000`. |
| In some cases adding this enumerant value may increase the size of the |
| underlying etext:Vk*FlagBits type, breaking the ABI. |
| ==== |
| -- |
| |
| ifdef::VK_VERSION_1_3,VK_KHR_format_feature_flags2,VK_KHR_synchronization2[] |
| [open,refpage='VkFlags64',desc='Vulkan 64-bit bitmasks',type='basetypes',xrefs='VkFlags'] |
| -- |
| A collection of 64-bit flags is represented by a bitmask using the type |
| basetype:VkFlags64: |
| |
| include::{generated}/api/basetypes/VkFlags64.adoc[] |
| |
| When the 31 bits available in basetype:VkFlags are insufficient, the |
| basetype:VkFlags64 type can be passed to commands and structures to |
| represent up to 64 options. |
| basetype:VkFlags64 is not used directly in the API. |
| Instead, a etext:Vk*Flags2 type which is an alias of basetype:VkFlags64, and |
| whose name matches the corresponding etext:Vk*FlagBits2 that are valid for |
| that type, is used. |
| |
| Any etext:Vk*Flags2 member or parameter used in the API as an input must: be |
| a valid combination of bit flags. |
| A valid combination is either zero or the bitwise OR of valid bit flags. |
| |
| An individual bit flag is valid for a etext:Vk*Flags2 type if it would be a |
| <<fundamentals-validusage-enums,valid enumerant>> when used with the |
| equivalent etext:Vk*FlagBits2 type, where the bits type is obtained by |
| taking the flag type and replacing the trailing etext:Flags2 with |
| etext:FlagBits2. |
| For example, a flag value of type tlink:VkAccessFlags2KHR must: contain only |
| bit flags defined by elink:VkAccessFlagBits2KHR. |
| |
| Any etext:Vk*Flags2 member or parameter returned from a query command or |
| otherwise output from Vulkan to the application may: contain bit flags |
| undefined: in its corresponding etext:Vk*FlagBits2 type. |
| An application cannot: rely on the state of these unspecified bits. |
| |
| [NOTE] |
| .Note |
| ==== |
| Both the etext:Vk*FlagBits2 type, and the individual bits defined for that |
| type, are defined as `uint64_t` integers in the C API. |
| This is in contrast to the 32-bit types, where the etext:Vk*FlagBits type is |
| defined as a C `enum` and the individual bits as enumerants belonging to |
| that `enum`. |
| As a result, there is less compile time type checking possible for the |
| 64-bit types. |
| This is unavoidable since there is no sufficiently portable way to define a |
| 64-bit `enum` type in C99. |
| ==== |
| -- |
| endif::VK_VERSION_1_3,VK_KHR_format_feature_flags2,VK_KHR_synchronization2[] |
| |
| |
| [[fundamentals-validusage-sType]] |
| ==== Valid Usage for Structure Types |
| |
| Any parameter that is a structure containing a pname:sType member must: have |
| a value of ptext:sType which is a valid elink:VkStructureType value matching |
| the type of the structure. |
| |
| |
| [[fundamentals-validusage-pNext]] |
| ==== Valid Usage for Structure Pointer Chains |
| |
| Any parameter that is a structure containing a code:void* ptext:pNext member |
| must: have a value of pname:pNext that is either `NULL`, or is a pointer to |
| a valid _extending structure_, containing ptext:sType and ptext:pNext |
| members as described in the <<vulkan-styleguide,Vulkan Documentation and |
| Extensions>> document in the section "`Extending Structures`". |
| The set of structures connected by ptext:pNext pointers is referred to as a |
| _pname:pNext chain_. |
| |
| Each structure included in the pname:pNext chain must: be defined at runtime |
| by either: |
| |
| * a core version which is supported |
| * an extension which is enabled |
| ifdef::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[] |
| * a supported device extension in the case of physical-device-level |
| functionality added by the device extension |
| endif::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[] |
| |
| Each type of extending structure must: not appear more than once in a |
| ptext:pNext chain, including any |
| <<extendingvulkan-compatibility-aliases,aliases>>. |
| This general rule may be explicitly overridden for specific structures. |
| |
| Any component of the implementation (the loader, any enabled layers, and |
| drivers) must: skip over, without processing (other than reading the |
| pname:sType and pname:pNext members) any extending structures in the chain |
| not defined by core versions or extensions supported by that component. |
| |
| As a convenience to implementations and layers needing to iterate through a |
| structure pointer chain, the Vulkan API provides two _base structures_. |
| These structures allow for some type safety, and can be used by Vulkan API |
| functions that operate on generic inputs and outputs. |
| |
| [open,refpage='VkBaseInStructure',desc='Base structure for a read-only pointer chain',type='structs'] |
| -- |
| The sname:VkBaseInStructure structure is defined as: |
| |
| include::{generated}/api/structs/VkBaseInStructure.adoc[] |
| |
| * pname:sType is the structure type of the structure being iterated |
| through. |
| * pname:pNext is `NULL` or a pointer to the next structure in a structure |
| chain. |
| |
| sname:VkBaseInStructure can be used to facilitate iterating through a |
| read-only structure pointer chain. |
| -- |
| |
| [open,refpage='VkBaseOutStructure',desc='Base structure for a read-only pointer chain',type='structs'] |
| -- |
| The sname:VkBaseOutStructure structure is defined as: |
| |
| include::{generated}/api/structs/VkBaseOutStructure.adoc[] |
| |
| * pname:sType is the structure type of the structure being iterated |
| through. |
| * pname:pNext is `NULL` or a pointer to the next structure in a structure |
| chain. |
| |
| sname:VkBaseOutStructure can be used to facilitate iterating through a |
| structure pointer chain that returns data back to the application. |
| -- |
| |
| |
| [[fundamentals-validusage-nested-structs]] |
| ==== Valid Usage for Nested Structures |
| |
| The above conditions also apply recursively to members of structures |
| provided as input to a command, either as a direct argument to the command, |
| or themselves a member of another structure. |
| |
| Specifics on valid usage of each command are covered in their individual |
| sections. |
| |
| |
| [[fundamentals-validusage-extensions]] |
| ==== Valid Usage for Extensions |
| |
| Instance-level functionality or behavior added by an <<extensions, instance |
| extension>> to the API must: not be used unless that extension is supported |
| by the instance as determined by |
| flink:vkEnumerateInstanceExtensionProperties, and that extension is enabled |
| in slink:VkInstanceCreateInfo. |
| |
| Physical-device-level functionality or behavior added by an <<extensions, |
| instance extension>> to the API must: not be used unless that extension is |
| supported by the instance as determined by |
| flink:vkEnumerateInstanceExtensionProperties, and that extension is enabled |
| in slink:VkInstanceCreateInfo. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[] |
| Physical-device-level functionality or behavior added by a <<extensions, |
| device extension>> to the API must: not be used unless the conditions |
| described in <<initialization-phys-dev-extensions, Extending Physical Device |
| Core Functionality>> are met. |
| endif::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[] |
| |
| Device-level functionality added by a <<extensions, device extension>> that |
| is dispatched from a slink:VkDevice, or from a child object of a |
| slink:VkDevice must: not be used unless that extension is supported by the |
| device as determined by flink:vkEnumerateDeviceExtensionProperties, and that |
| extension is enabled in slink:VkDeviceCreateInfo. |
| |
| [[fundamentals-validusage-versions]] |
| ==== Valid Usage for Newer Core Versions |
| |
| ifdef::VK_VERSION_1_1[] |
| |
| Instance-level functionality or behavior added by a <<versions, new core |
| version>> of the API must: not be used unless it is supported by the |
| instance as determined by flink:vkEnumerateInstanceVersion and the specified |
| version of slink:VkApplicationInfo::pname:apiVersion. |
| |
| endif::VK_VERSION_1_1[] |
| |
| Physical-device-level functionality or behavior added by a <<versions, new |
| core version>> of the API must: not be used unless it is supported by the |
| physical device as determined by |
| slink:VkPhysicalDeviceProperties::pname:apiVersion and the specified version |
| of slink:VkApplicationInfo::pname:apiVersion. |
| |
| Device-level functionality or behavior added by a <<versions, new core |
| version>> of the API must: not be used unless it is supported by the device |
| as determined by slink:VkPhysicalDeviceProperties::pname:apiVersion and the |
| specified version of slink:VkApplicationInfo::pname:apiVersion. |
| |
| |
| [[fundamentals-returncodes]] |
| == `VkResult` Return Codes |
| |
| [open,refpage='VkResult',desc='Vulkan command return codes',type='enums'] |
| -- |
| While the core Vulkan API is not designed to capture incorrect usage, some |
| circumstances still require return codes. |
| Commands in Vulkan return their status via return codes that are in one of |
| two categories: |
| |
| * Successful completion codes are returned when a command needs to |
| communicate success or status information. |
| All successful completion codes are non-negative values. |
| * Run time error codes are returned when a command needs to communicate a |
| failure that could only be detected at runtime. |
| All runtime error codes are negative values. |
| |
| All return codes in Vulkan are reported via elink:VkResult return values. |
| The possible codes are: |
| |
| include::{generated}/api/enums/VkResult.adoc[] |
| |
| [[fundamentals-successcodes]] |
| .Success Codes |
| * ename:VK_SUCCESS Command successfully completed |
| * ename:VK_NOT_READY A fence or query has not yet completed |
| * ename:VK_TIMEOUT A wait operation has not completed in the specified |
| time |
| * ename:VK_EVENT_SET An event is signaled |
| * ename:VK_EVENT_RESET An event is unsignaled |
| * ename:VK_INCOMPLETE A return array was too small for the result |
| ifdef::VK_KHR_swapchain[] |
| * ename:VK_SUBOPTIMAL_KHR A swapchain no longer matches the surface |
| properties exactly, but can: still be used to present to the surface |
| successfully. |
| endif::VK_KHR_swapchain[] |
| ifdef::VK_KHR_deferred_host_operations[] |
| * ename:VK_THREAD_IDLE_KHR A deferred operation is not complete but there |
| is currently no work for this thread to do at the time of this call. |
| * ename:VK_THREAD_DONE_KHR A deferred operation is not complete but there |
| is no work remaining to assign to additional threads. |
| * ename:VK_OPERATION_DEFERRED_KHR A deferred operation was requested and |
| at least some of the work was deferred. |
| * ename:VK_OPERATION_NOT_DEFERRED_KHR A deferred operation was requested |
| and no operations were deferred. |
| endif::VK_KHR_deferred_host_operations[] |
| ifdef::VK_VERSION_1_3,VK_EXT_pipeline_creation_cache_control[] |
| * ename:VK_PIPELINE_COMPILE_REQUIRED A requested pipeline creation would |
| have required compilation, but the application requested compilation to |
| not be performed. |
| endif::VK_VERSION_1_3,VK_EXT_pipeline_creation_cache_control[] |
| |
| [[fundamentals-errorcodes]] |
| .Error codes |
| * ename:VK_ERROR_OUT_OF_HOST_MEMORY A host memory allocation has failed. |
| * ename:VK_ERROR_OUT_OF_DEVICE_MEMORY A device memory allocation has |
| failed. |
| * ename:VK_ERROR_INITIALIZATION_FAILED Initialization of an object could |
| not be completed for implementation-specific reasons. |
| * ename:VK_ERROR_DEVICE_LOST The logical or physical device has been lost. |
| See <<devsandqueues-lost-device,Lost Device>> |
| * ename:VK_ERROR_MEMORY_MAP_FAILED Mapping of a memory object has failed. |
| * ename:VK_ERROR_LAYER_NOT_PRESENT A requested layer is not present or |
| could not be loaded. |
| * ename:VK_ERROR_EXTENSION_NOT_PRESENT A requested extension is not |
| supported. |
| * ename:VK_ERROR_FEATURE_NOT_PRESENT A requested feature is not supported. |
| * ename:VK_ERROR_INCOMPATIBLE_DRIVER The requested version of Vulkan is |
| not supported by the driver or is otherwise incompatible for |
| implementation-specific reasons. |
| * ename:VK_ERROR_TOO_MANY_OBJECTS Too many objects of the type have |
| already been created. |
| * ename:VK_ERROR_FORMAT_NOT_SUPPORTED A requested format is not supported |
| on this device. |
| * ename:VK_ERROR_FRAGMENTED_POOL A pool allocation has failed due to |
| fragmentation of the pool's memory. |
| This must: only be returned if no attempt to allocate host or device |
| memory was made to accommodate the new allocation. |
| ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[] |
| This should: be returned in preference to |
| ename:VK_ERROR_OUT_OF_POOL_MEMORY, but only if the implementation is |
| certain that the pool allocation failure was due to fragmentation. |
| endif::VK_VERSION_1_1,VK_KHR_maintenance1[] |
| ifdef::VK_KHR_surface[] |
| * ename:VK_ERROR_SURFACE_LOST_KHR A surface is no longer available. |
| * ename:VK_ERROR_NATIVE_WINDOW_IN_USE_KHR The requested window is already |
| in use by Vulkan or another API in a manner which prevents it from being |
| used again. |
| endif::VK_KHR_surface[] |
| ifdef::VK_KHR_swapchain[] |
| * ename:VK_ERROR_OUT_OF_DATE_KHR A surface has changed in such a way that |
| it is no longer compatible with the swapchain, and further presentation |
| requests using the swapchain will fail. |
| Applications must: query the new surface properties and recreate their |
| swapchain if they wish to continue presenting to the surface. |
| endif::VK_KHR_swapchain[] |
| ifdef::VK_KHR_display_swapchain[] |
| * ename:VK_ERROR_INCOMPATIBLE_DISPLAY_KHR The display used by a swapchain |
| does not use the same presentable image layout, or is incompatible in a |
| way that prevents sharing an image. |
| endif::VK_KHR_display_swapchain[] |
| ifdef::VK_NV_glsl_shader[] |
| * ename:VK_ERROR_INVALID_SHADER_NV One or more shaders failed to compile |
| or link. |
| More details are reported back to the application via |
| `apiext:VK_EXT_debug_report` if enabled. |
| endif::VK_NV_glsl_shader[] |
| ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[] |
| * ename:VK_ERROR_OUT_OF_POOL_MEMORY A pool memory allocation has failed. |
| This must: only be returned if no attempt to allocate host or device |
| memory was made to accommodate the new allocation. |
| If the failure was definitely due to fragmentation of the pool, |
| ename:VK_ERROR_FRAGMENTED_POOL should: be returned instead. |
| endif::VK_VERSION_1_1,VK_KHR_maintenance1[] |
| ifdef::VK_VERSION_1_1,VK_KHR_external_memory,VK_KHR_external_semaphore,VK_KHR_external_fence[] |
| * ename:VK_ERROR_INVALID_EXTERNAL_HANDLE An external handle is not a valid |
| handle of the specified type. |
| endif::VK_VERSION_1_1,VK_KHR_external_memory,VK_KHR_external_semaphore,VK_KHR_external_fence[] |
| ifdef::VK_VERSION_1_2,VK_EXT_descriptor_indexing[] |
| * ename:VK_ERROR_FRAGMENTATION A descriptor pool creation has failed due |
| to fragmentation. |
| endif::VK_VERSION_1_2,VK_EXT_descriptor_indexing[] |
| ifdef::VK_EXT_buffer_device_address[] |
| * ename:VK_ERROR_INVALID_DEVICE_ADDRESS_EXT A buffer creation failed |
| because the requested address is not available. |
| endif::VK_EXT_buffer_device_address[] |
| ifdef::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| * ename:VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS A buffer creation |
| ifdef::VK_VERSION_1_2,VK_KHR_buffer_device_address[] |
| or memory allocation |
| endif::VK_VERSION_1_2,VK_KHR_buffer_device_address[] |
| failed because the requested address is not available. |
| ifdef::VK_KHR_ray_tracing_pipeline[] |
| A shader group handle assignment failed because the requested shader |
| group handle information is no longer valid. |
| endif::VK_KHR_ray_tracing_pipeline[] |
| endif::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| ifdef::VK_EXT_full_screen_exclusive[] |
| * ename:VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT An operation on a |
| swapchain created with |
| ename:VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT failed as it |
| did not have exclusive full-screen access. |
| This may: occur due to implementation-dependent reasons, outside of the |
| application's control. |
| endif::VK_EXT_full_screen_exclusive[] |
| ifdef::VKSC_VERSION_1_0,VK_EXT_debug_report[] |
| ifdef::VKSC_VERSION_1_0[] |
| * ename:VK_ERROR_VALIDATION_FAILED |
| endif::VKSC_VERSION_1_0[] |
| ifdef::VK_EXT_debug_report[] |
| * ename:VK_ERROR_VALIDATION_FAILED_EXT |
| endif::VK_EXT_debug_report[] |
| A command failed because invalid usage was detected by the |
| implementation or a validation-layer. |
| endif::VKSC_VERSION_1_0,VK_EXT_debug_report[] |
| ifdef::VKSC_VERSION_1_0[] |
| * ename:VK_ERROR_INVALID_PIPELINE_CACHE_DATA The supplied pipeline cache |
| data was not valid for the current implementation. |
| * ename:VK_ERROR_NO_PIPELINE_MATCH The implementation did not find a match |
| in the pipeline cache for the specified pipeline, or |
| slink:VkPipelineOfflineCreateInfo was not provided to the |
| ftext:vkCreate*Pipelines function. |
| ifdef::hidden[] |
| // tag::scaddition[] |
| * extending elink:VkResult |
| ** ename:VK_ERROR_VALIDATION_FAILED <<SCID-1>> |
| ** ename:VK_ERROR_INVALID_PIPELINE_CACHE_DATA <<SCID-1>> |
| ** ename:VK_ERROR_NO_PIPELINE_MATCH <<SCID-1>> |
| // end::scaddition[] |
| endif::hidden[] |
| endif::VKSC_VERSION_1_0[] |
| ifdef::VK_EXT_image_compression_control[] |
| * ename:VK_ERROR_COMPRESSION_EXHAUSTED_EXT An image creation failed |
| because internal resources required for compression are exhausted. |
| This must: only be returned when fixed-rate compression is requested. |
| endif::VK_EXT_image_compression_control[] |
| ifdef::VK_KHR_video_queue[] |
| * ename:VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR The requested |
| tlink:VkImageUsageFlags are not supported. |
| * ename:VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR The requested |
| video picture layout is not supported. |
| * ename:VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR A video profile |
| operation specified via |
| slink:VkVideoProfileInfoKHR::pname:videoCodecOperation is not supported. |
| * ename:VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR Format parameters |
| in a requested slink:VkVideoProfileInfoKHR chain are not supported. |
| * ename:VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR Codec-specific |
| parameters in a requested slink:VkVideoProfileInfoKHR chain are not |
| supported. |
| * ename:VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR The specified video |
| Std header version is not supported. |
| endif::VK_KHR_video_queue[] |
| ifdef::VK_KHR_video_encode_queue[] |
| * ename:VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR The specified Video Std |
| parameters do not adhere to the syntactic or semantic requirements of |
| the used video compression standard, or values derived from parameters |
| according to the rules defined by the used video compression standard do |
| not adhere to the capabilities of the video compression standard or the |
| implementation. |
| endif::VK_KHR_video_encode_queue[] |
| ifdef::VK_EXT_shader_object[] |
| * ename:VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT The provided binary shader |
| code is not compatible with this device. |
| endif::VK_EXT_shader_object[] |
| * ename:VK_ERROR_UNKNOWN An unknown error has occurred; either the |
| application has provided invalid input, or an implementation failure has |
| occurred. |
| |
| If a command returns a runtime error, unless otherwise specified any output |
| parameters will have undefined: contents, except that if the output |
| parameter is a structure with pname:sType and pname:pNext fields, those |
| fields will be unmodified. |
| Any structures chained from pname:pNext will also have undefined: contents, |
| except that pname:sType and pname:pNext will be unmodified. |
| |
| etext:VK_ERROR_OUT_OF_*_MEMORY errors do not modify any currently existing |
| Vulkan objects. |
| Objects that have already been successfully created can: still be used by |
| the application. |
| ifdef::VKSC_VERSION_1_0[] |
| If |
| slink:VkPhysicalDeviceVulkanSC10Properties::pname:deviceNoDynamicHostAllocations |
| is ename:VK_TRUE, ename:VK_ERROR_OUT_OF_HOST_MEMORY must: not be returned |
| from any physical or logical device command which explicitly disallows it. |
| ifdef::hidden[] |
| // tag::scdeviation[] |
| * If |
| slink:VkPhysicalDeviceVulkanSC10Properties::pname:deviceNoDynamicHostAllocations |
| is ename:VK_TRUE, ename:VK_ERROR_OUT_OF_HOST_MEMORY must: not be |
| returned by physical or logical device commands which explicitly |
| disallow it <<SCID-4>>. |
| // end::scdeviation[] |
| endif::hidden[] |
| endif::VKSC_VERSION_1_0[] |
| |
| [NOTE] |
| .Note |
| ==== |
| As a general rule, ftext:Free, ftext:Release, and ftext:Reset commands do |
| not return ename:VK_ERROR_OUT_OF_HOST_MEMORY, while any other command with a |
| return code may: return it. |
| Any exceptions from this rule are described for those commands. |
| ==== |
| |
| ename:VK_ERROR_UNKNOWN will be returned by an implementation when an |
| unexpected error occurs that cannot be attributed to valid behavior of the |
| application and implementation. |
| Under these conditions, it may: be returned from any command returning a |
| elink:VkResult. |
| |
| [NOTE] |
| .Note |
| ==== |
| ename:VK_ERROR_UNKNOWN is not expected to ever be returned if the |
| application behavior is valid, and if the implementation is bug-free. |
| If ename:VK_ERROR_UNKNOWN is received, the application should be checked |
| against the latest validation layers to verify correct behavior as much as |
| possible. |
| If no issues are identified it could be an implementation issue, and the |
| implementor should be contacted for support. |
| ==== |
| |
| ifdef::VKSC_VERSION_1_0,VK_EXT_debug_report[] |
| Any command returning a elink:VkResult may: return |
| ifdef::VKSC_VERSION_1_0[ename:VK_ERROR_VALIDATION_FAILED] |
| ifdef::VK_EXT_debug_report[ename:VK_ERROR_VALIDATION_FAILED_EXT] |
| if a violation of valid usage is detected, even though commands do not |
| explicitly list this as a possible return code. |
| endif::VKSC_VERSION_1_0,VK_EXT_debug_report[] |
| |
| Performance-critical commands generally do not have return codes. |
| If a runtime error occurs in such commands, the implementation will defer |
| reporting the error until a specified point. |
| For commands that record into command buffers (ftext:vkCmd*) runtime errors |
| are reported by fname:vkEndCommandBuffer. |
| |
| ifdef::VKSC_VERSION_1_0[] |
| [NOTE] |
| .Note |
| ==== |
| Implementations can also use <<fault-handling>> to report runtime errors |
| where suitable return values are not available or to provide more prompt |
| notification of an error. |
| ==== |
| endif::VKSC_VERSION_1_0[] |
| -- |
| |
| |
| [[fundamentals-numerics]] |
| == Numeric Representation and Computation |
| |
| Implementations normally perform computations in floating-point, and must: |
| meet the range and precision requirements defined under "`Floating-Point |
| Computation`" below. |
| |
| These requirements only apply to computations performed in Vulkan operations |
| outside of shader execution, such as texture image specification and |
| sampling, and per-fragment operations. |
| Range and precision requirements during shader execution differ and are |
| specified by the <<spirvenv-precision-operation, Precision and Operation of |
| SPIR-V Instructions>> section. |
| |
| In some cases, the representation and/or precision of operations is |
| implicitly limited by the specified format of vertex or texel data consumed |
| by Vulkan. |
| Specific floating-point formats are described later in this section. |
| |
| |
| [[fundamentals-floatingpoint]] |
| === Floating-Point Computation |
| |
| Most floating-point computation is performed in SPIR-V shader modules. |
| The properties of computation within shaders are constrained as defined by |
| the <<spirvenv-precision-operation, Precision and Operation of SPIR-V |
| Instructions>> section. |
| |
| Some floating-point computation is performed outside of shaders, such as |
| viewport and depth range calculations. |
| For these computations, we do not specify how floating-point numbers are to |
| be represented, or the details of how operations on them are performed, but |
| only place minimal requirements on representation and precision as described |
| in the remainder of this section. |
| |
| ifdef::editing-notes[] |
| [NOTE] |
| .editing-note |
| ==== |
| (Jon, Bug 14966) This is a rat's nest of complexity, both in terms of |
| describing/enumerating places such computation may: take place (other than |
| "`not shader code`") and in how implementations may: do it. |
| We have consciously deferred the resolution of this issue to post-1.0, and |
| in the meantime, the following language inherited from the OpenGL |
| Specification is inserted as a placeholder. |
| Hopefully it can: be tightened up considerably. |
| ==== |
| endif::editing-notes[] |
| |
| We require simply that numbers`' floating-point parts contain enough bits |
| and that their exponent fields are large enough so that individual results |
| of floating-point operations are accurate to about 1 part in 10^5^. |
| The maximum representable magnitude for all floating-point values must: be |
| at least 2^32^. |
| |
| {empty}:: [eq]#x {times} 0 = 0 {times} x = 0# for any non-infinite and |
| non-[eq]#NaN# [eq]#x#. |
| {empty}:: [eq]#1 {times} x = x {times} 1 = x#. |
| {empty}:: [eq]#x {plus} 0 = 0 {plus} x = x#. |
| {empty}:: [eq]#0^0^ = 1#. |
| |
| Occasionally, further requirements will be specified. |
| Most single-precision floating-point formats meet these requirements. |
| |
| The special values [eq]#Inf# and [eq]#-Inf# encode values with magnitudes |
| too large to be represented; the special value [eq]#NaN# encodes "`Not A |
| Number`" values resulting from undefined: arithmetic operations such as |
| [eq]#0 / 0#. |
| Implementations may: support [eq]#Inf# and [eq]#NaN# in their floating-point |
| computations. |
| Any computation which does not support either [eq]#Inf# or [eq]#NaN#, for |
| which that value is an input or output will yield an undefined: value. |
| |
| |
| [[fundamentals-fp-conversion]] |
| === Floating-Point Format Conversions |
| |
| When a value is converted to a defined floating-point representation, finite |
| values falling between two representable finite values are rounded to one or |
| the other. |
| The rounding mode is not defined. |
| Finite values whose magnitude is larger than that of any representable |
| finite value may be rounded either to the closest representable finite value |
| or to the appropriately signed infinity. |
| For unsigned destination formats any negative values are converted to zero. |
| Positive infinity is converted to positive infinity; negative infinity is |
| converted to negative infinity in signed formats and to zero in unsigned |
| formats; and any [eq]#NaN# is converted to a [eq]#NaN#. |
| |
| |
| [[fundamentals-fp16]] |
| === 16-Bit Floating-Point Numbers |
| |
| 16-bit floating point numbers are defined in the "`16-bit floating point |
| numbers`" section of the <<data-format,Khronos Data Format Specification>>. |
| |
| |
| [[fundamentals-fp11]] |
| === Unsigned 11-Bit Floating-Point Numbers |
| |
| Unsigned 11-bit floating point numbers are defined in the "`Unsigned 11-bit |
| floating point numbers`" section of the <<data-format,Khronos Data Format |
| Specification>>. |
| |
| |
| [[fundamentals-fp10]] |
| === Unsigned 10-Bit Floating-Point Numbers |
| |
| Unsigned 10-bit floating point numbers are defined in the "`Unsigned 10-bit |
| floating point numbers`" section of the <<data-format,Khronos Data Format |
| Specification>>. |
| |
| |
| [[fundamentals-general]] |
| === General Requirements |
| |
| Any representable floating-point value in the appropriate format is legal as |
| input to a Vulkan command that requires floating-point data. |
| The result of providing a value that is not a floating-point number to such |
| a command is unspecified, but must: not lead to Vulkan interruption or |
| termination. |
| For example, providing a negative zero (where applicable) or a denormalized |
| number to a Vulkan command must: yield deterministic results, while |
| providing a [eq]#NaN# or [eq]#Inf# yields unspecified results. |
| |
| Some calculations require division. |
| In such cases (including implied divisions performed by vector |
| normalization), division by zero produces an unspecified result but must: |
| not lead to Vulkan interruption or termination. |
| |
| |
| [[fundamentals-fixedconv]] |
| == Fixed-Point Data Conversions |
| |
| When generic vertex attributes and pixel color or depth _components_ are |
| represented as integers, they are often (but not always) considered to be |
| _normalized_. |
| Normalized integer values are treated specially when being converted to and |
| from floating-point values, and are usually referred to as _normalized |
| fixed-point_. |
| |
| In the remainder of this section, [eq]#b# denotes the bit width of the |
| fixed-point integer representation. |
| When the integer is one of the types defined by the API, [eq]#b# is the bit |
| width of that type. |
| When the integer comes from an <<resources-images,image>> containing color |
| or depth component texels, [eq]#b# is the number of bits allocated to that |
| component in its <<formats,specified image format>>. |
| |
| The signed and unsigned fixed-point representations are assumed to be |
| [eq]#b#-bit binary two's-complement integers and binary unsigned integers, |
| respectively. |
| |
| |
| [[fundamentals-fixedfpconv]] |
| === Conversion From Normalized Fixed-Point to Floating-Point |
| |
| Unsigned normalized fixed-point integers represent numbers in the range |
| [eq]#[0,1]#. |
| The conversion from an unsigned normalized fixed-point value [eq]#c# to the |
| corresponding floating-point value [eq]#f# is defined as |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| f = { c \over { 2^b - 1 } } |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| Signed normalized fixed-point integers represent numbers in the range |
| [eq]#[-1,1]#. |
| The conversion from a signed normalized fixed-point value [eq]#c# to the |
| corresponding floating-point value [eq]#f# is performed using |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| f = \max\left( {c \over {2^{b-1} - 1}}, -1.0 \right) |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| Only the range [eq]#[-2^b-1^ {plus} 1, 2^b-1^ - 1]# is used to represent |
| signed fixed-point values in the range [eq]#[-1,1]#. |
| For example, if [eq]#b = 8#, then the integer value [eq]#-127# corresponds |
| to [eq]#-1.0# and the value 127 corresponds to [eq]#1.0#. |
| This equation is used everywhere that signed normalized fixed-point values |
| are converted to floating-point. |
| |
| Note that while zero is exactly expressible in this representation, one |
| value ([eq]#-128# in the example) is outside the representable range, and |
| implementations must: clamp it to [eq]#-1.0#. |
| Where the value is subject to further processing by the implementation, e.g. |
| during texture filtering, values less than [eq]#-1.0# may: be used but the |
| result must: be clamped before the value is returned to shaders. |
| |
| |
| [[fundamentals-fpfixedconv]] |
| === Conversion From Floating-Point to Normalized Fixed-Point |
| |
| The conversion from a floating-point value [eq]#f# to the corresponding |
| unsigned normalized fixed-point value [eq]#c# is defined by first clamping |
| [eq]#f# to the range [eq]#[0,1]#, then computing |
| |
| {empty}:: [eq]#c = convertFloatToUint(f {times} (2^b^ - 1), b)# |
| |
| where [eq]#convertFloatToUint(r,b)# returns one of the two unsigned binary |
| integer values with exactly [eq]#b# bits which are closest to the |
| floating-point value [eq]#r#. |
| Implementations should: round to nearest. |
| If [eq]#r# is equal to an integer, then that integer value must: be |
| returned. |
| In particular, if [eq]#f# is equal to 0.0 or 1.0, then [eq]#c# must: be |
| assigned 0 or [eq]#2^b^ - 1#, respectively. |
| |
| The conversion from a floating-point value [eq]#f# to the corresponding |
| signed normalized fixed-point value [eq]#c# is performed by clamping [eq]#f# |
| to the range [eq]#[-1,1]#, then computing |
| |
| {empty}:: [eq]#c = convertFloatToInt(f {times} (2^b-1^ - 1), b)# |
| |
| where [eq]#convertFloatToInt(r,b)# returns one of the two signed |
| two's-complement binary integer values with exactly [eq]#b# bits which are |
| closest to the floating-point value [eq]#r#. |
| Implementations should: round to nearest. |
| If [eq]#r# is equal to an integer, then that integer value must: be |
| returned. |
| In particular, if [eq]#f# is equal to -1.0, 0.0, or 1.0, then [eq]#c# must: |
| be assigned [eq]#-(2^b-1^ - 1)#, 0, or [eq]#2^b-1^ - 1#, respectively. |
| |
| This equation is used everywhere that floating-point values are converted to |
| signed normalized fixed-point. |
| |
| |
| [[fundamentals-common-objects]] |
| == Common Object Types |
| |
| Some types of Vulkan objects are used in many different structures and |
| command parameters, and are described here. |
| These types include _offsets_, _extents_, and _rectangles_. |
| |
| |
| === Offsets |
| |
| Offsets are used to describe a pixel location within an image or |
| framebuffer, as an (x,y) location for two-dimensional images, or an (x,y,z) |
| location for three-dimensional images. |
| |
| [open,refpage='VkOffset2D',desc='Structure specifying a two-dimensional offset',type='structs'] |
| -- |
| A two-dimensional offset is defined by the structure: |
| |
| include::{generated}/api/structs/VkOffset2D.adoc[] |
| |
| * pname:x is the x offset. |
| * pname:y is the y offset. |
| |
| include::{generated}/validity/structs/VkOffset2D.adoc[] |
| -- |
| |
| [open,refpage='VkOffset3D',desc='Structure specifying a three-dimensional offset',type='structs'] |
| -- |
| A three-dimensional offset is defined by the structure: |
| |
| include::{generated}/api/structs/VkOffset3D.adoc[] |
| |
| * pname:x is the x offset. |
| * pname:y is the y offset. |
| * pname:z is the z offset. |
| |
| include::{generated}/validity/structs/VkOffset3D.adoc[] |
| -- |
| |
| |
| === Extents |
| |
| Extents are used to describe the size of a rectangular region of pixels |
| within an image or framebuffer, as (width,height) for two-dimensional |
| images, or as (width,height,depth) for three-dimensional images. |
| |
| [open,refpage='VkExtent2D',desc='Structure specifying a two-dimensional extent',type='structs'] |
| -- |
| A two-dimensional extent is defined by the structure: |
| |
| include::{generated}/api/structs/VkExtent2D.adoc[] |
| |
| * pname:width is the width of the extent. |
| * pname:height is the height of the extent. |
| |
| include::{generated}/validity/structs/VkExtent2D.adoc[] |
| -- |
| |
| [open,refpage='VkExtent3D',desc='Structure specifying a three-dimensional extent',type='structs'] |
| -- |
| A three-dimensional extent is defined by the structure: |
| |
| include::{generated}/api/structs/VkExtent3D.adoc[] |
| |
| * pname:width is the width of the extent. |
| * pname:height is the height of the extent. |
| * pname:depth is the depth of the extent. |
| |
| include::{generated}/validity/structs/VkExtent3D.adoc[] |
| -- |
| |
| |
| === Rectangles |
| |
| [open,refpage='VkRect2D',desc='Structure specifying a two-dimensional subregion',type='structs'] |
| -- |
| Rectangles are used to describe a specified rectangular region of pixels |
| within an image or framebuffer. |
| Rectangles include both an offset and an extent of the same dimensionality, |
| as described above. |
| Two-dimensional rectangles are defined by the structure |
| |
| include::{generated}/api/structs/VkRect2D.adoc[] |
| |
| * pname:offset is a slink:VkOffset2D specifying the rectangle offset. |
| * pname:extent is a slink:VkExtent2D specifying the rectangle extent. |
| |
| include::{generated}/validity/structs/VkRect2D.adoc[] |
| -- |
| |
| |
| // VkStructureType is pretty long, |
| // so keep it as a last chapter section for readability. |
| === Structure Types |
| |
| [open,refpage='VkStructureType',desc='Vulkan structure types (pname:sType)',type='enums'] |
| -- |
| Each value corresponds to a particular structure with a pname:sType member |
| with a matching name. |
| As a general rule, the name of each elink:VkStructureType value is obtained |
| by taking the name of the structure, stripping the leading etext:Vk, |
| prefixing each capital letter with etext:_, converting the entire resulting |
| string to upper case, and prefixing it with etext:VK_STRUCTURE_TYPE_. |
| For example, structures of type slink:VkImageCreateInfo correspond to a |
| elink:VkStructureType value of ename:VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, |
| and thus a structure of this type must: have its pname:sType member set to |
| this value before it is passed to the API. |
| |
| The values ename:VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO and |
| ename:VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for internal |
| use by the loader, and do not have corresponding Vulkan structures in this |
| Specification. |
| |
| Structure types supported by the Vulkan API include: |
| |
| include::{generated}/api/enums/VkStructureType.adoc[] |
| |
| ifdef::VKSC_VERSION_1_0[] |
| ifdef::hidden[] |
| // tag::scremoved[] |
| * elink:VkStructureType (deprecated aliases) |
| ** etext:VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES |
| <<SCID-8>> |
| ** etext:VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES |
| <<SCID-8>> |
| ** etext:VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT <<SCID-8>> |
| // end::scremoved[] |
| endif::hidden[] |
| endif::VKSC_VERSION_1_0[] |
| -- |
| |
| |
| [[fundamentals-api-name-aliases]] |
| == API Name Aliases |
| |
| A small number of APIs did not follow the <<vulkan-styleguide, naming |
| conventions>> when initially defined. |
| For consistency, when we discover an API name that violates the naming |
| conventions, we rename it in the Specification, XML, and header files. |
| For backwards compatibility, the original (incorrect) name is retained as a |
| "`typo alias`". |
| The alias is deprecated and should not be used, but will be retained |
| indefinitely. |
| |
| [NOTE] |
| .Note |
| ==== |
| etext:VK_STENCIL_FRONT_AND_BACK is an example of a _typo alias_. |
| It was initially defined as part of elink:VkStencilFaceFlagBits. |
| Once the naming inconsistency was noticed, it was renamed to |
| ename:VK_STENCIL_FACE_FRONT_AND_BACK, and the old name was aliased to the |
| correct name. |
| ==== |