18.5. Image Copies with Scaling

To copy regions of a source image into a destination image, potentially performing format conversion, arbitrary scaling, and filtering, call:


void vkCmdBlitImage(
    VkCommandBuffer                             commandBuffer,
    VkImage                                     srcImage,
    VkImageLayout                               srcImageLayout,
    VkImage                                     dstImage,
    VkImageLayout                               dstImageLayout,
    uint32_t                                    regionCount,
    const VkImageBlit*                          pRegions,
    VkFilter                                    filter);

vkCmdBlitImage must not be used for multisampled source or destination images. Use vkCmdResolveImage for this purpose.

As the sizes of the source and destination extents can differ in any dimension, texels in the source extent are scaled and filtered to the destination extent. Scaling occurs via the following operations:

\begin{align*} u_{base} & = i + \frac{1}{2}\\ v_{base} & = j + \frac{1}{2}\\ w_{base} & = k + \frac{1}{2}\\ \end{align*}
\begin{align*} u_{offset} & = u_{base} - x_{dst_0}\\ v_{offset} & = v_{base} - y_{dst_0}\\ w_{offset} & = w_{base} - z_{dst_0}\\ a_{offset} & = a - baseArrayCount_{dst} \end{align*}
\begin{align*} scale_u & = \frac{x_{src_1} - x_{src_0}}{x_{dst_1} - x_{dst_0}}\\ scale_v & = \frac{y_{src_1} - y_{src_0}}{y_{dst_1} - y_{dst_0}}\\ scale_w & = \frac{z_{src_1} - z_{src_0}}{z_{dst_1} - z_{dst_0}}\\ \\ u_{scaled} & = u_{offset} * scale_u\\ v_{scaled} & = v_{offset} * scale_v\\ w_{scaled} & = w_{offset} * scale_w \end{align*}
\begin{align*} u & = u_{scaled} + x_{src_0}\\ v & = v_{scaled} + y_{src_0}\\ w & = w_{scaled} + z_{src_0}\\ q & = mipLevel\\ a & = a_{offset} + baseArrayCount_{src} \end{align*}

These coordinates are used to sample from the source image, as described in Image Operations chapter, with the filter mode equal to that of filter, a mipmap mode of VK_SAMPLER_MIPMAP_MODE_NEAREST and an address mode of VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. Implementations must clamp at the edge of the source image, and may additionally clamp to the edge of the source region.


Due to allowable rounding errors in the generation of the source texture coordinates, it is not always possible to guarantee exactly which source texels will be sampled for a given blit. As rounding errors are implementation dependent, the exact results of a blitting operation are also implementation dependent.

Blits are done layer by layer starting with the baseArrayLayer member of srcSubresource for the source and dstSubresource for the destination. layerCount layers are blitted to the destination image.

3D textures are blitted slice by slice. Slices in the source region bounded by srcOffsets[0].z and srcOffsets[1].z are copied to slices in the destination region bounded by dstOffsets[0].z and dstOffsets[1].z. For each destination slice, a source z coordinate is linearly interpolated between srcOffsets[0].z and srcOffsets[1].z. If the filter parameter is VK_FILTER_LINEAR then the value sampled from the source image is taken by doing linear filtering using the interpolated z coordinate. If filter parameter is VK_FILTER_NEAREST then value sampled from the source image is taken from the single nearest slice (with undefined rounding mode).

The following filtering and conversion rules apply:

Signed and unsigned integers are converted by first clamping to the representable range of the destination format, then casting the value.

The VkImageBlit structure is defined as:


typedef struct VkImageBlit {
    VkImageSubresourceLayers    srcSubresource;
    VkOffset3D                  srcOffsets[2];
    VkImageSubresourceLayers    dstSubresource;
    VkOffset3D                  dstOffsets[2];
} VkImageBlit;

For each element of the pRegions array, a blit operation is performed the specified source and destination regions.