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
A more extensible version of the copy buffer command is defined below.
Copying Data Between Images
A more extensible version of the copy image command is defined below.
Copying Data Between Buffers and Images
Data can be copied between buffers and images, enabling applications to load and store data between images and application-defined offsets in buffer memory.
When copying between a buffer and an image, texels in the image and bytes in the buffer are accessed as follows.
Texels at each coordinate (x,y,z,layer) in the image subresource are accessed, where:
- x is in the range [
imageOffset.x
,imageOffset.x
+imageExtent.width
), - y is in the range [
imageOffset.y
,imageOffset.y
+imageExtent.height
), - z is in the range [
imageOffset.z
,imageOffset.z
+imageExtent.depth
), - layer is in the range
[eq]#[
imageSubresource.baseArrayLayer
,imageSubresource.baseArrayLayer
+imageSubresource.layerCount
)
For each (x,y,z,layer) coordinate in the image, bytes in the buffer are accessed at offsets in the range [texelOffset, texelOffset + blockSize), where:
- texelOffset =
bufferOffset
+ (⌊x / blockWidth⌋ × blockSize) + (⌊y / blockHeight⌋ × rowExtent) + (⌊z / blockDepth⌋ × sliceExtent) + (layer × layerExtent) - rowExtent = ⌈ max(
bufferRowLength
,imageExtent.width
) / blockWidth ⌉ × blockSize - sliceExtent = ⌈ max(
bufferImageHeight
,imageExtent.height
) / blockHeight ⌉ × rowExtent - layerExtent = ⌈
imageExtent.depth
/ blockDepth ⌉ × sliceExtent
and where blockSize, blockWidth, blockHeight, and blockDepth are the texel block size and extents of the image’s format.
If a rotation is specified by VkCopyCommandTransformInfoQCOM, the 2D region of the image being addressed is rotated around the offset, and texels at each coordinate (x',y',z',layer) are accessed in the image subresource instead, where:
- 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
- If
VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR
is specified- x' is in the range [
imageOffset.x
-imageExtent.height
,imageOffset.x
) - y' is in the range [
imageOffset.y
,imageOffset.y
+imageExtent.width
)
- x' is in the range [
- If
VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR
is specified:- x' is in the range [
imageOffset.x
-imageExtent.width
,imageOffset.x
) - y' is in the range [
imageOffset.y
-imageExtent.height
,imageOffset.y
)
- x' is in the range [
- If
VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR
is specified:- x' is in the range [
imageOffset.x
,imageOffset.x
+imageExtent.height
) - y' is in the range [
imageOffset.y
-imageExtent.width
,imageOffset.y
)
- x' is in the range [
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:
Base Format | Depth Aspect Format | Stencil Aspect Format |
---|---|---|
- | ||
- | ||
- | ||
- | ||
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.
More extensible versions of the commands to copy between buffers and images are defined below.
The following commands can be used to copy between host memory and images.
Indirect Copies
An application can use indirect copies when the copy parameters are not known during the command buffer creation time.
Image Copies With Scaling
A more extensible version of the blit image command is defined below.
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
.
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.
// rotation of normalized coordinates
VkOffset2D RotateNormUV(VkOffset2D in, VkSurfaceTransformFlagBitsKHR flags)
{
VkOffset2D output;
switch (flags)
{
case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
out.x = in.x;
out.y = in.y;
break;
case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
out.x = in.y;
out.y = 1.0 - in.x;
break;
case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
out.x = 1.0 - in.x;
out.y = 1.0 - in.y;
break;
case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
out.x = 1.0 - in.y;
out.y = in.x;
break;
}
return out;
}
- 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 -
baseArrayCount
dst
- 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 +
baseArrayCount
src
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
A more extensible version of the resolve image command is defined below.