Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion plume_d3d12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2312,7 +2312,13 @@ namespace plume {

const D3D12_TEXTURE_COPY_LOCATION copyDstLocation = toD3D12(dstLocation);
const D3D12_TEXTURE_COPY_LOCATION copySrcLocation = toD3D12(srcLocation);
setSamplePositions(dstLocation.texture);

const bool hasDestinationTexture = (dstLocation.texture != nullptr);

if (hasDestinationTexture) {
setSamplePositions(dstLocation.texture);
}

d3d->CopyTextureRegion(&copyDstLocation, dstX, dstY, dstZ, &copySrcLocation, (srcBox != nullptr) ? &copyBox : nullptr);
resetSamplePositions();
}
Expand Down
31 changes: 31 additions & 0 deletions plume_metal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3022,6 +3022,37 @@ namespace plume {
dstOrigin
);
activeBlitEncoder->popDebugGroup();
} else if (dstLocation.type == RenderTextureCopyType::PLACED_FOOTPRINT && srcLocation.type == RenderTextureCopyType::SUBRESOURCE) {
assert(dstBuffer != nullptr);
assert(srcTexture != nullptr);

// Calculate block size based on source texture format
const uint32_t blockWidth = RenderFormatBlockWidth(srcTexture->desc.format);

const MTL::Size size = { dstLocation.placedFootprint.width, dstLocation.placedFootprint.height, dstLocation.placedFootprint.depth };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This takes the copy size from the footprint, D3D12 uses srcBox or the whole subresource when there's no box:

Suggested change
const MTL::Size size = { dstLocation.placedFootprint.width, dstLocation.placedFootprint.height, dstLocation.placedFootprint.depth };
const uint32_t mipLevel = srcLocation.subresource.mipLevel;
const MTL::Size size = (srcBox != nullptr)
? MTL::Size { NS::UInteger(srcBox->right - srcBox->left), NS::UInteger(srcBox->bottom - srcBox->top), NS::UInteger(srcBox->back - srcBox->front) }
: MTL::Size { std::max(srcTexture->desc.width >> mipLevel, 1U), std::max(srcTexture->desc.height >> mipLevel, 1U), std::max(srcTexture->desc.depth >> mipLevel, 1U) };


const uint32_t horizontalBlocks = (dstLocation.placedFootprint.rowWidth + blockWidth - 1) / blockWidth;
const uint32_t verticalBlocks = (dstLocation.placedFootprint.height + blockWidth - 1) / blockWidth;
const uint32_t bytesPerRow = horizontalBlocks * RenderFormatSize(srcTexture->desc.format);
const uint32_t bytesPerImage = bytesPerRow * verticalBlocks;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dstX/Y/Z place the region inside the footprint, so they need to go into the buffer offset:

Suggested change
const uint32_t bytesPerImage = bytesPerRow * verticalBlocks;
const uint32_t bytesPerImage = bytesPerRow * verticalBlocks;
const uint64_t dstOffset = dstLocation.placedFootprint.offset + dstZ * bytesPerImage + (dstY / blockWidth) * bytesPerRow + (dstX / blockWidth) * RenderFormatSize(srcTexture->desc.format);


const MTL::Origin srcOrigin = (srcBox != nullptr)
? MTL::Origin { NS::UInteger(srcBox->left), NS::UInteger(srcBox->top), NS::UInteger(srcBox->front) }
: MTL::Origin { 0, 0, 0 };

activeBlitEncoder->pushDebugGroup(MTLSTR("CopyTextureRegion"));
activeBlitEncoder->copyFromTexture(
srcTexture->mtl,
srcLocation.subresource.arrayIndex,
srcLocation.subresource.mipLevel,
srcOrigin,
size,
dstBuffer->mtl,
dstLocation.placedFootprint.offset,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dstLocation.placedFootprint.offset,
dstOffset,

bytesPerRow,
bytesPerImage
);
activeBlitEncoder->popDebugGroup();
} else {
assert(dstTexture != nullptr);
assert(srcTexture != nullptr);
Expand Down
21 changes: 21 additions & 0 deletions plume_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3229,6 +3229,27 @@ namespace plume {
imageCopy.imageExtent.depth = srcLocation.placedFootprint.depth;
vkCmdCopyBufferToImage(vk, srcBuffer->vk, dstTexture->vk, toImageLayout(dstTexture->textureLayout), 1, &imageCopy);
}
else if ((dstLocation.type == RenderTextureCopyType::PLACED_FOOTPRINT) && (srcLocation.type == RenderTextureCopyType::SUBRESOURCE)) {
assert(dstBuffer != nullptr);
assert(srcTexture != nullptr);

const uint32_t blockWidth = RenderFormatBlockWidth(srcTexture->desc.format);
VkBufferImageCopy imageCopy = {};
imageCopy.bufferOffset = dstLocation.placedFootprint.offset;
Comment on lines +3237 to +3238

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same two things on Vulkan, the offset:

Suggested change
VkBufferImageCopy imageCopy = {};
imageCopy.bufferOffset = dstLocation.placedFootprint.offset;
const uint32_t blockSize = RenderFormatSize(srcTexture->desc.format);
const uint32_t bytesPerRow = ((dstLocation.placedFootprint.rowWidth + blockWidth - 1) / blockWidth) * blockSize;
const uint32_t bytesPerImage = bytesPerRow * ((dstLocation.placedFootprint.height + blockWidth - 1) / blockWidth);
const uint32_t mipLevel = srcLocation.subresource.mipLevel;
VkBufferImageCopy imageCopy = {};
imageCopy.bufferOffset = dstLocation.placedFootprint.offset + dstZ * bytesPerImage + (dstY / blockWidth) * bytesPerRow + (dstX / blockWidth) * blockSize;

imageCopy.bufferRowLength = ((dstLocation.placedFootprint.rowWidth + blockWidth - 1) / blockWidth) * blockWidth;
imageCopy.bufferImageHeight = ((dstLocation.placedFootprint.height + blockWidth - 1) / blockWidth) * blockWidth;
imageCopy.imageSubresource.aspectMask = toAspectFlags(srcTexture->desc.format, srcTexture->desc.flags);
imageCopy.imageSubresource.baseArrayLayer = srcLocation.subresource.arrayIndex;
imageCopy.imageSubresource.layerCount = 1;
imageCopy.imageSubresource.mipLevel = srcLocation.subresource.mipLevel;
imageCopy.imageOffset.x = srcBox != nullptr ? srcBox->left : 0;
imageCopy.imageOffset.y = srcBox != nullptr ? srcBox->top : 0;
imageCopy.imageOffset.z = srcBox != nullptr ? srcBox->front : 0;
imageCopy.imageExtent.width = dstLocation.placedFootprint.width;
imageCopy.imageExtent.height = dstLocation.placedFootprint.height;
imageCopy.imageExtent.depth = dstLocation.placedFootprint.depth;
Comment on lines +3248 to +3250

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and the size:

Suggested change
imageCopy.imageExtent.width = dstLocation.placedFootprint.width;
imageCopy.imageExtent.height = dstLocation.placedFootprint.height;
imageCopy.imageExtent.depth = dstLocation.placedFootprint.depth;
imageCopy.imageExtent.width = srcBox != nullptr ? uint32_t(srcBox->right - srcBox->left) : std::max(srcTexture->desc.width >> mipLevel, 1U);
imageCopy.imageExtent.height = srcBox != nullptr ? uint32_t(srcBox->bottom - srcBox->top) : std::max(srcTexture->desc.height >> mipLevel, 1U);
imageCopy.imageExtent.depth = srcBox != nullptr ? uint32_t(srcBox->back - srcBox->front) : std::max(srcTexture->desc.depth >> mipLevel, 1U);

vkCmdCopyImageToBuffer(vk, srcTexture->vk, toImageLayout(srcTexture->textureLayout), dstBuffer->vk, 1, &imageCopy);
}
else {
VkImageCopy imageCopy = {};
imageCopy.srcSubresource.aspectMask = toAspectFlags(srcTexture->desc.format, srcTexture->desc.flags);
Expand Down
Loading