mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 02:10:11 +01:00
lavapipe: Always use dma-buf for external memory when we can
This makes lavapipe act like other DRM drivers whenever we have udmabuf
and just make everything a dma-buf even if it doesn't strictly have to
be. Without this we can end up in weird cases if the client asks to
allocate a memory object with multiple export types. Before, if this
happened, we would allocate a memfd and then return that when the client
calls GetMemoryFd() even if they asked for a dma-buf. In theory, we
could add additional plumbing to allow for using the memfd itself for
OPAQUE_FD and only wrap in a udmabuf if DMA_BUF is requested but this is
simpler and more in line with what hardware DRM drivers do.
Fixes: c1657de63c ("lavapipe: support VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13798
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37067>
This commit is contained in:
parent
16cd5e0244
commit
31f0d0732e
1 changed files with 51 additions and 6 deletions
|
|
@ -307,6 +307,49 @@ assert_memhandle_type(VkExternalMemoryHandleTypeFlags types)
|
|||
return types == 0;
|
||||
}
|
||||
|
||||
static enum lvp_device_memory_type
|
||||
lvp_device_memory_type_for_handle_types(const struct lvp_physical_device *pdevice,
|
||||
VkExternalMemoryHandleTypeFlags types)
|
||||
{
|
||||
if (types == 0)
|
||||
return LVP_DEVICE_MEMORY_TYPE_DEFAULT;
|
||||
|
||||
#ifdef PIPE_MEMORY_FD
|
||||
if (types & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)) {
|
||||
assert(!(types & ~(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)));
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
int dmabuf_bits = DRM_PRIME_CAP_EXPORT | DRM_PRIME_CAP_IMPORT;
|
||||
if ((pdevice->pscreen->caps.dmabuf & dmabuf_bits) == dmabuf_bits) {
|
||||
/* If we have full dma-buf support, everything is a dma-buf */
|
||||
return LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
|
||||
}
|
||||
|
||||
if (types & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
|
||||
/* dma-buf is only supported for import so if we see dma-buf it has
|
||||
* to come by itself.
|
||||
*/
|
||||
assert(types == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
||||
return LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(types == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
|
||||
return LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (types & VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT) {
|
||||
/* These can only be used for import so it's a single bit */
|
||||
assert(util_bitcount(types) == 1);
|
||||
return LVP_DEVICE_MEMORY_TYPE_USER_PTR;
|
||||
}
|
||||
|
||||
UNREACHABLE("Unsupported import/export type");
|
||||
}
|
||||
|
||||
static unsigned min_shader_cap(struct pipe_screen *pscreen,
|
||||
mesa_shader_stage shader,
|
||||
unsigned cap_offset)
|
||||
|
|
@ -2006,8 +2049,9 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
|
|||
else if (mem->vk.import_handle_type) {
|
||||
assert(import_info &&
|
||||
import_info->handleType == mem->vk.import_handle_type);
|
||||
const bool dmabuf = mem->vk.import_handle_type ==
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
const enum lvp_device_memory_type memory_type =
|
||||
lvp_device_memory_type_for_handle_types(device->physical_device, mem->vk.import_handle_type);
|
||||
const bool dmabuf = memory_type == LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
|
||||
uint64_t size;
|
||||
if(!device->pscreen->import_memory_fd(device->pscreen, import_info->fd, &mem->pmem, &size, dmabuf)) {
|
||||
error = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||
|
|
@ -2027,18 +2071,19 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
|
|||
|
||||
mem->vk.size = size;
|
||||
mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem);
|
||||
mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
|
||||
mem->memory_type = memory_type;
|
||||
}
|
||||
else if (mem->vk.export_handle_types) {
|
||||
const bool dmabuf = mem->vk.export_handle_types ==
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
const enum lvp_device_memory_type memory_type =
|
||||
lvp_device_memory_type_for_handle_types(device->physical_device, mem->vk.export_handle_types);
|
||||
const bool dmabuf = memory_type == LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
|
||||
mem->pmem = device->pscreen->allocate_memory_fd(device->pscreen, pAllocateInfo->allocationSize, &mem->backed_fd, dmabuf);
|
||||
if (!mem->pmem || mem->backed_fd < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem);
|
||||
mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
|
||||
mem->memory_type = memory_type;
|
||||
/* XXX: this should be memset_s or memset_explicit but they are not supported */
|
||||
if (mem_flags && mem_flags->flags & VK_MEMORY_ALLOCATE_ZERO_INITIALIZE_BIT_EXT)
|
||||
memset(mem->map, 0, pAllocateInfo->allocationSize);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue