Exemplo n.º 1
0
IMemoryImageSP VKTS_APIENTRY memoryImageCreate(IImageSP& stageImage, IBufferSP& stageBuffer, IDeviceMemorySP& stageDeviceMemory, const IInitialResourcesSP& initialResources, const ICommandBuffersSP& cmdBuffer, const std::string& name, const IImageDataSP& imageData, const VkImageCreateInfo& imageCreateInfo, const VkAccessFlags srcAccessMask, const VkAccessFlags dstAccessMask, const VkImageLayout newLayout, const VkImageSubresourceRange& subresourceRange, const VkMemoryPropertyFlags memoryPropertyFlags)
{
    if (!cmdBuffer || !imageData.get())
    {
        return IMemoryImageSP();
    }

    VkResult result;

    //

    IImageSP image;

    IDeviceMemorySP deviceMemory;

    //

    if (!memoryImagePrepare(image, deviceMemory, initialResources, cmdBuffer, imageCreateInfo, srcAccessMask, dstAccessMask, newLayout, subresourceRange, memoryPropertyFlags))
    {
        return IMemoryImageSP();
    }

    //

    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 (!memoryImageUpload(deviceMemory, imageData, i, subresourceLayout))
            {
                logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not upload image data.");

                return IMemoryImageSP();
            }
        }
    }
    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;
            stageImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;

            if (!memoryImagePrepare(stageImage, stageDeviceMemory, initialResources, cmdBuffer, stageImageCreateInfo, VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresourceRange, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
            {
                logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not prepare staging image.");

                return IMemoryImageSP();
            }

            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 (!memoryImageUpload(stageDeviceMemory, imageData, i, subresourceLayout))
                {
                    logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not upload image data.");

                    return IMemoryImageSP();
                }

                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, imageCopy);
            }
        }
Exemplo n.º 2
0
SmartPointerVector<IImageDataSP> VKTS_APIENTRY imageDataMipmap(const IImageDataSP& sourceImage, VkBool32 addSourceAsCopy, const std::string& name)
{
    if (name.size() == 0 || !sourceImage.get())
    {
        return SmartPointerVector<IImageDataSP>();
    }

    std::string sourceImageFilename = name;

    auto dotIndex = sourceImageFilename.rfind(".");

    if (dotIndex == sourceImageFilename.npos)
    {
        return SmartPointerVector<IImageDataSP>();
    }

    auto sourceImageName = sourceImageFilename.substr(0, dotIndex);
    auto sourceImageExtension = sourceImageFilename.substr(dotIndex);

    IImageDataSP currentSourceImage = sourceImage;
    int32_t width = currentSourceImage->getWidth();
    int32_t height = currentSourceImage->getHeight();
    int32_t depth = currentSourceImage->getDepth();

    IImageDataSP currentTargetImage;
    std::string targetImageFilename;

    int32_t level = 0;

    SmartPointerVector<IImageDataSP> result;

    if (addSourceAsCopy)
    {
        targetImageFilename = sourceImageName + "_L" + std::to_string(level++) + sourceImageExtension;

        currentTargetImage = imageDataCopy(sourceImage, targetImageFilename);

        if (!currentTargetImage.get())
        {
            return SmartPointerVector<IImageDataSP>();
        }

        result.append(currentTargetImage);
    }
    else
    {
        result.append(sourceImage);

        level++;
    }

    while (width > 1 || height > 1 || depth > 1)
    {
        width = glm::max(width / 2, 1);
        height = glm::max(height / 2, 1);
        depth = glm::max(depth / 2, 1);

        targetImageFilename = sourceImageName + "_L" + std::to_string(level++) + sourceImageExtension;

        currentTargetImage = imageDataCreate(targetImageFilename, width, height, depth, 0.0f, 0.0f, 0.0f, 0.0f, sourceImage->getImageType(), sourceImage->getFormat());

        if (!currentTargetImage.get())
        {
            return SmartPointerVector<IImageDataSP>();
        }

        for (int32_t z = 0; z < depth; z++)
        {
            for (int32_t y = 0; y < height; y++)
            {
                for (int32_t x = 0; x < width; x++)
                {
                    glm::vec4 rgba = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
                    float sampleCount = 0.0f;

                    for (int32_t iz = z * 2; iz < z * 2 + 1; iz++)
                    {
                        for (int32_t iy = y * 2; iy < y * 2 + 1; iy++)
                        {
                            for (int32_t ix = x * 2; ix < x * 2 + 1; ix++)
                            {
                                rgba += currentSourceImage->getTexel(ix, iy, iz);

                                sampleCount += 1.0f;
                            }
                        }
                    }

                    if (sampleCount > 0.0f)
                    {
                        rgba /= sampleCount;

                        currentTargetImage->setTexel(rgba, x, y, z);
                    }
                }
            }
        }

        result.append(currentTargetImage);

        //

        currentSourceImage = currentTargetImage;
        width = currentSourceImage->getWidth();
        height = currentSourceImage->getHeight();
        depth = currentSourceImage->getDepth();
    }

    return result;
}