首页 > 解决方案 > VK_FORMAT_UNDEFINED 用于 Vulkan 上具有深度格式的 Android 硬件缓冲区

问题描述

如果我分配具有深度格式 (AHARDWAREBUFFER_FORMAT_D16_UNORM) 的 Android 硬件缓冲区,则 vkGetAndroidHardwareBufferPropertiesANDROID 检索到的结果 Vulkan 格式为 VK_FORMAT_UNDEFINED,即使硬件缓冲区深度格式具有直接的 Vulkan 格式等效 (VK_FORMAT_D16_UNORM)。颜色格式不会发生同样的情况:使用 AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM vkGetAndroidHardwareBufferPropertiesANDROID 会按预期产生 VK_FORMAT_R8G8B8A8_UNORM。

我是否需要使用特殊参数或扩展名才能正确映射深度格式?

这是代码片段:

uint32_t width = 1024;
uint32_t height = 1024;
// uint32_t hardwareBufferFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
uint32_t hardwareBufferFormat = AHARDWAREBUFFER_FORMAT_D16_UNORM;
uint32_t hardwareBufferUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties{VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID};
VkAndroidHardwareBufferPropertiesANDROID bufferProperties{VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID};
bufferProperties.pNext = &bufferFormatProperties;
AHardwareBuffer *hardwareBuffer;
AHardwareBuffer_Desc desc{width, height, 1, hardwareBufferFormat, hardwareBufferUsage, 0, 0, 0};
int error = AHardwareBuffer_allocate(&desc, &hardwareBuffer);
if (error < 0) {
  LOGE("AHardwareBuffer_allocate error: %d", error);
  return;
}

vkGetAndroidHardwareBufferPropertiesANDROID(tutorialDevice, hardwareBuffer, &bufferProperties);

完整代码,在 android-vulkan-tutorials ( https://github.com/googlesamples/android-vulkan-tutorials )分支上的分支,可在此处获得:https ://github.com/pm328/android-vulkan-tutorials/pull /1/文件

测试设备:三星 Galaxy S20、Galaxy Note 10+ 5G

GPU:Adreno(高通骁龙)

安卓版本:10

我还测试了 AHARDWAREBUFFER_FORMAT_D24_UNORM、AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT 和 AHARDWAREBUFFER_FORMAT_D32_FLOAT,结果完全相同。

标签: androidandroid-ndkvulkandepth-buffer

解决方案


不保证所有AHARDWAREBUFFER_FORMAT类型都可以通过他的方法分配;可用的是特定于平台的。打电话AHardwareBuffer_isSupported()看看他们是否是,但如果深度缓冲区不是,我不会感到惊讶。


推荐阅读