vulkan/android: Add common helpers for the ANB extension

Change-Id: I999121edfc7163cecc83897eb7be73896de36d89
Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
Tested-by: tarsin <yuanqingxiang233@163.com>
Acked-by: David Heidelberg <david.heidelberg@collabora.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25360>
This commit is contained in:
Roman Stratiienko
2023-09-22 23:00:56 +03:00
committed by Marge Bot
parent 3b0f0b0ab9
commit d0996d1a30
4 changed files with 168 additions and 0 deletions

View File

@@ -23,6 +23,7 @@
#include "vk_android.h" #include "vk_android.h"
#include "vk_alloc.h"
#include "vk_common_entrypoints.h" #include "vk_common_entrypoints.h"
#include "vk_device.h" #include "vk_device.h"
#include "vk_physical_device.h" #include "vk_physical_device.h"
@@ -31,7 +32,10 @@
#include "vk_queue.h" #include "vk_queue.h"
#include "vk_util.h" #include "vk_util.h"
#include "drm-uapi/drm_fourcc.h"
#include "util/libsync.h" #include "util/libsync.h"
#include "util/os_file.h"
#include "util/u_gralloc/u_gralloc.h"
#include <hardware/gralloc.h> #include <hardware/gralloc.h>
@@ -198,6 +202,132 @@ vk_common_GetSwapchainGrallocUsage2ANDROID(
return VK_SUCCESS; return VK_SUCCESS;
} }
static VkResult
vk_gralloc_to_drm_explicit_layout(
struct u_gralloc_buffer_handle *in_hnd,
VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
VkSubresourceLayout *out_layouts, int max_planes)
{
struct u_gralloc_buffer_basic_info info;
struct u_gralloc *u_gralloc = vk_android_get_ugralloc();
assert(u_gralloc);
if (u_gralloc_get_buffer_basic_info(u_gralloc, in_hnd, &info) != 0)
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
if (info.num_planes > max_planes)
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
bool is_disjoint = false;
for (size_t i = 1; i < info.num_planes; i++) {
if (info.offsets[i] == 0) {
is_disjoint = true;
break;
}
}
if (is_disjoint) {
/* We don't support disjoint planes yet */
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
memset(out, 0, sizeof(*out));
memset(out_layouts, 0, sizeof(*out_layouts) * max_planes);
out->sType =
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
out->pPlaneLayouts = out_layouts;
out->drmFormatModifier = info.modifier;
out->drmFormatModifierPlaneCount = info.num_planes;
for (size_t i = 0; i < info.num_planes; i++) {
out_layouts[i].offset = info.offsets[i];
out_layouts[i].rowPitch = info.strides[i];
}
if (info.drm_fourcc == DRM_FORMAT_YVU420) {
/* Swap the U and V planes to match the
* VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM */
VkSubresourceLayout tmp = out_layouts[1];
out_layouts[1] = out_layouts[2];
out_layouts[2] = tmp;
}
return VK_SUCCESS;
}
VkResult
vk_android_import_anb(struct vk_device *device,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *alloc,
struct vk_image *image)
{
VkResult result;
const VkNativeBufferANDROID *native_buffer =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
assert(native_buffer);
assert(native_buffer->handle);
assert(native_buffer->handle->numFds > 0);
const VkMemoryDedicatedAllocateInfo ded_alloc = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = NULL,
.buffer = VK_NULL_HANDLE,
.image = (VkImage)image};
const VkImportMemoryFdInfoKHR import_info = {
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
.pNext = &ded_alloc,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
.fd = os_dupfd_cloexec(native_buffer->handle->data[0]),
};
result = device->dispatch_table.AllocateMemory(
(VkDevice)device,
&(VkMemoryAllocateInfo){
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &import_info,
.allocationSize = lseek(import_info.fd, 0, SEEK_END),
.memoryTypeIndex = 0, /* Should we be smarter here? */
},
alloc, &image->anb_memory);
if (result != VK_SUCCESS) {
close(import_info.fd);
return result;
}
VkBindImageMemoryInfo bind_info = {
.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
.image = (VkImage)image,
.memory = image->anb_memory,
.memoryOffset = 0,
};
return device->dispatch_table.BindImageMemory2((VkDevice)device, 1, &bind_info);
}
VkResult
vk_android_get_anb_layout(
const VkImageCreateInfo *pCreateInfo,
VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
VkSubresourceLayout *out_layouts, int max_planes)
{
const VkNativeBufferANDROID *native_buffer =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
struct u_gralloc_buffer_handle gr_handle = {
.handle = native_buffer->handle,
.hal_format = native_buffer->format,
.pixel_stride = native_buffer->stride,
};
return vk_gralloc_to_drm_explicit_layout(&gr_handle, out,
out_layouts, max_planes);
}
/* From the Android hardware_buffer.h header: /* From the Android hardware_buffer.h header:
* *
* "The buffer will be written to by the GPU as a framebuffer attachment. * "The buffer will be written to by the GPU as a framebuffer attachment.

View File

@@ -23,6 +23,8 @@
#ifndef VK_ANDROID_H #ifndef VK_ANDROID_H
#define VK_ANDROID_H #define VK_ANDROID_H
#include <stdbool.h>
#include "vulkan/vulkan_core.h" #include "vulkan/vulkan_core.h"
#include "util/detect_os.h" #include "util/detect_os.h"
@@ -32,11 +34,21 @@ extern "C" {
#endif #endif
struct u_gralloc; struct u_gralloc;
struct vk_device;
struct vk_image;
#if DETECT_OS_ANDROID #if DETECT_OS_ANDROID
struct u_gralloc *vk_android_get_ugralloc(void); struct u_gralloc *vk_android_get_ugralloc(void);
struct u_gralloc *vk_android_init_ugralloc(void); struct u_gralloc *vk_android_init_ugralloc(void);
void vk_android_destroy_ugralloc(void); void vk_android_destroy_ugralloc(void);
VkResult vk_android_import_anb(struct vk_device *device,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *alloc,
struct vk_image *image);
VkResult vk_android_get_anb_layout(
const VkImageCreateInfo *pCreateInfo,
VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
VkSubresourceLayout *out_layouts, int max_planes);
#else #else
static inline struct u_gralloc * static inline struct u_gralloc *
vk_android_get_ugralloc(void) vk_android_get_ugralloc(void)
@@ -54,6 +66,25 @@ static inline void
vk_android_destroy_ugralloc(void) vk_android_destroy_ugralloc(void)
{ {
} }
static inline VkResult
vk_android_import_anb(struct vk_device *device,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *alloc,
struct vk_image *image)
{
return VK_ERROR_FEATURE_NOT_PRESENT;
}
static inline VkResult
vk_android_get_anb_layout(
const VkImageCreateInfo *pCreateInfo,
VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
VkSubresourceLayout *out_layouts, int max_planes)
{
return VK_ERROR_FEATURE_NOT_PRESENT;
}
#endif #endif
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26 #if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26

View File

@@ -159,6 +159,12 @@ vk_image_destroy(struct vk_device *device,
const VkAllocationCallbacks *alloc, const VkAllocationCallbacks *alloc,
struct vk_image *image) struct vk_image *image)
{ {
#if DETECT_OS_ANDROID
if (image->anb_memory) {
device->dispatch_table.FreeMemory(
(VkDevice)device, image->anb_memory, alloc);
}
#endif
vk_object_free(device, alloc, image); vk_object_free(device, alloc, image);
} }

View File

@@ -90,6 +90,7 @@ struct vk_image {
#if DETECT_OS_ANDROID #if DETECT_OS_ANDROID
enum android_buffer_type android_buffer_type; enum android_buffer_type android_buffer_type;
VkDeviceMemory anb_memory;
/* AHARDWAREBUFFER_FORMAT for this image or 0 /* AHARDWAREBUFFER_FORMAT for this image or 0
* *