bool Image::createImageFromAHardwareBuffer()

in RenderScriptMigrationSample/app/src/main/cpp/VulkanResources.cpp [196:268]


bool Image::createImageFromAHardwareBuffer(AHardwareBuffer* buffer) {
    // Acquire the AHardwareBuffer and get the descriptor
    AHardwareBuffer_acquire(buffer);
    AHardwareBuffer_Desc ahwbDesc{};
    AHardwareBuffer_describe(buffer, &ahwbDesc);
    mBuffer = buffer;
    mWidth = ahwbDesc.width;
    mHeight = ahwbDesc.height;

    // Get AHardwareBuffer properties
    VkAndroidHardwareBufferFormatPropertiesANDROID formatInfo = {
            .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
            .pNext = nullptr,
    };
    VkAndroidHardwareBufferPropertiesANDROID properties = {
            .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
            .pNext = &formatInfo,
    };
    CALL_VK(vkGetAndroidHardwareBufferPropertiesANDROID, mContext->device(), mBuffer, &properties);

    // Create an image to bind to our AHardwareBuffer
    VkExternalMemoryImageCreateInfo externalCreateInfo{
            .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
            .pNext = nullptr,
            .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
    };
    VkImageCreateInfo createInfo{
            .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
            .pNext = &externalCreateInfo,
            .flags = 0u,
            .imageType = VK_IMAGE_TYPE_2D,
            .format = VK_FORMAT_R8G8B8A8_UNORM,
            .extent = {ahwbDesc.width, ahwbDesc.height, 1u},
            .mipLevels = 1u,
            .arrayLayers = 1u,
            .samples = VK_SAMPLE_COUNT_1_BIT,
            .tiling = VK_IMAGE_TILING_OPTIMAL,
            .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
            .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
            .queueFamilyIndexCount = 0,
            .pQueueFamilyIndices = nullptr,
            .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
    };
    CALL_VK(vkCreateImage, mContext->device(), &createInfo, nullptr, mImage.pHandle());

    // Allocate device memory
    const auto memoryTypeIndex = mContext->findMemoryType(properties.memoryTypeBits,
                                                          VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
    RET_CHECK(memoryTypeIndex.has_value());
    VkImportAndroidHardwareBufferInfoANDROID androidHardwareBufferInfo{
            .sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
            .pNext = nullptr,
            .buffer = mBuffer,
    };
    VkMemoryDedicatedAllocateInfo memoryAllocateInfo{
            .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
            .pNext = &androidHardwareBufferInfo,
            .image = mImage.handle(),
            .buffer = VK_NULL_HANDLE,
    };
    VkMemoryAllocateInfo allocateInfo{
            .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
            .pNext = &memoryAllocateInfo,
            .allocationSize = properties.allocationSize,
            .memoryTypeIndex = memoryTypeIndex.value(),
    };
    CALL_VK(vkAllocateMemory, mContext->device(), &allocateInfo, nullptr, mMemory.pHandle());

    // Bind image to the device memory
    CALL_VK(vkBindImageMemory, mContext->device(), mImage.handle(), mMemory.handle(), 0);
    RET_CHECK(transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL));
    return true;
}