mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-11 04:50:35 +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 "c11/threads.h"
|
||||||
#include "util/bitscan.h"
|
#include "util/bitscan.h"
|
||||||
|
#include "util/compiler.h"
|
||||||
#include "util/list.h"
|
#include "util/list.h"
|
||||||
#include "util/macros.h"
|
#include "util/macros.h"
|
||||||
#include "util/os_time.h"
|
#include "util/os_time.h"
|
||||||
|
|
|
||||||
|
|
@ -1331,21 +1331,39 @@ vn_physical_device_init_memory_properties(
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vn_physical_device_init_external_memory_handles(
|
vn_physical_device_init_external_memory(
|
||||||
struct vn_physical_device *physical_dev)
|
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)
|
if (!physical_dev->instance->renderer_info.has_dmabuf_import)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* We have export support but we don't advertise it. It is for WSI only at
|
/* TODO We assume the renderer uses dma-bufs here. This should be
|
||||||
* the moment. For import support, we need to be able to serialize
|
* negotiated by adding a new function to VK_MESA_venus_protocol.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
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
|
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_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_fence_handles(physical_dev);
|
||||||
vn_physical_device_init_external_semaphore_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);
|
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
|
VkResult
|
||||||
vn_GetPhysicalDeviceImageFormatProperties2(
|
vn_GetPhysicalDeviceImageFormatProperties2(
|
||||||
VkPhysicalDevice physicalDevice,
|
VkPhysicalDevice physicalDevice,
|
||||||
|
|
@ -2643,6 +2710,10 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
||||||
{
|
{
|
||||||
struct vn_physical_device *physical_dev =
|
struct vn_physical_device *physical_dev =
|
||||||
vn_physical_device_from_handle(physicalDevice);
|
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 =
|
const VkPhysicalDeviceExternalImageFormatInfo *external_info =
|
||||||
vk_find_struct_const(pImageFormatInfo->pNext,
|
vk_find_struct_const(pImageFormatInfo->pNext,
|
||||||
|
|
@ -2650,9 +2721,18 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
||||||
if (external_info && !external_info->handleType)
|
if (external_info && !external_info->handleType)
|
||||||
external_info = NULL;
|
external_info = NULL;
|
||||||
|
|
||||||
if (external_info &&
|
struct vn_physical_device_image_format_info local_info;
|
||||||
!(external_info->handleType & physical_dev->external_memory_handles))
|
if (external_info) {
|
||||||
return vn_error(physical_dev->instance, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
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;
|
VkResult result;
|
||||||
/* TODO per-device cache */
|
/* TODO per-device cache */
|
||||||
|
|
@ -2666,10 +2746,11 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
||||||
VkExternalMemoryProperties *mem_props =
|
VkExternalMemoryProperties *mem_props =
|
||||||
&img_props->externalMemoryProperties;
|
&img_props->externalMemoryProperties;
|
||||||
|
|
||||||
mem_props->compatibleHandleTypes &=
|
mem_props->compatibleHandleTypes = supported_handle_types;
|
||||||
physical_dev->external_memory_handles;
|
mem_props->exportFromImportedHandleTypes =
|
||||||
mem_props->exportFromImportedHandleTypes &=
|
(mem_props->exportFromImportedHandleTypes & renderer_handle_type)
|
||||||
physical_dev->external_memory_handles;
|
? supported_handle_types
|
||||||
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vn_result(physical_dev->instance, result);
|
return vn_result(physical_dev->instance, result);
|
||||||
|
|
@ -2699,25 +2780,37 @@ vn_GetPhysicalDeviceExternalBufferProperties(
|
||||||
{
|
{
|
||||||
struct vn_physical_device *physical_dev =
|
struct vn_physical_device *physical_dev =
|
||||||
vn_physical_device_from_handle(physicalDevice);
|
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 =
|
VkExternalMemoryProperties *props =
|
||||||
&pExternalBufferProperties->externalMemoryProperties;
|
&pExternalBufferProperties->externalMemoryProperties;
|
||||||
|
if (!(pExternalBufferInfo->handleType & supported_handle_types)) {
|
||||||
if (!(pExternalBufferInfo->handleType &
|
|
||||||
physical_dev->external_memory_handles)) {
|
|
||||||
props->compatibleHandleTypes = pExternalBufferInfo->handleType;
|
props->compatibleHandleTypes = pExternalBufferInfo->handleType;
|
||||||
props->exportFromImportedHandleTypes = 0;
|
props->exportFromImportedHandleTypes = 0;
|
||||||
props->externalMemoryFeatures = 0;
|
props->externalMemoryFeatures = 0;
|
||||||
return;
|
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 */
|
/* TODO per-device cache */
|
||||||
vn_call_vkGetPhysicalDeviceExternalBufferProperties(
|
vn_call_vkGetPhysicalDeviceExternalBufferProperties(
|
||||||
physical_dev->instance, physicalDevice, pExternalBufferInfo,
|
physical_dev->instance, physicalDevice, pExternalBufferInfo,
|
||||||
pExternalBufferProperties);
|
pExternalBufferProperties);
|
||||||
|
|
||||||
props->compatibleHandleTypes &= physical_dev->external_memory_handles;
|
props->compatibleHandleTypes = supported_handle_types;
|
||||||
props->exportFromImportedHandleTypes &=
|
props->exportFromImportedHandleTypes =
|
||||||
physical_dev->external_memory_handles;
|
(props->exportFromImportedHandleTypes & renderer_handle_type)
|
||||||
|
? supported_handle_types
|
||||||
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,11 @@ struct vn_physical_device {
|
||||||
|
|
||||||
VkPhysicalDeviceMemoryProperties2 memory_properties;
|
VkPhysicalDeviceMemoryProperties2 memory_properties;
|
||||||
|
|
||||||
VkExternalMemoryHandleTypeFlags external_memory_handles;
|
struct {
|
||||||
|
VkExternalMemoryHandleTypeFlagBits renderer_handle_type;
|
||||||
|
VkExternalMemoryHandleTypeFlags supported_handle_types;
|
||||||
|
} external_memory;
|
||||||
|
|
||||||
VkExternalFenceHandleTypeFlags external_fence_handles;
|
VkExternalFenceHandleTypeFlags external_fence_handles;
|
||||||
VkExternalSemaphoreHandleTypeFlags external_binary_semaphore_handles;
|
VkExternalSemaphoreHandleTypeFlags external_binary_semaphore_handles;
|
||||||
VkExternalSemaphoreHandleTypeFlags external_timeline_semaphore_handles;
|
VkExternalSemaphoreHandleTypeFlags external_timeline_semaphore_handles;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue