示例#1
0
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);
}
示例#2
0
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);
            }
        }