Skip to content

Commit b3303a2

Browse files
committed
Merge pull request #3382 from erikaharrison-adsk/adsk/bugfix/incorrect-HgiVulkanBlitCmds-CopyBufferCpuToGpu
Autodesk: Vulkan Bugfix - HgiVulkanBlitCmds offset (Internal change: 2347311)
2 parents 64c8a39 + 3fd3147 commit b3303a2

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed

pxr/imaging/hgiVulkan/blitCmds.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -283,23 +283,27 @@ void HgiVulkanBlitCmds::CopyBufferCpuToGpu(
283283
if (!buffer->IsCPUStagingAddress(copyOp.cpuSourceBuffer) ||
284284
copyOp.sourceByteOffset != copyOp.destinationByteOffset) {
285285

286-
uint8_t* dst = static_cast<uint8_t*>(buffer->GetCPUStagingAddress());
287-
size_t dstOffset = copyOp.destinationByteOffset;
286+
// Offset into the src buffer.
287+
const uint8_t* const src =
288+
static_cast<const uint8_t*>(copyOp.cpuSourceBuffer) +
289+
copyOp.sourceByteOffset;
288290

289-
// Offset into the src buffer
290-
uint8_t* src = ((uint8_t*) copyOp.cpuSourceBuffer) +
291-
copyOp.sourceByteOffset;
291+
// Offset into the dst buffer.
292+
uint8_t* const dst =
293+
static_cast<uint8_t*>(buffer->GetCPUStagingAddress()) +
294+
copyOp.destinationByteOffset;
292295

293-
// Offset into the dst buffer
294-
memcpy(dst + dstOffset, src, copyOp.byteSize);
296+
memcpy(dst, src, copyOp.byteSize);
295297
}
296298

297299
// Schedule copy data from staging buffer to device-local buffer.
298300
HgiVulkanBuffer* stagingBuffer = buffer->GetStagingBuffer();
299301

300302
if (TF_VERIFY(stagingBuffer)) {
301303
VkBufferCopy copyRegion = {};
302-
copyRegion.srcOffset = copyOp.sourceByteOffset;
304+
// Note we use the destinationByteOffset as the srcOffset here. The staging buffer
305+
// should be prepared with the same data layout of the destination buffer.
306+
copyRegion.srcOffset = copyOp.destinationByteOffset;
303307
copyRegion.dstOffset = copyOp.destinationByteOffset;
304308
copyRegion.size = copyOp.byteSize;
305309

pxr/imaging/hgiVulkan/testenv/testHgiVulkan.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,46 @@ TestVulkanBuffer(HgiVulkan& hgiVulkan)
588588
return false;
589589
}
590590

591+
// Test another CPU to GPU copy, this time with different src and dst
592+
// offsets.
593+
594+
// Write new data into CPU staging area
595+
stagingBlob[8] = 789;
596+
stagingBlob[9] = 789;
597+
stagingBlob[10] = 789;
598+
stagingBlob[11] = 789;
599+
memcpy(cpuAddress, stagingBlob.data() + 4, 8 * sizeof(blob[0]));
600+
601+
// Schedule copy from staging area to GPU device-local buffer.
602+
HgiBufferCpuToGpuOp transferOp2;
603+
transferOp2.byteSize = 8 * sizeof(blob[0]);
604+
transferOp2.cpuSourceBuffer = cpuAddress;
605+
transferOp2.sourceByteOffset = 0;
606+
transferOp2.destinationByteOffset = 4 * sizeof(blob[0]);
607+
transferOp2.gpuDestinationBuffer = buffer;
608+
609+
HgiBlitCmdsUniquePtr blitCmds4 = hgiVulkan.CreateBlitCmds();
610+
blitCmds4->CopyBufferCpuToGpu(transferOp2);
611+
hgiVulkan.SubmitCmds(blitCmds4.get(), HgiSubmitWaitTypeWaitUntilCompleted);
612+
613+
// Read back the transfer to confirm it worked
614+
HgiBufferGpuToCpuOp copyOp3;
615+
copyOp3.byteSize = desc.byteSize;
616+
copyOp3.cpuDestinationBuffer = &transferBackBlob[0];
617+
copyOp3.destinationByteOffset = 0;
618+
copyOp3.gpuSourceBuffer = buffer;
619+
copyOp3.sourceByteOffset = 0;
620+
621+
HgiBlitCmdsUniquePtr blitCmds5 = hgiVulkan.CreateBlitCmds();
622+
blitCmds5->CopyBufferGpuToCpu(copyOp3);
623+
hgiVulkan.SubmitCmds(blitCmds5.get(), HgiSubmitWaitTypeWaitUntilCompleted);
624+
625+
std::cout << std::endl;
626+
if (transferBackBlob != stagingBlob) {
627+
TF_CODING_ERROR("Transfer readback failed");
628+
return false;
629+
}
630+
591631
// Put buffer in garbage collector
592632
device->WaitForIdle();
593633
hgiVulkan.DestroyBuffer(&buffer);

0 commit comments

Comments
 (0)