diff --git a/src/broadcom/vulkan/v3dv_android.c b/src/broadcom/vulkan/v3dv_android.c index 4a8f431d269..99410a15b24 100644 --- a/src/broadcom/vulkan/v3dv_android.c +++ b/src/broadcom/vulkan/v3dv_android.c @@ -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: diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 9214fc5b70e..aafcd1b3968 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -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 #include @@ -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 */ diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c index 08703ba00a9..72048becbc6 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -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); diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 6227c5b16d3..2b1e98672e2 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -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 };