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

include::{generated}/meta/{refprefix}VK_KHR_dedicated_allocation.adoc[]

=== Other Extension Metadata

*Last Modified Date*::
    2017-09-05
*IP Status*::
    No known IP claims.
*Contributors*::
  - Jeff Bolz, NVIDIA
  - Faith Ekstrand, Intel

=== Description

This extension enables resources to be bound to a dedicated allocation,
rather than suballocated.
For any particular resource, applications can: query whether a dedicated
allocation is recommended, in which case using a dedicated allocation may:
improve the performance of access to that resource.
Normal device memory allocations must support multiple resources per
allocation, memory aliasing and sparse binding, which could interfere with
some optimizations.
Applications should query the implementation for when a dedicated allocation
may: be beneficial by adding a sname:VkMemoryDedicatedRequirementsKHR
structure to the pname:pNext chain of the sname:VkMemoryRequirements2
structure passed as the pname:pMemoryRequirements parameter of a call to
fname:vkGetBufferMemoryRequirements2 or fname:vkGetImageMemoryRequirements2.
Certain external handle types and external images or buffers may: also
depend on dedicated allocations on implementations that associate image or
buffer metadata with OS-level memory objects.

This extension adds a two small structures to memory requirements querying
and memory allocation: a new structure that flags whether an image/buffer
should have a dedicated allocation, and a structure indicating the image or
buffer that an allocation will be bound to.

=== Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with the
KHR suffix omitted.
The original type, enum and command names are still available as aliases of
the core functionality.

include::{generated}/interfaces/VK_KHR_dedicated_allocation.adoc[]

=== Examples

[source,c++]
----
    // Create an image with a dedicated allocation based on the
    // implementation's preference

    VkImageCreateInfo imageCreateInfo =
    {
        // Image creation parameters
    };

    VkImage image;
    VkResult result = vkCreateImage(
        device,
        &imageCreateInfo,
        NULL,               // pAllocator
        &image);

    VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
    {
        .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
        .pNext = NULL,
    };

    VkMemoryRequirements2 memoryRequirements =
    {
        .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
        .pNext = &dedicatedRequirements,
    };

    const VkImageMemoryRequirementsInfo2 imageRequirementsInfo =
    {
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
        .pNext = NULL,
        .image = image
    };

    vkGetImageMemoryRequirements2(
        device,
        &imageRequirementsInfo,
        &memoryRequirements);

    if (dedicatedRequirements.prefersDedicatedAllocation) {
        // Allocate memory with VkMemoryDedicatedAllocateInfoKHR::image
        // pointing to the image we are allocating the memory for

        VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
        {
            .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
            .pNext = NULL,
            .image = image,
            .buffer = VK_NULL_HANDLE,
        };

        VkMemoryAllocateInfo memoryAllocateInfo =
        {
            .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
            .pNext = &dedicatedInfo,
            .allocationSize = memoryRequirements.size,
            .memoryTypeIndex = FindMemoryTypeIndex(memoryRequirements.memoryTypeBits),
        };

        VkDeviceMemory memory;
        vkAllocateMemory(
            device,
            &memoryAllocateInfo,
            NULL,               // pAllocator
            &memory);

        // Bind the image to the memory

        vkBindImageMemory(
            device,
            image,
            memory,
            0);
    } else {
        // Take the normal memory sub-allocation path
    }
----

=== Version History

  * Revision 1, 2017-02-27 (James Jones)
  ** Copy content from VK_NV_dedicated_allocation
  ** Add some references to external object interactions to the overview.

  * Revision 2, 2017-03-27 (Faith Ekstrand)
  ** Rework the extension to be query-based

  * Revision 3, 2017-07-31 (Faith Ekstrand)
  ** Clarify that memory objects allocated with
     VkMemoryDedicatedAllocateInfoKHR can only have the specified resource
     bound and no others.
