## 11.3. Images

Images represent multidimensional - up to 3 - arrays of data which can be used for various purposes (e.g. attachments, textures), by binding them to a graphics or compute pipeline via descriptor sets, or by directly specifying them as parameters to certain commands.

Images are represented by `VkImage` handles:

    VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage)

To create images, call:

    VkResult vkCreateImage(
        VkDevice                                    device,
        const VkImageCreateInfo*                    pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkImage*                                    pImage);

- `device` is the logical device that creates the image.
- `pCreateInfo` is a pointer to an instance of the `VkImageCreateInfo` structure containing parameters to be used to create the image.
- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.
- `pImage` points to a `VkImage` handle in which the resulting image object is returned.

The `VkImageCreateInfo` structure is defined as:

    typedef struct VkImageCreateInfo {
        VkStructureType          sType;
        const void*              pNext;
        VkImageCreateFlags       flags;
        VkImageType              imageType;
        VkFormat                 format;
        VkExtent3D               extent;
        uint32_t                 mipLevels;
        uint32_t                 arrayLayers;
        VkSampleCountFlagBits    samples;
        VkImageTiling            tiling;
        VkImageUsageFlags        usage;
        VkSharingMode            sharingMode;
        uint32_t                 queueFamilyIndexCount;
        const uint32_t*          pQueueFamilyIndices;
        VkImageLayout            initialLayout;
    } VkImageCreateInfo;

- `sType` is the type of this structure.
- `pNext` is `NULL` or a pointer to an extension-specific structure.
- `flags` is a bitmask describing additional parameters of the image. See `VkImageCreateFlagBits` below for a description of the supported bits.
- `imageType` is a `VkImageType` specifying the basic dimensionality of the image, as described below. Layers in array textures do not count as a dimension for the purposes of the image type.
- `format` is a `VkFormat` describing the format and type of the data elements that will be contained in the image.
- `extent` is a `VkExtent3D` describing the number of data elements in each dimension of the base level.
- `mipLevels` describes the number of levels of detail available for minified sampling of the image.
- `arrayLayers` is the number of layers in the image.
- `samples` is the number of sub-data element samples in the image as defined in `VkSampleCountFlagBits`. See Multisampling.
- `tiling` is a `VkImageTiling` specifying the tiling arrangement of the data elements in memory, as described below.
- `usage` is a bitmask describing the intended usage of the image. See `VkImageUsageFlagBits` below for a description of the supported bits.
- `sharingMode` is the sharing mode of the image when it will be accessed by multiple queue families, and must be one of the values described for `VkSharingMode` in the Resource Sharing section below.
- `queueFamilyIndexCount` is the number of entries in the `pQueueFamilyIndices` array.
- `pQueueFamilyIndices` is a list of queue families that will access this image (ignored if `sharingMode` is not `VK_SHARING_MODE_CONCURRENT`).
- `initialLayout` selects the initial `VkImageLayout` state of all image subresources of the image. See Image Layouts. `initialLayout` must be `VK_IMAGE_LAYOUT_UNDEFINED` or `VK_IMAGE_LAYOUT_PREINITIALIZED`.

Valid limits for the image `extent`, `mipLevels`, `arrayLayers` and `samples` members are queried with the `vkGetPhysicalDeviceImageFormatProperties` command.

Images created with `tiling` equal to `VK_IMAGE_TILING_LINEAR` have further restrictions on their limits and capabilities compared to images created with `tiling` equal to `VK_IMAGE_TILING_OPTIMAL`. Creation of images with tiling `VK_IMAGE_TILING_LINEAR` may not be supported unless other parameters meet all of the constraints:

- `imageType` is `VK_IMAGE_TYPE_2D`
- `format` is not a depth/stencil format
- `mipLevels` is 1
- `arrayLayers` is 1
- `samples` is `VK_SAMPLE_COUNT_1_BIT`
- `usage` only includes `VK_IMAGE_USAGE_TRANSFER_SRC_BIT` and/or `VK_IMAGE_USAGE_TRANSFER_DST_BIT`

Implementations may support additional limits and capabilities beyond those listed above. To determine the specific capabilities of an implementation, query the valid `usage` bits by calling `vkGetPhysicalDeviceFormatProperties` and the valid limits for `mipLevels` and `arrayLayers` by calling `vkGetPhysicalDeviceImageFormatProperties`.

The intended usage of an image is specified by the bitmask `VkImageCreateInfo`::`usage`. Bits which can be set include:

    typedef enum VkImageUsageFlagBits {
        VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001,
        VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002,
        VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004,
        VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008,
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010,
        VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,
        VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,
        VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,
    } VkImageUsageFlagBits;

These bits have the following meanings:

- `VK_IMAGE_USAGE_TRANSFER_SRC_BIT` indicates that the image can be used as the source of a transfer command.
- `VK_IMAGE_USAGE_TRANSFER_DST_BIT` indicates that the image can be used as the destination of a transfer command.
- `VK_IMAGE_USAGE_SAMPLED_BIT` indicates that the image can be used to create a `VkImageView` suitable for occupying a `VkDescriptorSet` slot either of type `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE` or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and be sampled by a shader.
- `VK_IMAGE_USAGE_STORAGE_BIT` indicates that the image can be used to create a `VkImageView` suitable for occupying a `VkDescriptorSet` slot of type `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`.
- `VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT` indicates that the image can be used to create a `VkImageView` suitable for use as a color or resolve attachment in a `VkFramebuffer`.
- `VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT` indicates that the image can be used to create a `VkImageView` suitable for use as a depth/stencil attachment in a `VkFramebuffer`.
- `VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT` indicates that the memory bound to this image will have been allocated with the `VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT` (see Chapter 10, Memory Allocation for more detail). This bit can be set for any image that can be used to create a `VkImageView` suitable for use as a color, resolve, depth/stencil, or input attachment.
- `VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT` indicates that the image can be used to create a `VkImageView` suitable for occupying `VkDescriptorSet` slot of type `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`; be read from a shader as an input attachment; and be used as an input attachment in a framebuffer.

Additional parameters of an image are specified by `VkImageCreateInfo`::`flags`. Bits which can be set include:

    typedef enum VkImageCreateFlagBits {
        VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001,
        VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
        VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
        VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
        VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
    } VkImageCreateFlagBits;

These bits have the following meanings:

- `VK_IMAGE_CREATE_SPARSE_BINDING_BIT` indicates that the image will be backed using sparse memory binding.
- `VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT` indicates that the image can be partially backed using sparse memory binding. Images created with this flag must also be created with the `VK_IMAGE_CREATE_SPARSE_BINDING_BIT` flag.
- `VK_IMAGE_CREATE_SPARSE_ALIASED_BIT` indicates that the image will be backed using sparse memory binding with memory ranges that might also simultaneously be backing another image (or another portion of the same image). Images created with this flag must also be created with the `VK_IMAGE_CREATE_SPARSE_BINDING_BIT` flag
- `VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT` indicates that the image can be used to create a `VkImageView` with a different format from the image.
- `VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT` indicates that the image can be used to create a `VkImageView` of type `VK_IMAGE_VIEW_TYPE_CUBE` or `VK_IMAGE_VIEW_TYPE_CUBE_ARRAY`.

If any of the bits `VK_IMAGE_CREATE_SPARSE_BINDING_BIT`, `VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT`, or `VK_IMAGE_CREATE_SPARSE_ALIASED_BIT` are set, `VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT` must not also be set.

See Sparse Resource Features and Sparse Physical Device Features for more details.

The basic dimensionality of an image is specified by `VkImageCreateInfo`::`imageType`, which must be one of the values

    typedef enum VkImageType {
        VK_IMAGE_TYPE_1D = 0,
        VK_IMAGE_TYPE_2D = 1,
        VK_IMAGE_TYPE_3D = 2,
    } VkImageType;

These values specify one-, two-, or three-dimensional images, respectively.

The tiling arrangement of data elements in an image is specified by `VkImageCreateInfo`::`tiling`, which must be one of the values

    typedef enum VkImageTiling {
        VK_IMAGE_TILING_OPTIMAL = 0,
        VK_IMAGE_TILING_LINEAR = 1,
    } VkImageTiling;

`VK_IMAGE_TILING_OPTIMAL` specifies optimal tiling (texels are laid out in an implementation-dependent arrangement, for more optimal memory access), and `VK_IMAGE_TILING_LINEAR` specifies linear tiling (texels are laid out in memory in row-major order, possibly with some padding on each row).

To query the host access layout of an image subresource, for an image created with linear tiling, call:

    void vkGetImageSubresourceLayout(
        VkDevice                                    device,
        VkImage                                     image,
        const VkImageSubresource*                   pSubresource,
        VkSubresourceLayout*                        pLayout);

- `device` is the logical device that owns the image.
- `image` is the image whose layout is being queried.
- `pSubresource` is a pointer to a `VkImageSubresource` structure selecting a specific image for the image subresource.
- `pLayout` points to a `VkSubresourceLayout` structure in which the layout is returned.

`vkGetImageSubresourceLayout` is invariant for the lifetime of a single image.

The `VkImageSubresource` structure is defined as:

    typedef struct VkImageSubresource {
        VkImageAspectFlags    aspectMask;
        uint32_t              mipLevel;
        uint32_t              arrayLayer;
    } VkImageSubresource;

- `aspectMask` is a `VkImageAspectFlags` selecting the image aspect.
- `mipLevel` selects the mipmap level.
- `arrayLayer` selects the array layer.

Information about the layout of the image subresource is returned in a `VkSubresourceLayout` structure:

    typedef struct VkSubresourceLayout {
        VkDeviceSize    offset;
        VkDeviceSize    size;
        VkDeviceSize    rowPitch;
        VkDeviceSize    arrayPitch;
        VkDeviceSize    depthPitch;
    } VkSubresourceLayout;

- `offset` is the byte offset from the start of the image where the image subresource begins.
- `size` is the size in bytes of the image subresource. `size` includes any extra memory that is required based on `rowPitch`.
- `rowPitch` describes the number of bytes between each row of texels in an image.
- `arrayPitch` describes the number of bytes between each array layer of an image.
- `depthPitch` describes the number of bytes between each slice of 3D image.

For images created with linear tiling, `rowPitch`, `arrayPitch` and `depthPitch` describe the layout of the image subresource in linear memory. For uncompressed formats, `rowPitch` is the number of bytes between texels with the same x coordinate in adjacent rows (y coordinates differ by one). `arrayPitch` is the number of bytes between texels with the same x and y coordinate in adjacent array layers of the image (array layer values differ by one). `depthPitch` is the number of bytes between texels with the same x and y coordinate in adjacent slices of a 3D image (z coordinates differ by one). Expressed as an addressing formula, the starting byte of a texel in the image subresource has address:

    // (x,y,z,layer) are in texel coordinates
    address(x,y,z,layer) = layer*arrayPitch + z*depthPitch + y*rowPitch + x*elementSize + offset

For compressed formats, the `rowPitch` is the number of bytes between compressed texel blocks in adjacent rows. `arrayPitch` is the number of bytes between compressed texel blocks in adjacent array layers. `depthPitch` is the number of bytes between compressed texel blocks in adjacent slices of a 3D image.

    // (x,y,z,layer) are in compressed texel block coordinates
    address(x,y,z,layer) = layer*arrayPitch + z*depthPitch + y*rowPitch + x*compressedTexelBlockByteSize + offset;

`arrayPitch` is undefined for images that were not created as arrays. `depthPitch` is defined only for 3D images.

For color formats, the `aspectMask` member of `VkImageSubresource` must be `VK_IMAGE_ASPECT_COLOR_BIT`. For depth/stencil formats, `aspectMask` must be either `VK_IMAGE_ASPECT_DEPTH_BIT` or `VK_IMAGE_ASPECT_STENCIL_BIT`. On implementations that store depth and stencil aspects separately, querying each of these image subresource layouts will return a different `offset` and `size` representing the region of memory used for that aspect. On implementations that store depth and stencil aspects interleaved, the same `offset` and `size` are returned and represent the interleaved memory allocation.

To destroy an image, call:

    void vkDestroyImage(
        VkDevice                                    device,
        VkImage                                     image,
        const VkAllocationCallbacks*                pAllocator);

- `device` is the logical device that destroys the image.
- `image` is the image to destroy.
- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.