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); }
ITextureSP VKTS_APIENTRY textureCreate(IImageSP& stageImage, IBufferSP& stageBuffer, IDeviceMemorySP& stageDeviceMemory, const IInitialResourcesSP& initialResources, const ICommandBuffersSP& cmdBuffer, const std::string& name, const IImageDataSP& imageData, const VkImageCreateInfo& imageCreateInfo, const VkAccessFlags dstAccessMask, const VkImageLayout newLayout, const VkImageSubresourceRange& subresourceRange, const VkMemoryPropertyFlags memoryPropertyFlags, const VkSamplerCreateInfo& samplerCreateInfo, const VkImageViewCreateInfo& imageViewCreateInfo) { if (!cmdBuffer || !imageData.get()) { return ITextureSP(); } VkResult result; // IImageSP image; IDeviceMemorySP deviceMemory; // if (!texturePrepare(image, deviceMemory, initialResources, cmdBuffer, imageCreateInfo, dstAccessMask, newLayout, subresourceRange, memoryPropertyFlags)) { return ITextureSP(); } // if (memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { for (uint32_t i = 0; i < imageData->getMipLevels(); i++) { VkImageSubresource imageSubresource; imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageSubresource.mipLevel = i; imageSubresource.arrayLayer = 0; VkSubresourceLayout subresourceLayout; image->getImageSubresourceLayout(subresourceLayout, imageSubresource); if (!textureUpload(deviceMemory, imageData, i, subresourceLayout)) { logPrint(VKTS_LOG_ERROR, "Texture: Could not upload image data."); return ITextureSP(); } } } else { if (initialResources->getPhysicalDevice()->isImageTilingAvailable(VK_IMAGE_TILING_LINEAR, imageData->getFormat(), imageData->getImageType(), 0, imageData->getExtent3D(), imageData->getMipLevels(), 1, VK_SAMPLE_COUNT_1_BIT, imageData->getSize())) { VkImageCreateInfo stageImageCreateInfo; memcpy(&stageImageCreateInfo, &imageCreateInfo, sizeof(VkImageCreateInfo)); stageImageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR; stageImageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; if (!texturePrepare(stageImage, stageDeviceMemory, initialResources, cmdBuffer, stageImageCreateInfo, dstAccessMask, newLayout, subresourceRange, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) { logPrint(VKTS_LOG_ERROR, "Texture: Could not prepare staging image."); return ITextureSP(); } for (uint32_t i = 0; i < imageData->getMipLevels(); i++) { VkImageSubresource imageSubresource; imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageSubresource.mipLevel = i; imageSubresource.arrayLayer = 0; VkSubresourceLayout subresourceLayout; stageImage->getImageSubresourceLayout(subresourceLayout, imageSubresource); if (!textureUpload(stageDeviceMemory, imageData, i, subresourceLayout)) { logPrint(VKTS_LOG_ERROR, "Texture: Could not upload image data."); return ITextureSP(); } VkImageCopy imageCopy; imageCopy.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, 0, 1}; imageCopy.srcOffset = {0, 0, 0}; imageCopy.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, 0, 1}; imageCopy.dstOffset = {0, 0, 0}; imageCopy.extent = {glm::max(imageData->getWidth() >> i, 1u), glm::max(imageData->getHeight() >> i, 1u), glm::max(imageData->getDepth() >> i, 1u)}; stageImage->copyImage(cmdBuffer->getCommandBuffer(), image->getImage(), image->getAccessMask(), image->getImageLayout(), imageCopy); } }