1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 10:24:10 +01:00

[dxvk] Support destination pitch in packImageData

This commit is contained in:
Philip Rebohle 2021-07-19 16:53:00 +02:00
parent d3112c320b
commit 11bbc07ea1
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 51 additions and 24 deletions

View File

@ -1021,7 +1021,7 @@ namespace dxvk {
auto stagingSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, extent));
util::packImageData(stagingSlice.mapPtr(0),
pSrcData, SrcRowPitch, SrcDepthPitch,
pSrcData, SrcRowPitch, SrcDepthPitch, 0, 0,
dstTexture->GetVkImageType(), extent, 1,
formatInfo, formatInfo->aspectMask);

View File

@ -171,7 +171,7 @@ namespace dxvk {
if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) {
util::packImageData(pTexture->GetMappedBuffer(id)->mapPtr(0),
pInitialData[id].pSysMem, pInitialData[id].SysMemPitch, pInitialData[id].SysMemSlicePitch,
pTexture->GetVkImageType(), mipLevelExtent, 1, formatInfo, formatInfo->aspectMask);
0, 0, pTexture->GetVkImageType(), mipLevelExtent, 1, formatInfo, formatInfo->aspectMask);
}
}
}

View File

@ -76,8 +76,10 @@ namespace dxvk::util {
void packImageData(
void* dstBytes,
const void* srcBytes,
VkDeviceSize rowPitch,
VkDeviceSize slicePitch,
VkDeviceSize srcRowPitch,
VkDeviceSize srcSlicePitch,
VkDeviceSize dstRowPitchIn,
VkDeviceSize dstSlicePitchIn,
VkImageType imageType,
VkExtent3D imageExtent,
uint32_t imageLayers,
@ -85,7 +87,7 @@ namespace dxvk::util {
VkImageAspectFlags aspectMask) {
for (uint32_t i = 0; i < imageLayers; i++) {
auto dstData = reinterpret_cast< char*>(dstBytes);
auto srcData = reinterpret_cast<const char*>(srcBytes) + i * slicePitch;
auto srcData = reinterpret_cast<const char*>(srcBytes);
for (auto aspects = aspectMask; aspects; ) {
auto aspect = vk::getNextAspect(aspects);
@ -105,36 +107,54 @@ namespace dxvk::util {
VkDeviceSize bytesPerSlice = blockCount.height * bytesPerRow;
VkDeviceSize bytesTotal = blockCount.depth * bytesPerSlice;
const bool directCopy = ((bytesPerRow == rowPitch ) || (blockCount.height == 1))
&& ((bytesPerSlice == slicePitch) || (blockCount.depth == 1));
VkDeviceSize dstRowPitch = dstRowPitchIn ? dstRowPitchIn : bytesPerRow;
VkDeviceSize dstSlicePitch = dstSlicePitchIn ? dstSlicePitchIn : bytesPerSlice;
const bool directCopy = ((bytesPerRow == srcRowPitch && bytesPerRow == dstRowPitch ) || (blockCount.height == 1))
&& ((bytesPerSlice == srcSlicePitch && bytesPerSlice == dstSlicePitch) || (blockCount.depth == 1));
if (directCopy) {
std::memcpy(dstData, srcData, bytesTotal);
dstData += bytesTotal;
switch (imageType) {
case VK_IMAGE_TYPE_1D: srcData += bytesPerRow; break;
case VK_IMAGE_TYPE_2D: srcData += blockCount.height * rowPitch; break;
case VK_IMAGE_TYPE_3D: srcData += blockCount.depth * slicePitch; break;
case VK_IMAGE_TYPE_1D:
srcData += srcRowPitch;
dstData += dstRowPitch;
break;
case VK_IMAGE_TYPE_2D:
srcData += blockCount.height * srcRowPitch;
dstData += blockCount.height * dstRowPitch;
break;
case VK_IMAGE_TYPE_3D:
srcData += blockCount.depth * srcSlicePitch;
dstData += blockCount.depth * dstSlicePitch;
break;
default: ;
}
} else {
for (uint32_t i = 0; i < blockCount.depth; i++) {
for (uint32_t j = 0; j < blockCount.height; j++) {
std::memcpy(
dstData + j * bytesPerRow,
srcData + j * rowPitch,
dstData + j * dstRowPitch,
srcData + j * srcRowPitch,
bytesPerRow);
}
switch (imageType) {
case VK_IMAGE_TYPE_1D: srcData += bytesPerRow; break;
case VK_IMAGE_TYPE_2D: srcData += blockCount.height * rowPitch; break;
case VK_IMAGE_TYPE_3D: srcData += slicePitch; break;
case VK_IMAGE_TYPE_1D:
srcData += srcRowPitch;
dstData += dstRowPitch;
break;
case VK_IMAGE_TYPE_2D:
srcData += blockCount.height * srcRowPitch;
dstData += blockCount.height * dstRowPitch;
break;
case VK_IMAGE_TYPE_3D:
srcData += srcSlicePitch;
dstData += dstSlicePitch;
break;
default: ;
}
dstData += bytesPerSlice;
}
}
}

View File

@ -40,12 +40,17 @@ namespace dxvk::util {
VkDeviceSize pitchPerLayer);
/**
* \brief Writes tightly packed image data to a buffer
* \brief Repacks image data to a buffer
*
* Note that passing destination pitches of 0 means that the data is
* tightly packed, while a source pitch of 0 will not show this behaviour
* in order to match client API behaviour for initialization.
* \param [in] dstBytes Destination buffer pointer
* \param [in] srcBytes Pointer to source data
* \param [in] rowPitch Number of bytes between rows
* \param [in] slicePitch Number of bytes between layers
* \param [in] srcRowPitch Number of bytes between rows to read
* \param [in] srcSlicePitch Number of bytes between layers to read
* \param [in] dstRowPitch Number of bytes between rows to write
* \param [in] dstSlicePitch Number of bytes between layers to write
* \param [in] imageType Image type (2D, 3D etc)
* \param [in] imageExtent Image extent, in pixels
* \param [in] imageLayers Image layer count
@ -55,8 +60,10 @@ namespace dxvk::util {
void packImageData(
void* dstBytes,
const void* srcBytes,
VkDeviceSize rowPitch,
VkDeviceSize slicePitch,
VkDeviceSize srcRowPitch,
VkDeviceSize srcSlicePitch,
VkDeviceSize dstRowPitchIn,
VkDeviceSize dstSlicePitchIn,
VkImageType imageType,
VkExtent3D imageExtent,
uint32_t imageLayers,