|
|
|
@@ -26,7 +26,6 @@
|
|
|
|
|
#include "vn_queue.h"
|
|
|
|
|
|
|
|
|
|
struct vn_android_gralloc_buffer_properties {
|
|
|
|
|
uint32_t drm_fourcc;
|
|
|
|
|
uint32_t num_planes;
|
|
|
|
|
uint64_t modifier;
|
|
|
|
|
|
|
|
|
@@ -67,7 +66,6 @@ vn_android_gralloc_get_buffer_properties(
|
|
|
|
|
|
|
|
|
|
assert(info.num_planes <= 4);
|
|
|
|
|
|
|
|
|
|
out_props->drm_fourcc = info.drm_fourcc;
|
|
|
|
|
out_props->num_planes = info.num_planes;
|
|
|
|
|
for (uint32_t i = 0; i < info.num_planes; i++) {
|
|
|
|
|
if (!info.strides[i]) {
|
|
|
|
@@ -153,99 +151,6 @@ vn_android_format_to_view_formats(VkFormat format, uint32_t *out_count)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkFormat
|
|
|
|
|
vn_android_drm_format_to_vk_format(uint32_t format)
|
|
|
|
|
{
|
|
|
|
|
switch (format) {
|
|
|
|
|
case DRM_FORMAT_ABGR8888:
|
|
|
|
|
case DRM_FORMAT_XBGR8888:
|
|
|
|
|
return VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
|
case DRM_FORMAT_BGR888:
|
|
|
|
|
return VK_FORMAT_R8G8B8_UNORM;
|
|
|
|
|
case DRM_FORMAT_RGB565:
|
|
|
|
|
return VK_FORMAT_R5G6B5_UNORM_PACK16;
|
|
|
|
|
case DRM_FORMAT_ABGR16161616F:
|
|
|
|
|
return VK_FORMAT_R16G16B16A16_SFLOAT;
|
|
|
|
|
case DRM_FORMAT_ABGR2101010:
|
|
|
|
|
return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
|
|
|
|
|
case DRM_FORMAT_R8:
|
|
|
|
|
return VK_FORMAT_R8_UNORM;
|
|
|
|
|
case DRM_FORMAT_YVU420:
|
|
|
|
|
return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
|
|
|
|
|
case DRM_FORMAT_NV12:
|
|
|
|
|
return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
|
|
|
|
default:
|
|
|
|
|
return VK_FORMAT_UNDEFINED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
vn_android_drm_format_is_yuv(uint32_t format)
|
|
|
|
|
{
|
|
|
|
|
assert(vn_android_drm_format_to_vk_format(format) != VK_FORMAT_UNDEFINED);
|
|
|
|
|
|
|
|
|
|
switch (format) {
|
|
|
|
|
case DRM_FORMAT_YVU420:
|
|
|
|
|
case DRM_FORMAT_NV12:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static VkResult
|
|
|
|
|
vn_android_get_modifier_properties(struct vn_device *dev,
|
|
|
|
|
VkFormat format,
|
|
|
|
|
uint64_t modifier,
|
|
|
|
|
VkDrmFormatModifierPropertiesEXT *out_props)
|
|
|
|
|
{
|
|
|
|
|
VkPhysicalDevice physical_device =
|
|
|
|
|
vn_physical_device_to_handle(dev->physical_device);
|
|
|
|
|
VkDrmFormatModifierPropertiesListEXT mod_prop_list = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
|
|
|
|
|
};
|
|
|
|
|
VkFormatProperties2 format_prop = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
|
|
|
|
|
.pNext = &mod_prop_list,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vn_GetPhysicalDeviceFormatProperties2(physical_device, format,
|
|
|
|
|
&format_prop);
|
|
|
|
|
|
|
|
|
|
if (!mod_prop_list.drmFormatModifierCount) {
|
|
|
|
|
vn_log(dev->instance, "No compatible modifier for VkFormat(%u)",
|
|
|
|
|
format);
|
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STACK_ARRAY(VkDrmFormatModifierPropertiesEXT, mod_props,
|
|
|
|
|
mod_prop_list.drmFormatModifierCount);
|
|
|
|
|
|
|
|
|
|
mod_prop_list.pDrmFormatModifierProperties = mod_props;
|
|
|
|
|
vn_GetPhysicalDeviceFormatProperties2(physical_device, format,
|
|
|
|
|
&format_prop);
|
|
|
|
|
|
|
|
|
|
bool modifier_found = false;
|
|
|
|
|
for (uint32_t i = 0; i < mod_prop_list.drmFormatModifierCount; i++) {
|
|
|
|
|
if (mod_props[i].drmFormatModifier == modifier) {
|
|
|
|
|
*out_props = mod_props[i];
|
|
|
|
|
modifier_found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STACK_ARRAY_FINISH(mod_props);
|
|
|
|
|
|
|
|
|
|
if (!modifier_found) {
|
|
|
|
|
vn_log(dev->instance,
|
|
|
|
|
"No matching modifier(%" PRIu64 ") properties for VkFormat(%u)",
|
|
|
|
|
modifier, format);
|
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct vn_android_image_builder {
|
|
|
|
|
VkImageCreateInfo create;
|
|
|
|
|
VkSubresourceLayout layouts[4];
|
|
|
|
@@ -513,181 +418,6 @@ vn_android_get_wsi_memory_from_bind_info(
|
|
|
|
|
return img->wsi.memory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static VkResult
|
|
|
|
|
vn_android_get_ahb_format_properties(
|
|
|
|
|
struct vn_device *dev,
|
|
|
|
|
const struct AHardwareBuffer *ahb,
|
|
|
|
|
VkAndroidHardwareBufferFormatPropertiesANDROID *out_props)
|
|
|
|
|
{
|
|
|
|
|
AHardwareBuffer_Desc desc;
|
|
|
|
|
VkFormat format;
|
|
|
|
|
struct vn_android_gralloc_buffer_properties buf_props;
|
|
|
|
|
VkDrmFormatModifierPropertiesEXT mod_props;
|
|
|
|
|
|
|
|
|
|
AHardwareBuffer_describe(ahb, &desc);
|
|
|
|
|
if (!(desc.usage & (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
|
|
|
|
|
AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
|
|
|
|
|
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER))) {
|
|
|
|
|
vn_log(dev->instance,
|
|
|
|
|
"AHB usage(%" PRIu64 ") must include at least one GPU bit",
|
|
|
|
|
desc.usage);
|
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Handle the special AHARDWAREBUFFER_FORMAT_BLOB for VkBuffer case. */
|
|
|
|
|
if (desc.format == AHARDWAREBUFFER_FORMAT_BLOB) {
|
|
|
|
|
out_props->format = VK_FORMAT_UNDEFINED;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!vn_android_gralloc_get_buffer_properties(
|
|
|
|
|
AHardwareBuffer_getNativeHandle(ahb), &buf_props))
|
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
|
|
|
|
|
|
|
|
/* We implement AHB extension support with EXT_image_drm_format_modifier.
|
|
|
|
|
* It requires us to have a compatible VkFormat but not DRM formats. So if
|
|
|
|
|
* the ahb is not intended for backing a VkBuffer, error out early if the
|
|
|
|
|
* format is VK_FORMAT_UNDEFINED.
|
|
|
|
|
*/
|
|
|
|
|
format = vn_android_drm_format_to_vk_format(buf_props.drm_fourcc);
|
|
|
|
|
if (format == VK_FORMAT_UNDEFINED) {
|
|
|
|
|
vn_log(dev->instance, "Unknown drm_fourcc(%u) from AHB format(0x%X)",
|
|
|
|
|
buf_props.drm_fourcc, desc.format);
|
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult result = vn_android_get_modifier_properties(
|
|
|
|
|
dev, format, buf_props.modifier, &mod_props);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
if (mod_props.drmFormatModifierPlaneCount != buf_props.num_planes) {
|
|
|
|
|
vn_log(dev->instance,
|
|
|
|
|
"drmFormatModifierPlaneCount(%u) != buf_props.num_planes(%u) "
|
|
|
|
|
"for DRM format modifier(%" PRIu64 ")",
|
|
|
|
|
mod_props.drmFormatModifierPlaneCount, buf_props.num_planes,
|
|
|
|
|
buf_props.modifier);
|
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The spec requires that formatFeatures must include at least one of
|
|
|
|
|
* VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
|
|
|
|
|
* VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT.
|
|
|
|
|
*/
|
|
|
|
|
const VkFormatFeatureFlags format_features =
|
|
|
|
|
mod_props.drmFormatModifierTilingFeatures |
|
|
|
|
|
VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
|
|
|
|
|
|
|
|
|
|
/* 11.2.7. Android Hardware Buffer External Memory
|
|
|
|
|
*
|
|
|
|
|
* Implementations may not always be able to determine the color model,
|
|
|
|
|
* numerical range, or chroma offsets of the image contents, so the values
|
|
|
|
|
* in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
|
|
|
|
|
* Applications should treat these values as sensible defaults to use in the
|
|
|
|
|
* absence of more reliable information obtained through some other means.
|
|
|
|
|
*/
|
|
|
|
|
const bool is_yuv = vn_android_drm_format_is_yuv(buf_props.drm_fourcc);
|
|
|
|
|
const VkSamplerYcbcrModelConversion model =
|
|
|
|
|
is_yuv ? VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601
|
|
|
|
|
: VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
|
|
|
|
|
|
|
|
|
|
/* ANGLE expects VK_FORMAT_UNDEFINED with externalFormat resolved from
|
|
|
|
|
* AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED and any supported planar
|
|
|
|
|
* AHB formats. Venus supports below explicit ones:
|
|
|
|
|
* - AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 (DRM_FORMAT_NV12)
|
|
|
|
|
* - AHARDWAREBUFFER_FORMAT_YV12 (DRM_FORMAT_YVU420)
|
|
|
|
|
*/
|
|
|
|
|
if (desc.format == AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED || is_yuv)
|
|
|
|
|
format = VK_FORMAT_UNDEFINED;
|
|
|
|
|
|
|
|
|
|
*out_props = (VkAndroidHardwareBufferFormatPropertiesANDROID) {
|
|
|
|
|
.sType = out_props->sType,
|
|
|
|
|
.pNext = out_props->pNext,
|
|
|
|
|
.format = format,
|
|
|
|
|
.externalFormat = buf_props.drm_fourcc,
|
|
|
|
|
.formatFeatures = format_features,
|
|
|
|
|
.samplerYcbcrConversionComponents = {
|
|
|
|
|
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
|
|
|
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
|
|
|
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
|
|
|
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
|
|
|
},
|
|
|
|
|
.suggestedYcbcrModel = model,
|
|
|
|
|
/* match EGL_YUV_NARROW_RANGE_EXT used in egl platform_android */
|
|
|
|
|
.suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
|
|
|
|
|
.suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT,
|
|
|
|
|
.suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult
|
|
|
|
|
vn_GetAndroidHardwareBufferPropertiesANDROID(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
const struct AHardwareBuffer *buffer,
|
|
|
|
|
VkAndroidHardwareBufferPropertiesANDROID *pProperties)
|
|
|
|
|
{
|
|
|
|
|
VN_TRACE_FUNC();
|
|
|
|
|
struct vn_device *dev = vn_device_from_handle(device);
|
|
|
|
|
VkResult result = VK_SUCCESS;
|
|
|
|
|
int dma_buf_fd = -1;
|
|
|
|
|
uint64_t alloc_size = 0;
|
|
|
|
|
uint32_t mem_type_bits = 0;
|
|
|
|
|
|
|
|
|
|
VkAndroidHardwareBufferFormatProperties2ANDROID *format_props2 =
|
|
|
|
|
vk_find_struct(pProperties->pNext,
|
|
|
|
|
ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
|
|
|
|
|
VkAndroidHardwareBufferFormatPropertiesANDROID *format_props =
|
|
|
|
|
vk_find_struct(pProperties->pNext,
|
|
|
|
|
ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
|
|
|
|
|
if (format_props2 || format_props) {
|
|
|
|
|
VkAndroidHardwareBufferFormatPropertiesANDROID local_props = {
|
|
|
|
|
.sType =
|
|
|
|
|
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
|
|
|
|
|
};
|
|
|
|
|
if (!format_props)
|
|
|
|
|
format_props = &local_props;
|
|
|
|
|
|
|
|
|
|
result =
|
|
|
|
|
vn_android_get_ahb_format_properties(dev, buffer, format_props);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return vn_error(dev->instance, result);
|
|
|
|
|
|
|
|
|
|
if (format_props2) {
|
|
|
|
|
format_props2->format = format_props->format;
|
|
|
|
|
format_props2->externalFormat = format_props->externalFormat;
|
|
|
|
|
format_props2->formatFeatures =
|
|
|
|
|
(VkFormatFeatureFlags2)format_props->formatFeatures;
|
|
|
|
|
format_props2->samplerYcbcrConversionComponents =
|
|
|
|
|
format_props->samplerYcbcrConversionComponents;
|
|
|
|
|
format_props2->suggestedYcbcrModel =
|
|
|
|
|
format_props->suggestedYcbcrModel;
|
|
|
|
|
format_props2->suggestedYcbcrRange =
|
|
|
|
|
format_props->suggestedYcbcrRange;
|
|
|
|
|
format_props2->suggestedXChromaOffset =
|
|
|
|
|
format_props->suggestedXChromaOffset;
|
|
|
|
|
format_props2->suggestedYChromaOffset =
|
|
|
|
|
format_props->suggestedYChromaOffset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dma_buf_fd = vn_android_gralloc_get_dma_buf_fd(
|
|
|
|
|
AHardwareBuffer_getNativeHandle(buffer));
|
|
|
|
|
if (dma_buf_fd < 0)
|
|
|
|
|
return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
|
|
|
|
|
|
|
|
|
result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size,
|
|
|
|
|
&mem_type_bits);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return vn_error(dev->instance, result);
|
|
|
|
|
|
|
|
|
|
pProperties->allocationSize = alloc_size;
|
|
|
|
|
pProperties->memoryTypeBits = mem_type_bits;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static AHardwareBuffer *
|
|
|
|
|
vn_android_ahb_allocate(uint32_t width,
|
|
|
|
|
uint32_t height,
|
|
|
|
|