v3dv/android: Rework Android native buffer importing logic

Rework it to use the existing VkImageDrmFormatModifierExplicitCreateInfoEXT
logic to set the image's explicit layout.

The code turned out to be generic enough so it could be integrated into
vk_image.c in the future and removed from the v3dv code.

Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14195>
This commit is contained in:
Roman Stratiienko
2023-09-02 22:15:33 +03:00
committed by Marge Bot
parent 179dc4a106
commit 02fc0c7e6a
4 changed files with 96 additions and 58 deletions

View File

@@ -169,11 +169,8 @@ v3dv_import_native_buffer_fd(VkDevice device_h,
const VkAllocationCallbacks *alloc,
VkImage image_h)
{
struct v3dv_image *image = NULL;
VkResult result;
image = v3dv_image_from_handle(image_h);
VkDeviceMemory memory_h;
const VkMemoryDedicatedAllocateInfo ded_alloc = {
@@ -190,13 +187,12 @@ v3dv_import_native_buffer_fd(VkDevice device_h,
.fd = os_dupfd_cloexec(native_buffer_fd),
};
assert(image->plane_count == 1);
result =
v3dv_AllocateMemory(device_h,
&(VkMemoryAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &import_info,
.allocationSize = image->planes[0].size,
.allocationSize = lseek(native_buffer_fd, 0, SEEK_END),
.memoryTypeIndex = 0,
},
alloc, &memory_h);
@@ -212,8 +208,6 @@ v3dv_import_native_buffer_fd(VkDevice device_h,
};
v3dv_BindImageMemory2(device_h, 1, &bind_info);
image->is_native_buffer_memory = true;
return VK_SUCCESS;
fail_create_image:

View File

@@ -52,6 +52,10 @@
#include "util/u_debug.h"
#include "util/format/u_format.h"
#ifdef ANDROID
#include "vk_android.h"
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
#include <xcb/xcb.h>
#include <xcb/dri3.h>
@@ -156,9 +160,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
.KHR_shader_float_controls = true,
.KHR_shader_non_semantic_info = true,
.KHR_sampler_mirror_clamp_to_edge = true,
#ifndef ANDROID
.KHR_sampler_ycbcr_conversion = true,
#endif
.KHR_spirv_1_4 = true,
.KHR_storage_buffer_storage_class = true,
.KHR_timeline_semaphore = true,
@@ -202,7 +204,9 @@ get_device_extensions(const struct v3dv_physical_device *device,
.EXT_tooling_info = true,
.EXT_vertex_attribute_divisor = true,
#ifdef ANDROID
.ANDROID_external_memory_android_hardware_buffer = true,
.ANDROID_native_buffer = true,
.EXT_queue_family_foreign = true,
#endif
};
}
@@ -285,11 +289,7 @@ get_features(const struct v3dv_physical_device *physical_device,
/* FIXME: this needs support for non-constant index on UBO/SSBO */
.variablePointers = false,
.protectedMemory = false,
#ifdef ANDROID
.samplerYcbcrConversion = false,
#else
.samplerYcbcrConversion = true,
#endif
.shaderDrawParameters = false,
/* Vulkan 1.2 */

View File

@@ -28,6 +28,9 @@
#include "util/u_math.h"
#include "vk_util.h"
#include "vulkan/wsi/wsi_common.h"
#ifdef ANDROID
#include "vk_android.h"
#endif
/**
* Computes the HW's UIFblock padding for a given height/cpp.
@@ -378,6 +381,13 @@ v3dv_image_init(struct v3dv_device *device,
uint64_t modifier = DRM_FORMAT_MOD_INVALID;
const VkImageDrmFormatModifierListCreateInfoEXT *mod_info = NULL;
const VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod_info = NULL;
#ifdef ANDROID
if (image->is_native_buffer_memory) {
assert(image->android_explicit_layout);
explicit_mod_info = image->android_explicit_layout;
modifier = explicit_mod_info->drmFormatModifier;
}
#endif
if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
mod_info =
vk_find_struct_const(pCreateInfo->pNext,
@@ -409,27 +419,6 @@ v3dv_image_init(struct v3dv_device *device,
tiling = VK_IMAGE_TILING_LINEAR;
}
#ifdef ANDROID
const VkNativeBufferANDROID *native_buffer =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
struct u_gralloc_buffer_basic_info buffer_info;
if (native_buffer != NULL) {
struct u_gralloc_buffer_handle u_gralloc_handle = {
.handle = native_buffer->handle,
.hal_format = native_buffer->format,
.pixel_stride = native_buffer->stride,
};
if (u_gralloc_get_buffer_basic_info(device->gralloc, &u_gralloc_handle, &buffer_info))
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
if (buffer_info.modifier != DRM_FORMAT_MOD_BROADCOM_UIF)
tiling = VK_IMAGE_TILING_LINEAR;
}
#endif
const struct v3dv_format *format =
v3dv_X(device, get_format)(pCreateInfo->format);
v3dv_assert(format != NULL && format->plane_count);
@@ -463,9 +452,10 @@ v3dv_image_init(struct v3dv_device *device,
ycbcr_info->planes[plane].denominator_scales[1];
}
}
image->tiled = tiling == VK_IMAGE_TILING_OPTIMAL ||
(tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
modifier != DRM_FORMAT_MOD_LINEAR);
if (modifier == DRM_FORMAT_MOD_INVALID)
modifier = (tiling == VK_IMAGE_TILING_OPTIMAL) ? DRM_FORMAT_MOD_BROADCOM_UIF
: DRM_FORMAT_MOD_LINEAR;
image->tiled = modifier != DRM_FORMAT_MOD_LINEAR;
image->vk.drm_format_mod = modifier;
@@ -484,22 +474,6 @@ v3dv_image_init(struct v3dv_device *device,
return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
}
#ifdef ANDROID
if (native_buffer != NULL) {
assert(image->plane_count == 1);
image->planes[0].slices[0].stride = buffer_info.strides[0];
image->non_disjoint_size =
image->planes[0].slices[0].size =
image->planes[0].size = lseek(buffer_info.fds[0], 0, SEEK_END);
VkResult result = v3dv_import_native_buffer_fd(v3dv_device_to_handle(device),
buffer_info.fds[0], pAllocator,
v3dv_image_to_handle(image));
if (result != VK_SUCCESS)
return result;
}
#endif
return VK_SUCCESS;
}
@@ -509,21 +483,85 @@ create_image(struct v3dv_device *device,
const VkAllocationCallbacks *pAllocator,
VkImage *pImage)
{
VkResult result;
struct v3dv_image *image = NULL;
image = vk_image_create(&device->vk, pCreateInfo, pAllocator, sizeof(*image));
if (image == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = v3dv_image_init(device, pCreateInfo, pAllocator, image);
if (result != VK_SUCCESS) {
vk_image_destroy(&device->vk, pAllocator, &image->vk);
return result;
#ifdef ANDROID
const VkExternalMemoryImageCreateInfo *external_info =
vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
const VkNativeBufferANDROID *native_buffer =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
if (native_buffer != NULL)
image->is_native_buffer_memory = true;
if (image->is_native_buffer_memory) {
image->android_explicit_layout = vk_alloc2(&device->vk.alloc, pAllocator,
sizeof(VkImageDrmFormatModifierExplicitCreateInfoEXT),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!image->android_explicit_layout) {
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
goto fail;
}
image->android_plane_layouts = vk_alloc2(&device->vk.alloc, pAllocator,
sizeof(VkSubresourceLayout) * V3DV_MAX_PLANE_COUNT,
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!image->android_plane_layouts) {
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
goto fail;
}
struct u_gralloc_buffer_handle gr_handle = {
.handle = native_buffer->handle,
.hal_format = native_buffer->format,
.pixel_stride = native_buffer->stride,
};
result = v3dv_gralloc_to_drm_explicit_layout(device->gralloc,
&gr_handle,
image->android_explicit_layout,
image->android_plane_layouts,
V3DV_MAX_PLANE_COUNT);
if (result != VK_SUCCESS)
goto fail;
}
#endif
result = v3dv_image_init(device, pCreateInfo, pAllocator, image);
if (result != VK_SUCCESS)
goto fail;
#ifdef ANDROID
if (image->is_native_buffer_memory) {
result = v3dv_import_native_buffer_fd(v3dv_device_to_handle(device),
native_buffer->handle->data[0], pAllocator,
v3dv_image_to_handle(image));
if (result != VK_SUCCESS)
goto fail;
}
#endif
*pImage = v3dv_image_to_handle(image);
return VK_SUCCESS;
fail:
#ifdef ANDROID
if (image->android_explicit_layout)
vk_free2(&device->vk.alloc, pAllocator, image->android_explicit_layout);
if (image->android_plane_layouts)
vk_free2(&device->vk.alloc, pAllocator, image->android_plane_layouts);
#endif
vk_image_destroy(&device->vk, pAllocator, &image->vk);
return result;
}
static VkResult
@@ -677,11 +715,15 @@ v3dv_DestroyImage(VkDevice _device,
}
#ifdef ANDROID
assert(image->plane_count == 1);
if (image->is_native_buffer_memory)
v3dv_FreeMemory(_device,
v3dv_device_memory_to_handle(image->planes[0].mem),
pAllocator);
if (image->android_explicit_layout)
vk_free2(&device->vk.alloc, pAllocator, image->android_explicit_layout);
if (image->android_plane_layouts)
vk_free2(&device->vk.alloc, pAllocator, image->android_plane_layouts);
#endif
vk_image_destroy(&device->vk, pAllocator, &image->vk);

View File

@@ -736,6 +736,8 @@ struct v3dv_image {
#ifdef ANDROID
/* Image is backed by VK_ANDROID_native_buffer, */
bool is_native_buffer_memory;
VkImageDrmFormatModifierExplicitCreateInfoEXT *android_explicit_layout;
VkSubresourceLayout *android_plane_layouts;
#endif
};