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:
committed by
Marge Bot
parent
179dc4a106
commit
02fc0c7e6a
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user