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:

committed by
Marge Bot

parent
3b0f0b0ab9
commit
d0996d1a30
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "vk_android.h"
|
||||
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_common_entrypoints.h"
|
||||
#include "vk_device.h"
|
||||
#include "vk_physical_device.h"
|
||||
@@ -31,7 +32,10 @@
|
||||
#include "vk_queue.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "util/libsync.h"
|
||||
#include "util/os_file.h"
|
||||
#include "util/u_gralloc/u_gralloc.h"
|
||||
|
||||
#include <hardware/gralloc.h>
|
||||
|
||||
@@ -198,6 +202,132 @@ vk_common_GetSwapchainGrallocUsage2ANDROID(
|
||||
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:
|
||||
*
|
||||
* "The buffer will be written to by the GPU as a framebuffer attachment.
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#ifndef VK_ANDROID_H
|
||||
#define VK_ANDROID_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#include "util/detect_os.h"
|
||||
@@ -32,11 +34,21 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct u_gralloc;
|
||||
struct vk_device;
|
||||
struct vk_image;
|
||||
|
||||
#if DETECT_OS_ANDROID
|
||||
struct u_gralloc *vk_android_get_ugralloc(void);
|
||||
struct u_gralloc *vk_android_init_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
|
||||
static inline struct u_gralloc *
|
||||
vk_android_get_ugralloc(void)
|
||||
@@ -54,6 +66,25 @@ static inline 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
|
||||
|
||||
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26
|
||||
|
@@ -159,6 +159,12 @@ vk_image_destroy(struct vk_device *device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@@ -90,6 +90,7 @@ struct vk_image {
|
||||
|
||||
#if DETECT_OS_ANDROID
|
||||
enum android_buffer_type android_buffer_type;
|
||||
VkDeviceMemory anb_memory;
|
||||
|
||||
/* AHARDWAREBUFFER_FORMAT for this image or 0
|
||||
*
|
||||
|
Reference in New Issue
Block a user