void Image::copyImageToBuffer(const VkCommandBuffer cmdBuffer, IBufferSP& targetBuffer, const VkBufferImageCopy& bufferImageCopy) { if (!targetBuffer.get()) { return; } VkImageLayout sourceImageLayout = getImageLayout(bufferImageCopy.imageSubresource.mipLevel, bufferImageCopy.imageSubresource.baseArrayLayer); VkAccessFlags sourceAccessMask = getAccessMask(bufferImageCopy.imageSubresource.mipLevel, bufferImageCopy.imageSubresource.baseArrayLayer); VkAccessFlags targetAccessMask = targetBuffer->getAccessMask(); // Prepare source image for copy. VkImageSubresourceRange imageSubresourceRange = {bufferImageCopy.imageSubresource.aspectMask, bufferImageCopy.imageSubresource.mipLevel, 1, bufferImageCopy.imageSubresource.baseArrayLayer, bufferImageCopy.imageSubresource.layerCount}; cmdPipelineBarrier(cmdBuffer, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageSubresourceRange); // Prepare target buffer for copy. targetBuffer->cmdPipelineBarrier(cmdBuffer, VK_ACCESS_TRANSFER_WRITE_BIT); // Copy image by command. vkCmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, targetBuffer->getBuffer(), 1, &bufferImageCopy); // Revert back. targetBuffer->cmdPipelineBarrier(cmdBuffer, targetAccessMask); // Revert back. cmdPipelineBarrier(cmdBuffer, sourceAccessMask, sourceImageLayout, imageSubresourceRange); }
void CopyContext::resourceBarrier(const Resource* pResource, Resource::State newState) { if (pResource->getState() != newState) { if(pResource->getApiHandle().getType() == VkResourceType::Image) { const Texture* pTexture = dynamic_cast<const Texture*>(pResource); VkImageMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.newLayout = getImageLayout(newState); barrier.oldLayout = getImageLayout(pResource->mState); barrier.image = pResource->getApiHandle(); barrier.subresourceRange.aspectMask = getAspectFlagsFromFormat(pTexture->getFormat()); barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.layerCount = pTexture->getArraySize(); barrier.subresourceRange.levelCount = pTexture->getMipCount(); barrier.srcAccessMask = getAccessMask(pResource->mState); barrier.dstAccessMask = getAccessMask(newState); vkCmdPipelineBarrier(mpLowLevelData->getCommandList(), getShaderStageMask(pResource->mState, true), getShaderStageMask(newState, false), 0, 0, nullptr, 0, nullptr, 1, &barrier); } else { const Buffer* pBuffer = dynamic_cast<const Buffer*>(pResource); assert(pBuffer); VkBufferMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; barrier.srcAccessMask = getAccessMask(pResource->mState); barrier.dstAccessMask = getAccessMask(newState); barrier.buffer = pBuffer->getApiHandle(); barrier.offset = pBuffer->getGpuAddressOffset(); barrier.size = pBuffer->getSize(); vkCmdPipelineBarrier(mpLowLevelData->getCommandList(), getShaderStageMask(pResource->mState, true), getShaderStageMask(newState, false), 0, 0, nullptr, 1, &barrier, 0, nullptr); } pResource->mState = newState; mCommandsPending = true; } }
void Image::copyImage(const VkCommandBuffer cmdBuffer, IImageSP& targetImage, const VkImageCopy& imageCopy) { if (!targetImage.get()) { return; } VkImageLayout sourceImageLayout = getImageLayout(imageCopy.srcSubresource.mipLevel, imageCopy.srcSubresource.baseArrayLayer); VkAccessFlags sourceAccessMask = getAccessMask(imageCopy.srcSubresource.mipLevel, imageCopy.srcSubresource.baseArrayLayer); VkImageLayout targetImageLayout = targetImage->getImageLayout(imageCopy.dstSubresource.mipLevel, imageCopy.dstSubresource.baseArrayLayer); VkAccessFlags targetAccessMask = targetImage->getAccessMask(imageCopy.dstSubresource.mipLevel, imageCopy.dstSubresource.baseArrayLayer); // Prepare source image for copy. VkImageSubresourceRange srcImageSubresourceRange = {imageCopy.srcSubresource.aspectMask, imageCopy.srcSubresource.mipLevel, 1, imageCopy.srcSubresource.baseArrayLayer, imageCopy.srcSubresource.layerCount}; cmdPipelineBarrier(cmdBuffer, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, srcImageSubresourceRange); // Prepare target image for copy. VkImageSubresourceRange dstImageSubresourceRange = {imageCopy.dstSubresource.aspectMask, imageCopy.dstSubresource.mipLevel, 1, imageCopy.dstSubresource.baseArrayLayer, imageCopy.dstSubresource.layerCount}; targetImage->cmdPipelineBarrier(cmdBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dstImageSubresourceRange); // Copy image by command. vkCmdCopyImage(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, targetImage->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy); // Revert back. targetImage->cmdPipelineBarrier(cmdBuffer, targetAccessMask, targetImageLayout, dstImageSubresourceRange); // Revert back. cmdPipelineBarrier(cmdBuffer, sourceAccessMask, sourceImageLayout, srcImageSubresourceRange); }