@@ -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