mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 11:00:11 +01:00
venus: rework external memory capability queries
The idea is to allow the renderer to use a completely different external memory handle type (e.g., OPAQUE_WIN32!?) than the driver (always OPAQUE_FD and DMA_BUF). It hides the mismatch by doing translations in vkGetPhysicalDevice*. Signed-off-by: Chia-I Wu <olvaffe@gmail.com> Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10437>
This commit is contained in:
parent
fbaa6dbf4e
commit
efa185ed5c
3 changed files with 122 additions and 24 deletions
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "c11/threads.h"
|
||||
#include "util/bitscan.h"
|
||||
#include "util/compiler.h"
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/os_time.h"
|
||||
|
|
|
|||
|
|
@ -1331,21 +1331,39 @@ vn_physical_device_init_memory_properties(
|
|||
}
|
||||
|
||||
static void
|
||||
vn_physical_device_init_external_memory_handles(
|
||||
vn_physical_device_init_external_memory(
|
||||
struct vn_physical_device *physical_dev)
|
||||
{
|
||||
/* When a renderer VkDeviceMemory is exportable, we can create a
|
||||
* vn_renderer_bo from it. The vn_renderer_bo can be freely exported as an
|
||||
* opaque fd or a dma-buf.
|
||||
*
|
||||
* However, to know if a rendender VkDeviceMemory is exportable, we have to
|
||||
* start from VkPhysicalDeviceExternalImageFormatInfo (or
|
||||
* vkGetPhysicalDeviceExternalBufferProperties). That means we need to
|
||||
* know the handle type that the renderer will use to make those queries.
|
||||
*
|
||||
* XXX We also assume that a vn_renderer_bo can be created as long as the
|
||||
* renderer VkDeviceMemory has a mappable memory type. That is plain
|
||||
* wrong. It is impossible to fix though until some new extension is
|
||||
* created and supported by the driver, and that the renderer switches to
|
||||
* the extension.
|
||||
*/
|
||||
|
||||
if (!physical_dev->instance->renderer_info.has_dmabuf_import)
|
||||
return;
|
||||
|
||||
/* We have export support but we don't advertise it. It is for WSI only at
|
||||
* the moment. For import support, we need to be able to serialize
|
||||
* vkGetMemoryFdPropertiesKHR and VkImportMemoryFdInfoKHR. We can
|
||||
* serialize fd to bo->res_id, but we probably want to add new
|
||||
* commands/structs first (using VK_MESA_venus_protocol).
|
||||
*
|
||||
* We also create a BO when a vn_device_memory is mappable. We don't know
|
||||
* which handle type the renderer uses. That seems fine though.
|
||||
/* TODO We assume the renderer uses dma-bufs here. This should be
|
||||
* negotiated by adding a new function to VK_MESA_venus_protocol.
|
||||
*/
|
||||
if (physical_dev->renderer_extensions.EXT_external_memory_dma_buf) {
|
||||
physical_dev->external_memory.renderer_handle_type =
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
|
||||
physical_dev->external_memory.supported_handle_types =
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1618,7 +1636,7 @@ vn_physical_device_init(struct vn_physical_device *physical_dev)
|
|||
|
||||
vn_physical_device_init_memory_properties(physical_dev);
|
||||
|
||||
vn_physical_device_init_external_memory_handles(physical_dev);
|
||||
vn_physical_device_init_external_memory(physical_dev);
|
||||
vn_physical_device_init_external_fence_handles(physical_dev);
|
||||
vn_physical_device_init_external_semaphore_handles(physical_dev);
|
||||
|
||||
|
|
@ -2635,6 +2653,55 @@ vn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
|
|||
physical_dev->instance, physicalDevice, format, pFormatProperties);
|
||||
}
|
||||
|
||||
struct vn_physical_device_image_format_info {
|
||||
VkPhysicalDeviceImageFormatInfo2 format;
|
||||
VkPhysicalDeviceExternalImageFormatInfo external;
|
||||
VkImageFormatListCreateInfo list;
|
||||
VkImageStencilUsageCreateInfo stencil_usage;
|
||||
};
|
||||
|
||||
static const VkPhysicalDeviceImageFormatInfo2 *
|
||||
vn_physical_device_fix_image_format_info(
|
||||
struct vn_physical_device *physical_dev,
|
||||
const VkPhysicalDeviceImageFormatInfo2 *info,
|
||||
struct vn_physical_device_image_format_info *local_info)
|
||||
{
|
||||
local_info->format = *info;
|
||||
VkBaseOutStructure *dst = (void *)&local_info->format;
|
||||
|
||||
/* we should generate deep copy functions... */
|
||||
vk_foreach_struct_const(src, info->pNext) {
|
||||
void *pnext = NULL;
|
||||
switch (src->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
|
||||
memcpy(&local_info->external, src, sizeof(local_info->external));
|
||||
local_info->external.handleType =
|
||||
physical_dev->external_memory.renderer_handle_type;
|
||||
pnext = &local_info->external;
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
|
||||
memcpy(&local_info->list, src, sizeof(local_info->list));
|
||||
pnext = &local_info->list;
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:
|
||||
memcpy(&local_info->stencil_usage, src,
|
||||
sizeof(local_info->stencil_usage));
|
||||
pnext = &local_info->stencil_usage;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pnext) {
|
||||
dst->pNext = pnext;
|
||||
dst = pnext;
|
||||
}
|
||||
}
|
||||
|
||||
dst->pNext = NULL;
|
||||
return &local_info->format;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_GetPhysicalDeviceImageFormatProperties2(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
|
|
@ -2643,6 +2710,10 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
|||
{
|
||||
struct vn_physical_device *physical_dev =
|
||||
vn_physical_device_from_handle(physicalDevice);
|
||||
const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
|
||||
physical_dev->external_memory.renderer_handle_type;
|
||||
const VkExternalMemoryHandleTypeFlags supported_handle_types =
|
||||
physical_dev->external_memory.supported_handle_types;
|
||||
|
||||
const VkPhysicalDeviceExternalImageFormatInfo *external_info =
|
||||
vk_find_struct_const(pImageFormatInfo->pNext,
|
||||
|
|
@ -2650,9 +2721,18 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
|||
if (external_info && !external_info->handleType)
|
||||
external_info = NULL;
|
||||
|
||||
if (external_info &&
|
||||
!(external_info->handleType & physical_dev->external_memory_handles))
|
||||
return vn_error(physical_dev->instance, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
struct vn_physical_device_image_format_info local_info;
|
||||
if (external_info) {
|
||||
if (!(external_info->handleType & supported_handle_types)) {
|
||||
return vn_error(physical_dev->instance,
|
||||
VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
if (external_info->handleType != renderer_handle_type) {
|
||||
pImageFormatInfo = vn_physical_device_fix_image_format_info(
|
||||
physical_dev, pImageFormatInfo, &local_info);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult result;
|
||||
/* TODO per-device cache */
|
||||
|
|
@ -2666,10 +2746,11 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
|||
VkExternalMemoryProperties *mem_props =
|
||||
&img_props->externalMemoryProperties;
|
||||
|
||||
mem_props->compatibleHandleTypes &=
|
||||
physical_dev->external_memory_handles;
|
||||
mem_props->exportFromImportedHandleTypes &=
|
||||
physical_dev->external_memory_handles;
|
||||
mem_props->compatibleHandleTypes = supported_handle_types;
|
||||
mem_props->exportFromImportedHandleTypes =
|
||||
(mem_props->exportFromImportedHandleTypes & renderer_handle_type)
|
||||
? supported_handle_types
|
||||
: 0;
|
||||
}
|
||||
|
||||
return vn_result(physical_dev->instance, result);
|
||||
|
|
@ -2699,25 +2780,37 @@ vn_GetPhysicalDeviceExternalBufferProperties(
|
|||
{
|
||||
struct vn_physical_device *physical_dev =
|
||||
vn_physical_device_from_handle(physicalDevice);
|
||||
const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
|
||||
physical_dev->external_memory.renderer_handle_type;
|
||||
const VkExternalMemoryHandleTypeFlags supported_handle_types =
|
||||
physical_dev->external_memory.supported_handle_types;
|
||||
|
||||
VkExternalMemoryProperties *props =
|
||||
&pExternalBufferProperties->externalMemoryProperties;
|
||||
|
||||
if (!(pExternalBufferInfo->handleType &
|
||||
physical_dev->external_memory_handles)) {
|
||||
if (!(pExternalBufferInfo->handleType & supported_handle_types)) {
|
||||
props->compatibleHandleTypes = pExternalBufferInfo->handleType;
|
||||
props->exportFromImportedHandleTypes = 0;
|
||||
props->externalMemoryFeatures = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceExternalBufferInfo local_info;
|
||||
if (pExternalBufferInfo->handleType != renderer_handle_type) {
|
||||
local_info = *pExternalBufferInfo;
|
||||
local_info.handleType = renderer_handle_type;
|
||||
pExternalBufferInfo = &local_info;
|
||||
}
|
||||
|
||||
/* TODO per-device cache */
|
||||
vn_call_vkGetPhysicalDeviceExternalBufferProperties(
|
||||
physical_dev->instance, physicalDevice, pExternalBufferInfo,
|
||||
pExternalBufferProperties);
|
||||
|
||||
props->compatibleHandleTypes &= physical_dev->external_memory_handles;
|
||||
props->exportFromImportedHandleTypes &=
|
||||
physical_dev->external_memory_handles;
|
||||
props->compatibleHandleTypes = supported_handle_types;
|
||||
props->exportFromImportedHandleTypes =
|
||||
(props->exportFromImportedHandleTypes & renderer_handle_type)
|
||||
? supported_handle_types
|
||||
: 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -85,7 +85,11 @@ struct vn_physical_device {
|
|||
|
||||
VkPhysicalDeviceMemoryProperties2 memory_properties;
|
||||
|
||||
VkExternalMemoryHandleTypeFlags external_memory_handles;
|
||||
struct {
|
||||
VkExternalMemoryHandleTypeFlagBits renderer_handle_type;
|
||||
VkExternalMemoryHandleTypeFlags supported_handle_types;
|
||||
} external_memory;
|
||||
|
||||
VkExternalFenceHandleTypeFlags external_fence_handles;
|
||||
VkExternalSemaphoreHandleTypeFlags external_binary_semaphore_handles;
|
||||
VkExternalSemaphoreHandleTypeFlags external_timeline_semaphore_handles;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue