blob: 7e13f219ee671efde1df49aaa3690a3afaf51978 [file] [log] [blame]
// Copyright (c) 2020 Qualcomm Technologies Incorporated
//
// SPDX-License-Identifier: CC-BY-4.0
[[copies-buffers-images-rotation-addressing]]
=== Buffer and Image Addressing with Rotation
When slink:VkCopyCommandTransformInfoQCOM is in the pname:pNext chain of
slink:VkBufferImageCopy2KHR, a _rotated copy_ is specified.
For both flink:vkCmdCopyImageToBuffer2KHR and
flink:vkCmdCopyBufferToImage2KHR, a rotation is applied to the region used
for image accesses, but a non-rotated region is used for buffer accesses.
In the case of rotated flink:vkCmdCopyImageToBuffer2KHR, the source image
region is rotated.
In the case of rotated flink:vkCmdCopyBufferToImage2KHR, the destination
image region is rotated.
For a _rotated copy_, the following description of rotated addressing
replaces the description in <<copies-buffers-images-addressing,Buffer and
Image Addressing>>.
The following code computes rotation of unnormalized coordinates.
[source,c]
---------------------------------------------------
// Forward rotation of unnormalized coordinates
VkOffset2D RotateUV(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 = in.x;
break;
case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
out.x = -in.x;
out.y = -in.y;
break;
case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
out.x = in.y;
out.y = -in.x;
break;
}
return out;
}
---------------------------------------------------
Pseudocode for image/buffer addressing of uncompressed formats with rotation
is:
[source,c]
---------------------------------------------------
rowLength = region->bufferRowLength;
if (rowLength == 0)
rowLength = region->imageExtent.width;
imageHeight = region->bufferImageHeight;
if (imageHeight == 0)
imageHeight = region->imageExtent.height;
texelBlockSize = <texel block size of the format of the src/dstImage>;
// Buffer addressing is unaffected by rotation:
address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelBlockSize;
// When copying from buffer to image, the source buffer coordinates x,y,z range from (0,0,0) to
// region->imageExtent.{width,height,depth}. The source extent is rotated by the specified
// VK_SURFACE_TRANSFORM, centered on the imageOffset, to define a rotated destination region.
// For each source buffer texel with coordinates (x,y) the rotated destination image texel has
// coordinates (x',y') defined as:
(x',y')= RotateUV(x,y) + ImageOffset.{x,y}
// When copying from image to buffer, the the destination buffer coordinates x,y,z range from (0,0,0) to
// region->imageExtent.{width,height,depth}. The destination extent is rotated by the specified
// VK_SURFACE_TRANSFORM, centered on the imageOffset, to define a rotated source region. For each destination
// buffer texel with coordinates (x,y) the rotated source image texel has coordinates (x',y') defined as:
(x',y')= RotateUV(x,y) + ImageOffset.{x,y}
---------------------------------------------------
Note that pname:imageOffset does not affect addressing calculations for
buffer memory.
Instead, pname:bufferOffset can: be used to select the starting address in
buffer memory.