## 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);

- `commandBuffer` is the command buffer into which the command will be recorded.
- `srcImage` is the source image.
- `srcImageLayout` is the layout of the source image subresources for the blit.
- `dstImage` is the destination image.
- `dstImageLayout` is the layout of the destination image subresources for the blit.
- `regionCount` is the number of regions to blit.
- `pRegions` is a pointer to an array of `VkImageBlit` structures specifying the regions to blit.
- `filter` is a `VkFilter` specifying the filter to apply if the blits require scaling.

`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:

- For each destination texel, the integer coordinate of that texel is converted to an unnormalized texture coordinate, using the effective inverse of the equations described in unnormalized to integer conversion:

\begin{align*} u_{base} & = i + \frac{1}{2}\\ v_{base} & = j + \frac{1}{2}\\ w_{base} & = k + \frac{1}{2}\\ \end{align*}

- These base coordinates are then offset by the first destination offset:

\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*}

- The scale is determined from the source and destination regions, and applied to the offset coordinates:

\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*}

- Finally the source offset is added to the scaled coordinates, to determine the final unnormalized coordinates used to sample from `srcImage`:

\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.

| Note
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:

- Integer formats can only be converted to other integer formats with the same signedness.
- No format conversion is supported between depth/stencil images - the formats must match.
- Format conversions on unorm, snorm, unscaled and packed float formats of the copied aspect of the image are performed by first converting the pixels to float values.
- In case of sRGB source format, nonlinear RGB values are converted to linear representation prior to filtering.
- After filtering, the float values are first clamped and then cast to the destination image format. In case of sRGB destination format, linear RGB values are converted to nonlinear representation before writing the pixel to the image.

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;

- `srcSubresource` is the subresource to blit from.
- `srcOffsets` is an array of two `VkOffset3D` structures specifying the bounds of the source region within `srcSubresource`.
- `dstSubresource` is the subresource to blit into.
- `dstOffsets` is an array of two `VkOffset3D` structures specifying the bounds of the destination region within `dstSubresource`.

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