// Record a buffer copy operation into the command buffer public void RecordBufferCopy(VkCommandBuffer cmd, ResourceType?dstBufferType, ulong dataSize, VkBuffer srcBuffer, ulong srcOffset, VkBuffer dstBuffer, ulong dstOffset) { // Get pipeline barrier values VkPipelineStageFlags srcStage = 0, dstStage = 0; VkAccessFlags srcAccess = 0, dstAccess = 0; if (dstBufferType.HasValue) { GetBarrierStages(dstBufferType.Value, out srcStage, out dstStage); GetAccessFlags(dstBufferType.Value, out srcAccess, out dstAccess); } // Start command VkCommandBufferBeginInfo cbbi = new(VkCommandBufferUsageFlags.OneTimeSubmit, null); cmd.BeginCommandBuffer(&cbbi); // Src barrier if (dstBufferType.HasValue) { VkBufferMemoryBarrier srcBarrier = new( srcAccessMask : srcAccess, dstAccessMask : VkAccessFlags.TransferWrite, srcQueueFamilyIndex : VkConstants.QUEUE_FAMILY_IGNORED, dstQueueFamilyIndex : VkConstants.QUEUE_FAMILY_IGNORED, buffer : dstBuffer, offset : dstOffset, size : dataSize ); cmd.CmdPipelineBarrier( srcStage, VkPipelineStageFlags.Transfer, VkDependencyFlags.ByRegion, 0, null, 1, &srcBarrier, 0, null ); } // Create copy command VkBufferCopy bc = new(srcOffset, dstOffset, dataSize); cmd.CmdCopyBuffer(srcBuffer, dstBuffer, 1, &bc); // Last barrier if (dstBufferType.HasValue) { VkBufferMemoryBarrier dstBarrier = new( srcAccessMask : VkAccessFlags.TransferWrite, dstAccessMask : dstAccess, srcQueueFamilyIndex : VkConstants.QUEUE_FAMILY_IGNORED, dstQueueFamilyIndex : VkConstants.QUEUE_FAMILY_IGNORED, buffer : dstBuffer, offset : dstOffset, size : dataSize ); cmd.CmdPipelineBarrier( VkPipelineStageFlags.Transfer, dstStage, VkDependencyFlags.ByRegion, 0, null, 1, &dstBarrier, 0, null ); } // End cmd.EndCommandBuffer().Throw("Failed to record buffer upload commands"); }