Copy Commands

An application can copy buffer and image data using several methods described in this chapter, depending on the type of data transfer.

All copy commands are treated as transfer operations for the purposes of synchronization barriers.

All copy commands that have a source format with an X component in its format description read undefined: values from those bits.

All copy commands that have a destination format with an X component in its format description write undefined: values to those bits.

Copying Data Between Buffers

vkCmdCopyBufferCopy data between buffer regions
VkBufferCopyStructure specifying a buffer copy operation

A more extensible version of the copy buffer command is defined below.

vkCmdCopyBuffer2Copy data between buffer regions
VkCopyBufferInfo2Structure specifying parameters of a buffer copy command
VkBufferCopy2Structure specifying a buffer copy operation

Copying Data Between Images

vkCmdCopyImageCopy data between images
VkImageCopyStructure specifying an image copy operation
VkImageSubresourceLayersStructure specifying an image subresource layers

A more extensible version of the copy image command is defined below.

vkCmdCopyImage2Copy data between images
VkCopyImageInfo2Structure specifying parameters of an image copy command
VkImageCopy2Structure specifying an image copy operation

Copying Data Between Buffers and Images

Data can be copied between buffers and images, enabling applications to load and store data between images and user defined offsets in buffer memory.

When copying between a buffer and an image, whole texel blocks are always copied; each texel block in the specified extent in the image to be copied will be written to a region in the buffer, specified according to the position of the texel block, and the texel block extent and size of the format being copied.

For a set of coordinates (x,y,z,layer), where:

x is in the range [imageOffset.x / blockWidth, ⌈(imageOffset.x + imageExtent.width) / blockWidth⌉),

y is in the range [imageOffset.y / blockHeight, ⌈(imageOffset.y + imageExtent.height) / blockHeight⌉),

z is in the range [imageOffset.z / blockDepth, ⌈(imageOffset.z + imageExtent.depth) / blockDepth⌉),

layer

and where blockWidth, blockHeight, and blockDepth are the dimensions of the texel block extent of the image’s format.

For each (x,y,z,layer) coordinate, texels in the image layer selected by layer are accessed in the following ranges:

[x × blockWidth, max( (x × blockWidth) + blockWidth, imageWidth) )[y × blockHeight, max( (y × blockHeight) + blockHeight, imageHeight) )[z × blockDepth, max( (z × blockDepth) + blockDepth, imageDepth) )

where imageWidth, imageHeight, and imageDepth are the dimensions of the image subresource.

For each (x,y,z,layer) coordinate, bytes in the buffer are accessed at offsets in the range [texelOffset, texelOffset + blockSize), where:

texelOffset = bufferOffset + (x × blockSize) + (y × rowExtent) + (z × sliceExtent) + (layer × layerExtent)blockSizerowExtent = max(bufferRowLength, ⌈imageExtent.width / blockWidth⌉ × blockSize)sliceExtent = max(bufferImageHeight, imageExtent.height × rowExtent)layerExtent = imageExtent.depth × sliceExtent

If a rotation is specified by VkCopyCommandTransformInfoQCOM, the 2D region of the image being addressed is rotated around the offset, modifying the range of x and y coordinates for the image address according to the specified VkSurfaceTransformFlagBitsKHR:

  • If VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR is specified, no rotation is performed:

    x' is in the same range as x

    y' is in the same range as y
    blockWidth' = blockWidth
    blockHeight' = blockHeight
    imageWidth' = imageWidth
    imageHeight' = imageHeight
  • If VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR is specified

    x' is in the range [⌈(imageOffset.x - imageExtent.height) / blockHeight⌉, imageOffset.x - image/ blockHeight)

    y' is in the range [imageOffset.y / blockWidth, ⌈(imageOffset.y + imageExtent.width) / blockWidth⌉)
    blockWidth' = blockHeight
    blockHeight' = blockWidth
    imageWidth' = imageHeight
    imageHeight' = imageWidth
  • If VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR is specified:

    x' is in the range [⌈(imageOffset.x - imageExtent.width) / blockWidth⌉, imageOffset.x / blockWidth),

    y' is in the range [⌈(imageOffset.x + imageExtent.height) / blockHeight⌉, imageOffset.x / blockHeight),
    blockWidth' = blockWidth
    blockHeight' = blockHeight
    imageWidth' = imageWidth
    imageHeight' = imageHeight
  • If VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR is specified:

    x is in the range [imageOffset.x / blockHeight, ⌈(imageOffset.x + imageExtent.height) / blockHeight⌉)

    y is in the range [⌈(imageOffset.y - imageExtent.width) / blockWidth⌉, imageOffset.y / blockWidth).
    blockWidth' = blockHeight
    blockHeight' = blockWidth
    imageWidth' = imageHeight
    imageHeight' = imageWidth

When rotation is performed, for each (x,y,z,layer) coordinate, texels in the image layer selected by layer are instead accessed in the following ranges:

[x' × blockWidth', max( (x' × blockWidth') + blockWidth', imageWidth') )[y' × blockHeight', max( (y' × blockHeight') + blockHeight', imageHeight') )[z' × blockDepth', max( (z' × blockDepth') + blockDepth', imageDepth') )

Buffer addressing calculations are unaffected by this rotation.

When copying between a buffer and the depth or stencil aspect of an image, data in the buffer is assumed to be laid out as separate planes rather than interleaved. Addressing calculations are thus performed for a different format than the base image, according to the aspect, as described in the following table:

When copying between a buffer and any plane of a multi-planar image, addressing calculations are performed using the compatible format for that plane, rather than the format of the multi-planar image.

Each texel block is copied from one resource to the other according to the above addressing equations.

vkCmdCopyBufferToImageCopy data from a buffer into an image
vkCmdCopyImageToBufferCopy image data into a buffer
VkBufferImageCopyStructure specifying a buffer image copy operation

More extensible versions of the commands to copy between buffers and images are defined below.

vkCmdCopyBufferToImage2Copy data from a buffer into an image
VkCopyBufferToImageInfo2Structure specifying parameters of a buffer to image copy command
vkCmdCopyImageToBuffer2Copy image data into a buffer
VkCopyImageToBufferInfo2Structure specifying parameters of an image to buffer copy command
VkBufferImageCopy2Structure specifying a buffer image copy operation
VkCopyCommandTransformInfoQCOMStructure describing transform parameters of rotated copy command

The following commands can be used to copy between host memory and images.

vkCopyMemoryToImageEXTCopy data from host memory into an image
VkCopyMemoryToImageInfoEXTStructure specifying parameters of host memory to image copy command
VkMemoryToImageCopyEXTStructure specifying a host memory to image copy operation
vkCopyImageToMemoryEXTCopy image data into host memory
VkCopyImageToMemoryInfoEXTStructure specifying parameters of an image to host memory copy command
VkImageToMemoryCopyEXTStructure specifying an image to host memory copy operation
VkHostImageCopyFlagBitsEXTBitmask specifying additional copy parameters
VkHostImageCopyFlagsEXTBitmask of VkHostImageCopyFlagBitsEXT
vkCopyImageToImageEXTCopy image data using the host
VkCopyImageToImageInfoEXTStructure specifying parameters of an image to image host copy command

Indirect Copies

An application can use indirect copies when the copy parameters are not known during the command buffer creation time.

vkCmdCopyMemoryIndirectNVCopy data between memory regions
VkCopyMemoryIndirectCommandNVStructure specifying indirect memory region copy operation
vkCmdCopyMemoryToImageIndirectNVCopy data from a memory region into an image
VkCopyMemoryToImageIndirectCommandNVStructure specifying indirect buffer image copy operation

Image Copies With Scaling

vkCmdBlitImageCopy regions of an image, potentially performing format conversion,
VkImageBlitStructure specifying an image blit operation

A more extensible version of the blit image command is defined below.

vkCmdBlitImage2Copy regions of an image, potentially performing format conversion,
VkBlitImageInfo2Structure specifying parameters of blit image command

If filter is VK_FILTER_CUBIC_EXT and if the pNext chain of VkBlitImageInfo2 includes a VkBlitImageCubicWeightsInfoQCOM structure, then that structure specifies cubic weights are used in the blit. If that structure is not present, then cubic weights are considered to be VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM.

VkBlitImageCubicWeightsInfoQCOMStructure specifying image blit cubic weight info
VkImageBlit2Structure specifying an image blit operation

For vkCmdBlitImage2, each region copied can include a rotation. To specify a rotated region, add VkCopyCommandTransformInfoQCOM to the pNext chain of VkImageBlit2. For each region with a rotation specified, Image Blits with Scaling and Rotation specifies how coordinates are rotated prior to sampling from the source image. When rotation is specified, the source and destination images must each be 2D images, have a 1x1x1 texel block extent, and only one plane.

Image Blits With Scaling and Rotation

When VkCopyCommandTransformInfoQCOM is in the pNext chain of VkImageBlit2, the specified region is rotated during the blit. The following description of rotated addressing replaces the description in vkCmdBlitImage.

The following code computes rotation of normalized coordinates.

  • 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 UV destination coordinates are scaled by the destination region, rotated, and scaled by the source region.
    udest_scaled = uoffset / (xdst1 - xdst0)
    vdest_scaled = voffset / (ydst1 - ydst0)
    (usrc_scaled, vsrc_scaled) = RotateNormUV(udest_scaled, vdest_scaled, transform)
    uscaled = usrc_scaled × (xSrc1 - xSrc0)
    vscaled = vsrc_scaled × (ySrc1 - ySrc0)
  • The W coordinate is unaffected by rotation. The scale is determined from the ratio of source and destination regions, and applied to the offset coordinate:
    scalew = (zSrc1 - zSrc0) / (zdst1 - zdst0)
    wscaled = woffset × scalew
  • Finally the source offset is added to the scaled source 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 for Image Operations, 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.

Resolving Multisample Images

vkCmdResolveImageResolve regions of an image
VkImageResolveStructure specifying an image resolve operation

A more extensible version of the resolve image command is defined below.

vkCmdResolveImage2Resolve regions of an image
VkResolveImageInfo2Structure specifying parameters of resolve image command
VkImageResolve2Structure specifying an image resolve operation

Buffer Markers

vkCmdWriteBufferMarker2AMDExecute a pipelined write of a marker value into a buffer
vkCmdWriteBufferMarkerAMDExecute a pipelined write of a marker value into a buffer