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