在Android中将外部缓冲区导入Vulkan时出现问题
我正在尝试使用Vulkan在Android 10中显示图像。管道看起来像这样 MediaCodec->ImageReader->AHardwareBuffer(传递到Vulkan上下文)->映射到Vulkan->使用Vulkan API显示它 在本机CPP层中,在Vulkan上下文中执行以下操作以导入hardwarebuffer: 查找AHardwareBuffer的属性->创建VkImage->创建设备内存(专用内存)->使用YUVSampler将缓冲区映射到VkImage->Sample 问题在于“创建设备内存”是Vulkan验证层显示错误的步骤。它抱怨该格式不受支持。请注意,我使用的是外部格式(规范允许这样做),因此格式处理是不透明的。 这是不工作,现在和我只看到一个黑色的框架,每次。有人能看一下吗?在将AHardwareBuffer导入Vulkan上下文的逻辑中,我遗漏了什么 为什么是外部格式?因为我不能在不同的设备上控制解码器的输出,我想要一些不透明的处理方法 另外,我正在使用以下设置创建ImageReader在Android中将外部缓冲区导入Vulkan时出现问题,android,android-ndk,vulkan,android-mediacodec,Android,Android Ndk,Vulkan,Android Mediacodec,我正在尝试使用Vulkan在Android 10中显示图像。管道看起来像这样 MediaCodec->ImageReader->AHardwareBuffer(传递到Vulkan上下文)->映射到Vulkan->使用Vulkan API显示它 在本机CPP层中,在Vulkan上下文中执行以下操作以导入hardwarebuffer: 查找AHardwareBuffer的属性->创建VkImage->创建设备内存(专用内存)->使用YUVSampler将缓冲区映射到VkImage->Sample 问
ImageReader.newInstance(1920, 1080, ImageFormat.PRIVATE, MAX_IMAGE_SIZE + 1,
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
下面是Vulkan中的代码,从我收到AHardwareBuffer到验证层认为引起问题的API。我试着只保留与映射相关的代码
VkAndroidHardwareBufferFormatPropertiesANDROID hardwareBufferFormat{
.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
.pNext = nullptr,
};
VkAndroidHardwareBufferPropertiesANDROID hardwareBufferProperties{
.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
.pNext = &hardwareBufferFormat,
};
/* Find the properties of AHardwareBuffer that is to be imported */
vkGetAndroidHardwareBufferPropertiesANDROID(mLogicalDevice, buffer, &hardwareBufferProperties);
// mTexture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkImage Image_local;
VkExternalFormatANDROID externalFormatAndroid{
.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID,
.pNext = nullptr,
.externalFormat = hardwareBufferFormat.externalFormat,
};
VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo{
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
.pNext = &externalFormatAndroid,
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
};
VkImageCreateInfo imageCreateInfo{
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = &externalMemoryImageCreateInfo,
.flags = 0,
.imageType = VK_IMAGE_TYPE_2D,
.format = VK_FORMAT_UNDEFINED,
.extent = {1920, 1080, 1},
.mipLevels = 1,
.arrayLayers = hardwareBufferDesc.layers,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_SAMPLED_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
vkCreateImage(mLogicalDevice, &imageCreateInfo, nullptr, &Image_local);
VkImportAndroidHardwareBufferInfoANDROID hardwareBufferInfo{
.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
.pNext = nullptr,
.buffer = buffer};
VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo{
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = &hardwareBufferInfo,
.image = Image_local,
.buffer = VK_NULL_HANDLE,
};
uint32_t mem_index = GetMemoryType(hardwareBufferProperties.memoryTypeBits, 0);
VkMemoryAllocateInfo memoryAllocateInfo{
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &memoryDedicatedAllocateInfo,
.allocationSize = hardwareBufferProperties.allocationSize,
.memoryTypeIndex = mem_index,
};
/* So this API here does not return any erros, however the validation layer says that the format
* is not supported. I am using an external Format, so assuming that this should not complain.
*/
vkAllocateMemory(mLogicalDevice, &memoryAllocateInfo, nullptr, &mTexture.deviceMemory)
不确定这是否是答案,但通过阅读一些其他执行此操作的代码和规范,它看起来像hardwareBufferFormat.format可以是未定义的VK_格式,但也可以是有效的VK_格式,可以写入VkImageCreateInfo。只有当该成员为VK_FORMAT_UNDEFINED时,才需要使用externalFormat成员。@LewisGordon在我的例子中,格式为VK_FORMAT_UNDEFINED。所以我必须使用externalFormat。externalFormat是一个非零的大值。不确定这是否是答案,但通过阅读其他执行此操作的代码和规范,它看起来像hardwareBufferFormat.format可以是未定义的VK_格式,但也可以是可以写入VkImageCreateInfo的有效VK_格式。只有当该成员为VK_FORMAT_UNDEFINED时,才需要使用externalFormat成员。@LewisGordon在我的例子中,格式为VK_FORMAT_UNDEFINED。所以我必须使用externalFormat。externalFormat是一个非零的大值。