vulkan/android: Add common vkGetAndroidHardwareBufferPropertiesANDROID
Change-Id: I1a7542c6eed7ebf00241bce7fd69840a9007ed27 Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com> Tested-by: tarsin <yuanqingxiang233@163.com> Reviewed-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25360>
This commit is contained in:

committed by
Marge Bot

parent
e8f7e7582a
commit
8732a619f1
@@ -32,10 +32,13 @@
|
||||
#include "vk_queue.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#include "vulkan/util/vk_enum_defines.h"
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "util/libsync.h"
|
||||
#include "util/os_file.h"
|
||||
#include "util/u_gralloc/u_gralloc.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#include <hardware/gralloc.h>
|
||||
|
||||
@@ -524,6 +527,185 @@ vk_alloc_ahardware_buffer(const VkMemoryAllocateInfo *pAllocateInfo)
|
||||
|
||||
return ahb;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
get_ahb_buffer_format_properties2(
|
||||
struct vk_device *device, const struct AHardwareBuffer *buffer,
|
||||
VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties)
|
||||
{
|
||||
/* Get a description of buffer contents . */
|
||||
AHardwareBuffer_Desc desc;
|
||||
AHardwareBuffer_describe(buffer, &desc);
|
||||
|
||||
/* Verify description. */
|
||||
bool gpu_usage = desc.usage & (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
|
||||
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
|
||||
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER);
|
||||
|
||||
/* "Buffer must be a valid Android hardware buffer object with at least
|
||||
* one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
|
||||
*/
|
||||
if (!gpu_usage)
|
||||
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||
|
||||
/* Fill properties fields based on description. */
|
||||
VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties;
|
||||
|
||||
p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
|
||||
p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
|
||||
p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
|
||||
|
||||
p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
|
||||
p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
|
||||
|
||||
VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
|
||||
|
||||
p->format = vk_ahb_format_to_image_format(desc.format);
|
||||
|
||||
VkFormat external_format = p->format;
|
||||
|
||||
if (p->format != VK_FORMAT_UNDEFINED)
|
||||
goto finish;
|
||||
|
||||
/* External format only case
|
||||
*
|
||||
* From vkGetAndroidHardwareBufferPropertiesANDROID spec:
|
||||
* "If the Android hardware buffer has one of the formats listed in the Format
|
||||
* Equivalence table (see spec.), then format must have the equivalent Vulkan
|
||||
* format listed in the table. Otherwise, format may be VK_FORMAT_UNDEFINED,
|
||||
* indicating the Android hardware buffer can only be used with an external format."
|
||||
*
|
||||
* From SKIA source code analysis: p->format MUST be VK_FORMAT_UNDEFINED, if the
|
||||
* format is not in the Equivalence table.
|
||||
*/
|
||||
|
||||
struct u_gralloc_buffer_handle gr_handle = {
|
||||
.handle = AHardwareBuffer_getNativeHandle(buffer),
|
||||
.pixel_stride = desc.stride,
|
||||
.hal_format = desc.format,
|
||||
};
|
||||
|
||||
struct u_gralloc_buffer_basic_info info;
|
||||
|
||||
if (u_gralloc_get_buffer_basic_info(vk_android_get_ugralloc(), &gr_handle, &info) != 0)
|
||||
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||
|
||||
switch (info.drm_fourcc) {
|
||||
case DRM_FORMAT_YVU420:
|
||||
/* Assuming that U and V planes are swapped earlier */
|
||||
external_format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
|
||||
break;
|
||||
case DRM_FORMAT_NV12:
|
||||
external_format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
break;
|
||||
default:;
|
||||
mesa_loge("Unsupported external DRM format: %d", info.drm_fourcc);
|
||||
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||
}
|
||||
|
||||
struct u_gralloc_buffer_color_info color_info;
|
||||
if (u_gralloc_get_buffer_color_info(vk_android_get_ugralloc(), &gr_handle, &color_info) == 0) {
|
||||
switch (color_info.yuv_color_space) {
|
||||
case __DRI_YUV_COLOR_SPACE_ITU_REC601:
|
||||
p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
|
||||
break;
|
||||
case __DRI_YUV_COLOR_SPACE_ITU_REC709:
|
||||
p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709;
|
||||
break;
|
||||
case __DRI_YUV_COLOR_SPACE_ITU_REC2020:
|
||||
p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p->suggestedYcbcrRange = (color_info.sample_range == __DRI_YUV_NARROW_RANGE) ?
|
||||
VK_SAMPLER_YCBCR_RANGE_ITU_NARROW : VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
|
||||
p->suggestedXChromaOffset = (color_info.horizontal_siting == __DRI_YUV_CHROMA_SITING_0_5) ?
|
||||
VK_CHROMA_LOCATION_MIDPOINT : VK_CHROMA_LOCATION_COSITED_EVEN;
|
||||
p->suggestedYChromaOffset = (color_info.vertical_siting == __DRI_YUV_CHROMA_SITING_0_5) ?
|
||||
VK_CHROMA_LOCATION_MIDPOINT : VK_CHROMA_LOCATION_COSITED_EVEN;
|
||||
}
|
||||
|
||||
finish:
|
||||
|
||||
device->physical->dispatch_table.GetPhysicalDeviceFormatProperties2(
|
||||
(VkPhysicalDevice)device->physical, external_format, &format_properties);
|
||||
|
||||
p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
|
||||
p->externalFormat = external_format;
|
||||
|
||||
/* From vkGetAndroidHardwareBufferPropertiesANDROID spec:
|
||||
* "The formatFeatures member *must* include
|
||||
* VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT and at least one of
|
||||
* VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT or
|
||||
* VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT"
|
||||
*/
|
||||
p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_common_GetAndroidHardwareBufferPropertiesANDROID(
|
||||
VkDevice device_h, const struct AHardwareBuffer *buffer,
|
||||
VkAndroidHardwareBufferPropertiesANDROID *pProperties)
|
||||
{
|
||||
VK_FROM_HANDLE(vk_device, device, device_h);
|
||||
struct vk_physical_device *pdevice = device->physical;
|
||||
|
||||
VkResult result;
|
||||
|
||||
VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
|
||||
vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
|
||||
|
||||
/* Fill format properties of an Android hardware buffer. */
|
||||
if (format_prop) {
|
||||
VkAndroidHardwareBufferFormatProperties2ANDROID format_prop2 = {
|
||||
.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID,
|
||||
};
|
||||
result = get_ahb_buffer_format_properties2(device, buffer, &format_prop2);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
format_prop->format = format_prop2.format;
|
||||
format_prop->externalFormat = format_prop2.externalFormat;
|
||||
format_prop->formatFeatures =
|
||||
vk_format_features2_to_features(format_prop2.formatFeatures);
|
||||
format_prop->samplerYcbcrConversionComponents =
|
||||
format_prop2.samplerYcbcrConversionComponents;
|
||||
format_prop->suggestedYcbcrModel = format_prop2.suggestedYcbcrModel;
|
||||
format_prop->suggestedYcbcrRange = format_prop2.suggestedYcbcrRange;
|
||||
format_prop->suggestedXChromaOffset = format_prop2.suggestedXChromaOffset;
|
||||
format_prop->suggestedYChromaOffset = format_prop2.suggestedYChromaOffset;
|
||||
}
|
||||
|
||||
VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
|
||||
vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
|
||||
if (format_prop2) {
|
||||
result = get_ahb_buffer_format_properties2(device, buffer, format_prop2);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
const native_handle_t *handle = AHardwareBuffer_getNativeHandle(buffer);
|
||||
assert(handle && handle->numFds > 0);
|
||||
pProperties->allocationSize = lseek(handle->data[0], 0, SEEK_END);
|
||||
|
||||
VkPhysicalDeviceMemoryProperties mem_props;
|
||||
|
||||
device->physical->dispatch_table.GetPhysicalDeviceMemoryProperties(
|
||||
(VkPhysicalDevice)pdevice, &mem_props);
|
||||
|
||||
/* All memory types. (Should we be smarter than this?) */
|
||||
pProperties->memoryTypeBits = (1u << mem_props.memoryTypeCount) - 1;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
#endif /* ANDROID_API_LEVEL >= 26 */
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
|
Reference in New Issue
Block a user