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); } }
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; }