mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
vulkan: Add a vk_device_memory base struct
This lets us provide a vk_device_memory_range helper similar to what's provided for buffers for dealing with VK_WHOLE_SIZE. We can also handle flags and some annoyance around Android hardware buffer import. Reviewed-by: Lina Versace <lina@kiwitree.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22038>
This commit is contained in:
parent
b16cfe23ef
commit
c0cc508cd0
3 changed files with 289 additions and 0 deletions
|
|
@ -50,6 +50,8 @@ vulkan_runtime_files = files(
|
|||
'vk_descriptor_update_template.h',
|
||||
'vk_device.c',
|
||||
'vk_device.h',
|
||||
'vk_device_memory.c',
|
||||
'vk_device_memory.h',
|
||||
'vk_fence.c',
|
||||
'vk_fence.h',
|
||||
'vk_framebuffer.c',
|
||||
|
|
|
|||
200
src/vulkan/runtime/vk_device_memory.c
Normal file
200
src/vulkan/runtime/vk_device_memory.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* 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 defined(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);
|
||||
assert(pAllocateInfo->allocationSize > 0);
|
||||
|
||||
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 defined(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 /* 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;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ANDROID) && ANDROID_API_LEVEL >= 26
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
void
|
||||
vk_device_memory_destroy(struct vk_device *device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct vk_device_memory *mem)
|
||||
{
|
||||
#if defined(ANDROID) && ANDROID_API_LEVEL >= 26
|
||||
if (mem->ahardware_buffer)
|
||||
AHardwareBuffer_release(mem->ahardware_buffer);
|
||||
#endif /* ANDROID_API_LEVEL >= 26 */
|
||||
|
||||
vk_object_free(device, alloc, mem);
|
||||
}
|
||||
|
||||
#if defined(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_KHR;
|
||||
}
|
||||
#endif
|
||||
87
src/vulkan/runtime/vk_device_memory.h
Normal file
87
src/vulkan/runtime/vk_device_memory.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef VK_DEVICE_MEMORY_H
|
||||
#define VK_DEVICE_MEMORY_H
|
||||
|
||||
#include "vk_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct AHardwareBuffer;
|
||||
|
||||
struct vk_device_memory {
|
||||
struct vk_object_base base;
|
||||
|
||||
/* VkMemoryAllocateFlagsInfo::flags */
|
||||
VkMemoryAllocateFlags alloc_flags;
|
||||
|
||||
/* VkMemoryAllocateInfo::allocationSize */
|
||||
VkDeviceSize size;
|
||||
|
||||
/* VkMemoryAllocateInfo::memoryTypeIndex */
|
||||
uint32_t memory_type_index;
|
||||
|
||||
/* Import handle type (if any) */
|
||||
VkExternalMemoryHandleTypeFlags import_handle_type;
|
||||
|
||||
/* VkExportMemoryAllocateInfo::handleTypes */
|
||||
VkExternalMemoryHandleTypeFlags export_handle_types;
|
||||
|
||||
/* VkImportMemoryHostPointerInfoEXT::pHostPointer */
|
||||
void *host_ptr;
|
||||
|
||||
/* VkImportAndroidHardwareBufferInfoANDROID::buffer */
|
||||
struct AHardwareBuffer *ahardware_buffer;
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_device_memory, base, VkDeviceMemory,
|
||||
VK_OBJECT_TYPE_DEVICE_MEMORY);
|
||||
|
||||
void *vk_device_memory_create(struct vk_device *device,
|
||||
const VkMemoryAllocateInfo *pAllocateInfo,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
size_t size);
|
||||
void vk_device_memory_destroy(struct vk_device *device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct vk_device_memory *mem);
|
||||
|
||||
static inline uint64_t
|
||||
vk_device_memory_range(const struct vk_device_memory *mem,
|
||||
uint64_t offset, uint64_t range)
|
||||
{
|
||||
assert(offset <= mem->size);
|
||||
if (range == VK_WHOLE_SIZE) {
|
||||
return mem->size - offset;
|
||||
} else {
|
||||
assert(range + offset >= range);
|
||||
assert(range + offset <= mem->size);
|
||||
return range;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VK_DEVICE_MEMORY_H */
|
||||
Loading…
Add table
Reference in a new issue