## C Specification

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

## Parameters

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

## Description

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:

ubase = i + ½

vbase = j + ½

wbase = k + ½

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

uoffset = ubase - xdst0

voffset = vbase - ydst0

woffset = wbase - zdst0

aoffset = a - baseArrayCountdst

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

scale_u = (xsrc1 - xsrc0) / (xdst1 - xdst0)

scale_v = (ysrc1 - ysrc0) / (ydst1 - ydst0)

scale_w = (zsrc1 - zsrc0) / (zdst1 - zdst0)

uscaled = uoffset * scaleu

vscaled = voffset * scalev

wscaled = woffset * scalew

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

u = uscaled + xsrc0

v = vscaled + ysrc0

w = wscaled + zsrc0

q = mipLevel

a = aoffset + baseArrayCountsrc

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 the value sampled from the source image is taken from the single nearest slice, with an implementation-dependent arithmetic 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.

• For sRGB source formats, 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.

Valid Usage
• The source region specified by each element of pRegions must be a region that is contained within srcImage

• The destination region specified by each element of pRegions must be a region that is contained within dstImage

• The union of all destination regions, specified by the elements of pRegions, must not overlap in memory with any texel that may be sampled during the blit operation

• The format features of srcImage must contain VK_FORMAT_FEATURE_BLIT_SRC_BIT.

• srcImage must not use a format listed in https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#formats-requiring-sampler-ycbcr-conversion

• srcImage must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag

• If srcImage is non-sparse then it must be bound completely and contiguously to a single VkDeviceMemory object

• srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice

• srcImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

• The format features of dstImage must contain VK_FORMAT_FEATURE_BLIT_DST_BIT.

• dstImage must not use a format listed in https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#formats-requiring-sampler-ycbcr-conversion

• dstImage must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag

• If dstImage is non-sparse then it must be bound completely and contiguously to a single VkDeviceMemory object

• dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice

• dstImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

• The sample count of srcImage and dstImage must both be equal to VK_SAMPLE_COUNT_1_BIT

• If either of srcImage or dstImage was created with a signed integer VkFormat, the other must also have been created with a signed integer VkFormat

• If either of srcImage or dstImage was created with an unsigned integer VkFormat, the other must also have been created with an unsigned integer VkFormat

• If either of srcImage or dstImage was created with a depth/stencil format, the other must have exactly the same format

• If srcImage was created with a depth/stencil format, filter must be VK_FILTER_NEAREST

• srcImage must have been created with a samples value of VK_SAMPLE_COUNT_1_BIT

• dstImage must have been created with a samples value of VK_SAMPLE_COUNT_1_BIT

• If filter is VK_FILTER_LINEAR, then the format features of srcImage must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

• If filter is VK_FILTER_CUBIC_EXT, then the format features of srcImage must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT.

• If filter is VK_FILTER_CUBIC_EXT, srcImage must have a VkImageType of VK_IMAGE_TYPE_2D

• If commandBuffer is an unprotected command buffer, then srcImage must not be a protected image

• If commandBuffer is an unprotected command buffer, then dstImage must not be a protected image

• If commandBuffer is a protected command buffer, then dstImage must not be an unprotected image

• The srcSubresource.mipLevel member of each element of pRegions must be less than the mipLevels specified in VkImageCreateInfo when srcImage was created

• The dstSubresource.mipLevel member of each element of pRegions must be less than the mipLevels specified in VkImageCreateInfo when dstImage was created

• The srcSubresource.baseArrayLayer + srcSubresource.layerCount of each element of pRegions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when srcImage was created

• The dstSubresource.baseArrayLayer + dstSubresource.layerCount of each element of pRegions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when dstImage was created

• dstImage and srcImage must not have been created with flags containing VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT

Valid Usage (Implicit)
• commandBuffer must be a valid VkCommandBuffer handle

• srcImage must be a valid VkImage handle

• srcImageLayout must be a valid VkImageLayout value

• dstImage must be a valid VkImage handle

• dstImageLayout must be a valid VkImageLayout value

• pRegions must be a valid pointer to an array of regionCount valid VkImageBlit structures

• filter must be a valid VkFilter value

• commandBuffer must be in the recording state

• The VkCommandPool that commandBuffer was allocated from must support graphics operations

• This command must only be called outside of a render pass instance

• regionCount must be greater than 0

• Each of commandBuffer, dstImage, and srcImage must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
• Host access to commandBuffer must be externally synchronized

• Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Outside

Graphics

Transfer