Skip to content

Commit 4d7bbd6

Browse files
authored
Implement dkCmdBufCopyImageToBuffer and dkCmdBufCopyImage (#11)
1 parent 8939ff8 commit 4d7bbd6

1 file changed

Lines changed: 155 additions & 2 deletions

File tree

source/dk_image.cpp

Lines changed: 155 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,47 @@ DkGpuAddr dkImageGetGpuAddr(DkImage const* obj)
505505

506506
void dkCmdBufCopyImage(DkCmdBuf obj, DkImageView const* srcView, DkImageRect const* srcRect, DkImageView const* dstView, DkImageRect const* dstRect, uint32_t flags)
507507
{
508-
DK_ENTRYPOINT_NOT_IMPLEMENTED(obj);
508+
DK_ENTRYPOINT(obj);
509+
510+
ImageInfo srcInfo, dstInfo;
511+
srcInfo.fromImageView(srcView, ImageInfo::TransferCopy);
512+
dstInfo.fromImageView(dstView, ImageInfo::TransferCopy);
513+
514+
[[maybe_unused]] const bool isSrcTexCompressed = srcView->pImage->m_blockW > 1;
515+
[[maybe_unused]] const bool isDstTexCompressed = dstView->pImage->m_blockW > 1;
516+
DK_DEBUG_BAD_INPUT(isSrcTexCompressed != isDstTexCompressed, "mismatched compression attributes");
517+
DK_DEBUG_BAD_INPUT(isSrcTexCompressed && srcInfo.m_format != dstInfo.m_format, "compression formats must match");
518+
519+
DK_DEBUG_BAD_INPUT(!srcRect || !srcRect->width || !srcRect->height || !srcRect->depth, "invalid srcRect");
520+
DK_DEBUG_BAD_INPUT(srcRect->x + srcRect->width > srcView->pImage->m_dimensions[0], "srcRect x/width out of bounds");
521+
DK_DEBUG_BAD_INPUT(srcRect->y + srcRect->height > srcView->pImage->m_dimensions[1], "srcRect y/height out of bounds");
522+
DK_DEBUG_BAD_INPUT(srcRect->z + srcRect->depth > srcInfo.m_arrayMode, "srcRect z/depth out of bounds");
523+
524+
DK_DEBUG_BAD_INPUT(!dstRect || !dstRect->width || !dstRect->height || !dstRect->depth, "invalid dstRect");
525+
DK_DEBUG_BAD_INPUT(dstRect->x + dstRect->width > dstView->pImage->m_dimensions[0], "dstRect x/width out of bounds");
526+
DK_DEBUG_BAD_INPUT(dstRect->y + dstRect->height > dstView->pImage->m_dimensions[1], "dstRect y/height out of bounds");
527+
DK_DEBUG_BAD_INPUT(dstRect->z + dstRect->depth > dstInfo.m_arrayMode, "dstRect z/depth out of bounds");
528+
529+
DK_DEBUG_BAD_INPUT(srcRect->width != dstRect->width, "srcRect/dstRect width must match");
530+
DK_DEBUG_BAD_INPUT(srcRect->height != dstRect->height, "srcRect/dstRect height must match");
531+
DK_DEBUG_BAD_INPUT(srcRect->depth != dstRect->depth, "srcRect/dstRect depth must match");
532+
533+
BlitParams params;
534+
params.srcX = srcRect->x;
535+
params.srcY = srcRect->y;
536+
params.dstX = dstRect->x;
537+
params.dstY = dstRect->y;
538+
params.width = srcRect->width;
539+
params.height = srcRect->height;
540+
541+
for (uint32_t z = 0; z < dstRect->depth; z ++)
542+
{
543+
uint32_t srcZ = z;
544+
uint32_t dstZ = dstRect->z + z;
545+
if (flags & DkBlitFlag_FlipZ)
546+
srcZ = dstRect->depth - z - 1;
547+
BlitCopyEngine(obj, srcInfo, dstInfo, params, srcZ, dstZ);
548+
}
509549
}
510550

511551
void dkCmdBufBlitImage(DkCmdBuf obj, DkImageView const* srcView, DkImageRect const* srcRect, DkImageView const* dstView, DkImageRect const* dstRect, uint32_t flags, uint32_t factor)
@@ -769,5 +809,118 @@ void dkCmdBufCopyBufferToImage(DkCmdBuf obj, DkCopyBuf const* src, DkImageView c
769809

770810
void dkCmdBufCopyImageToBuffer(DkCmdBuf obj, DkImageView const* srcView, DkImageRect const* srcRect, DkCopyBuf const* dst, uint32_t flags)
771811
{
772-
DK_ENTRYPOINT_NOT_IMPLEMENTED(obj);
812+
DK_ENTRYPOINT(obj);
813+
814+
ImageInfo srcInfo;
815+
srcInfo.fromImageView(srcView, ImageInfo::TransferCopy);
816+
817+
DK_DEBUG_BAD_INPUT(!dst || dst->addr == DK_GPU_ADDR_INVALID, "invalid dst");
818+
DK_DEBUG_BAD_INPUT(!srcRect || !srcRect->width || !srcRect->height || !srcRect->depth, "invalid dstView");
819+
DK_DEBUG_BAD_INPUT(srcRect->x + srcRect->width > srcView->pImage->m_dimensions[0], "srcRect x/width out of bounds");
820+
DK_DEBUG_BAD_INPUT(srcRect->y + srcRect->height > srcView->pImage->m_dimensions[1], "srcRect y/height out of bounds");
821+
DK_DEBUG_BAD_INPUT(srcRect->z + srcRect->depth > srcInfo.m_arrayMode, "srcRect z/depth out of bounds");
822+
823+
BlitParams params;
824+
params.srcX = srcRect->x;
825+
params.srcY = srcRect->y;
826+
params.dstX = 0;
827+
params.dstY = 0;
828+
params.width = srcRect->width;
829+
params.height = srcRect->height;
830+
831+
auto& traits = formatTraits[srcView->format ? srcView->format : srcView->pImage->m_format];
832+
const bool isCompressed = traits.blockWidth > 1 || traits.blockHeight > 1;
833+
834+
if (isCompressed)
835+
{
836+
// Horizontal/vertical flips can't be used with compressed formats for obvious reasons
837+
DK_DEBUG_BAD_FLAGS(flags & (DkBlitFlag_FlipX|DkBlitFlag_FlipY), "cannot use DkBlitFlag_FlipX/FlipY with compressed formats");
838+
839+
params.srcX = adjustBlockSize(params.srcX, traits.blockWidth);
840+
params.srcY = adjustBlockSize(params.srcY, traits.blockHeight);
841+
params.width = adjustBlockSize(params.width, traits.blockWidth);
842+
params.height = adjustBlockSize(params.height, traits.blockHeight);
843+
}
844+
845+
ImageInfo dstInfo = {};
846+
dstInfo.m_iova = dst->addr;
847+
dstInfo.m_horizontal = dst->rowLength ? dst->rowLength : params.width*srcInfo.m_bytesPerBlock;
848+
dstInfo.m_vertical = srcRect->height;
849+
dstInfo.m_format = srcInfo.m_format;
850+
dstInfo.m_arrayMode = srcRect->depth;
851+
dstInfo.m_layerStride = dst->imageHeight ? dst->imageHeight : params.height*dstInfo.m_horizontal;
852+
dstInfo.m_width = srcRect->width;
853+
dstInfo.m_height = srcRect->height;
854+
dstInfo.m_widthMs = dstInfo.m_width;
855+
dstInfo.m_heightMs = dstInfo.m_height;
856+
dstInfo.m_bytesPerBlock = srcInfo.m_bytesPerBlock;
857+
dstInfo.m_isLinear = true;
858+
dstInfo.m_isLayered = true;
859+
860+
bool needs2D = false;
861+
if (flags & (DkBlitFlag_FlipX))
862+
needs2D = true;
863+
864+
if (needs2D)
865+
{
866+
// Check whether we can really use the 2D engine
867+
DK_DEBUG_BAD_FLAGS(!(srcView->pImage->m_flags & DkImageFlags_Usage2DEngine), "DkImageFlags_Usage2DEngine required in destination image");
868+
DK_DEBUG_BAD_FLAGS(!(traits.flags & FormatTraitFlags_CanUse2DEngine), "specified format does not support DkImageFlags_Usage2DEngine");
869+
DK_DEBUG_DATA_ALIGN(dstInfo.m_iova, DK_IMAGE_LINEAR_STRIDE_ALIGNMENT); // Technically there are ways to work around this by extending width a bit, but w/e
870+
DK_DEBUG_SIZE_ALIGN(dstInfo.m_horizontal, DK_IMAGE_LINEAR_STRIDE_ALIGNMENT);
871+
DK_DEBUG_BAD_INPUT(isCompressed, "cannot use 2D engine with compressed formats"); // Technically the 2D engine *can* be used with compressed formats, but there isn't really any point in doing so
872+
873+
int dudx = 1, dvdy = 1;
874+
875+
if (flags & DkBlitFlag_FlipX)
876+
{
877+
params.srcX = params.width;
878+
dudx = -1;
879+
}
880+
881+
if (flags & DkBlitFlag_FlipY)
882+
{
883+
params.srcY = params.height;
884+
dvdy = -1;
885+
}
886+
887+
params.srcX = (params.srcX<<SrcFractBits) + (dudx<<(SrcFractBits-1));
888+
params.srcY = (params.srcY<<SrcFractBits) + (dvdy<<(SrcFractBits-1));
889+
uint32_t blitFlags = Blit2D_SetupEngine | Blit2D_OriginCorner;
890+
891+
if (srcRect->z)
892+
srcInfo.m_iova += srcRect->z * srcInfo.m_layerStride;
893+
894+
int64_t srcLayerStride = dstInfo.m_layerStride;
895+
if (flags & DkBlitFlag_FlipZ)
896+
{
897+
srcInfo.m_iova += (srcRect->depth - 1) * srcInfo.m_layerStride;
898+
srcLayerStride = -srcInfo.m_layerStride;
899+
}
900+
901+
for (uint32_t z = 0; z < srcRect->depth; z ++)
902+
{
903+
Blit2DEngine(obj, srcInfo, dstInfo, params, dudx<<DiffFractBits, dvdy<<DiffFractBits, blitFlags, 0);
904+
srcInfo.m_iova += srcLayerStride;
905+
dstInfo.m_iova += srcInfo.m_layerStride;
906+
blitFlags &= ~Blit2D_SetupEngine;
907+
}
908+
}
909+
else
910+
{
911+
if (flags & DkBlitFlag_FlipY)
912+
{
913+
dstInfo.m_iova += (params.height-1)*dstInfo.m_horizontal;
914+
dstInfo.m_horizontal = -dstInfo.m_horizontal;
915+
}
916+
917+
for (uint32_t z = 0; z < srcRect->depth; z ++)
918+
{
919+
uint32_t srcZ = srcRect->z + z;
920+
uint32_t dstZ = z;
921+
if (flags & DkBlitFlag_FlipZ)
922+
srcZ = srcRect->depth - z - 1;
923+
BlitCopyEngine(obj, srcInfo, dstInfo, params, srcZ, dstZ);
924+
}
925+
}
773926
}

0 commit comments

Comments
 (0)