mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-24 10:20:22 +01:00
This uses DETECT_OS_ANDROID instead of defined(ANDROID). This better supports glibc based host builds in the Soong build system. Reviewed-by: Aaron Ruby <aruby@blackberry.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26874>
221 lines
8.3 KiB
C
221 lines
8.3 KiB
C
/*
|
|
* Copyright © 2023 Collabora, Ltd.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include "vk_device_memory.h"
|
|
|
|
#include "vk_android.h"
|
|
#include "vk_common_entrypoints.h"
|
|
#include "vk_util.h"
|
|
|
|
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26
|
|
#include <vndk/hardware_buffer.h>
|
|
#endif
|
|
|
|
void *
|
|
vk_device_memory_create(struct vk_device *device,
|
|
const VkMemoryAllocateInfo *pAllocateInfo,
|
|
const VkAllocationCallbacks *alloc,
|
|
size_t size)
|
|
{
|
|
struct vk_device_memory *mem =
|
|
vk_object_zalloc(device, alloc, size, VK_OBJECT_TYPE_DEVICE_MEMORY);
|
|
if (mem == NULL)
|
|
return NULL;
|
|
|
|
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
|
|
|
mem->size = pAllocateInfo->allocationSize;
|
|
mem->memory_type_index = pAllocateInfo->memoryTypeIndex;
|
|
|
|
vk_foreach_struct_const(ext, pAllocateInfo->pNext) {
|
|
switch (ext->sType) {
|
|
case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO: {
|
|
const VkExportMemoryAllocateInfo *export_info = (void *)ext;
|
|
mem->export_handle_types = export_info->handleTypes;
|
|
break;
|
|
}
|
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID: {
|
|
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26
|
|
const VkImportAndroidHardwareBufferInfoANDROID *ahb_info = (void *)ext;
|
|
|
|
assert(mem->import_handle_type == 0);
|
|
mem->import_handle_type =
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
|
|
|
|
/* From the Vulkan 1.3.242 spec:
|
|
*
|
|
* "If the vkAllocateMemory command succeeds, the implementation
|
|
* must acquire a reference to the imported hardware buffer, which
|
|
* it must release when the device memory object is freed. If the
|
|
* command fails, the implementation must not retain a
|
|
* reference."
|
|
*
|
|
* We assume that if the driver fails to create its memory object,
|
|
* it will call vk_device_memory_destroy which will delete our
|
|
* reference.
|
|
*/
|
|
AHardwareBuffer_acquire(ahb_info->buffer);
|
|
mem->ahardware_buffer = ahb_info->buffer;
|
|
break;
|
|
#else
|
|
unreachable("AHardwareBuffer import requires Android >= 26");
|
|
#endif /* DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26 */
|
|
}
|
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR: {
|
|
const VkImportMemoryFdInfoKHR *fd_info = (void *)ext;
|
|
if (fd_info->handleType) {
|
|
assert(fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
|
fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
|
assert(mem->import_handle_type == 0);
|
|
mem->import_handle_type = fd_info->handleType;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT: {
|
|
const VkImportMemoryHostPointerInfoEXT *host_ptr_info = (void *)ext;
|
|
if (host_ptr_info->handleType) {
|
|
assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT ||
|
|
host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT);
|
|
|
|
assert(mem->import_handle_type == 0);
|
|
mem->import_handle_type = host_ptr_info->handleType;
|
|
mem->host_ptr = host_ptr_info->pHostPointer;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR: {
|
|
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
|
const VkImportMemoryWin32HandleInfoKHR *w32h_info = (void *)ext;
|
|
if (w32h_info->handleType) {
|
|
assert(w32h_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT ||
|
|
w32h_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT ||
|
|
w32h_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT ||
|
|
w32h_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT ||
|
|
w32h_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT ||
|
|
w32h_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT);
|
|
assert(mem->import_handle_type == 0);
|
|
mem->import_handle_type = w32h_info->handleType;
|
|
}
|
|
break;
|
|
#else
|
|
unreachable("Win32 platform support disabled");
|
|
#endif
|
|
}
|
|
|
|
case VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO: {
|
|
const VkMemoryAllocateFlagsInfo *flags_info = (void *)ext;
|
|
mem->alloc_flags = flags_info->flags;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* From the Vulkan Specification 1.3.261:
|
|
*
|
|
* VUID-VkMemoryAllocateInfo-allocationSize-07897
|
|
*
|
|
* "If the parameters do not define an import or export operation,
|
|
* allocationSize must be greater than 0."
|
|
*/
|
|
if (!mem->import_handle_type && !mem->export_handle_types)
|
|
assert(pAllocateInfo->allocationSize > 0);
|
|
|
|
/* From the Vulkan Specification 1.3.261:
|
|
*
|
|
* VUID-VkMemoryAllocateInfo-allocationSize-07899
|
|
*
|
|
* "If the parameters define an export operation and the handle type is
|
|
* not VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
|
|
* allocationSize must be greater than 0."
|
|
*/
|
|
if (mem->export_handle_types &&
|
|
mem->export_handle_types !=
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
|
|
assert(pAllocateInfo->allocationSize > 0);
|
|
|
|
if ((mem->export_handle_types &
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) &&
|
|
mem->ahardware_buffer == NULL) {
|
|
/* If we need to be able to export an Android hardware buffer but none
|
|
* is provided as an import, create a new one.
|
|
*/
|
|
mem->ahardware_buffer = vk_alloc_ahardware_buffer(pAllocateInfo);
|
|
if (mem->ahardware_buffer == NULL) {
|
|
vk_device_memory_destroy(device, alloc, mem);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return mem;
|
|
}
|
|
|
|
void
|
|
vk_device_memory_destroy(struct vk_device *device,
|
|
const VkAllocationCallbacks *alloc,
|
|
struct vk_device_memory *mem)
|
|
{
|
|
|
|
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26
|
|
if (mem->ahardware_buffer)
|
|
AHardwareBuffer_release(mem->ahardware_buffer);
|
|
#endif /* DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26 */
|
|
|
|
vk_object_free(device, alloc, mem);
|
|
}
|
|
|
|
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26
|
|
VkResult
|
|
vk_common_GetMemoryAndroidHardwareBufferANDROID(
|
|
VkDevice _device,
|
|
const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
|
|
struct AHardwareBuffer **pBuffer)
|
|
{
|
|
VK_FROM_HANDLE(vk_device_memory, mem, pInfo->memory);
|
|
|
|
/* Some quotes from Vulkan spec:
|
|
*
|
|
* "If the device memory was created by importing an Android hardware
|
|
* buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
|
|
* Android hardware buffer object."
|
|
*
|
|
* "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
|
|
* must have been included in VkExportMemoryAllocateInfo::handleTypes
|
|
* when memory was created."
|
|
*/
|
|
if (mem->ahardware_buffer) {
|
|
*pBuffer = mem->ahardware_buffer;
|
|
/* Increase refcount. */
|
|
AHardwareBuffer_acquire(*pBuffer);
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
}
|
|
#endif
|