No functional change. Signed-off-by: Chia-I Wu <olvaffe@gmail.com> Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org> Reviewed-by: Ryan Neph <ryanneph@google.com>macos/master
parent
c15d09acd1
commit
f29550d86c
@ -0,0 +1,278 @@ |
|||||||
|
/*
|
||||||
|
* Copyright 2020 Google LLC |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "vkr_device_memory.h" |
||||||
|
|
||||||
|
#include "venus-protocol/vn_protocol_renderer_device_memory.h" |
||||||
|
#include "venus-protocol/vn_protocol_renderer_transport.h" |
||||||
|
|
||||||
|
#include "vkr_context.h" |
||||||
|
#include "vkr_device.h" |
||||||
|
|
||||||
|
static bool |
||||||
|
vkr_get_fd_handle_type_from_virgl_fd_type( |
||||||
|
struct vkr_physical_device *dev, |
||||||
|
enum virgl_resource_fd_type fd_type, |
||||||
|
VkExternalMemoryHandleTypeFlagBits *out_handle_type) |
||||||
|
{ |
||||||
|
assert(dev); |
||||||
|
assert(out_handle_type); |
||||||
|
|
||||||
|
switch (fd_type) { |
||||||
|
case VIRGL_RESOURCE_FD_DMABUF: |
||||||
|
if (!dev->EXT_external_memory_dma_buf) |
||||||
|
return false; |
||||||
|
*out_handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; |
||||||
|
break; |
||||||
|
case VIRGL_RESOURCE_FD_OPAQUE: |
||||||
|
if (!dev->KHR_external_memory_fd) |
||||||
|
return false; |
||||||
|
*out_handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; |
||||||
|
break; |
||||||
|
default: |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
vkr_dispatch_vkAllocateMemory(struct vn_dispatch_context *dispatch, |
||||||
|
struct vn_command_vkAllocateMemory *args) |
||||||
|
{ |
||||||
|
struct vkr_context *ctx = dispatch->data; |
||||||
|
|
||||||
|
struct vkr_device *dev = (struct vkr_device *)args->device; |
||||||
|
if (!dev || dev->base.type != VK_OBJECT_TYPE_DEVICE) { |
||||||
|
vkr_cs_decoder_set_fatal(&ctx->decoder); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef FORCE_ENABLE_DMABUF |
||||||
|
VkExportMemoryAllocateInfo local_export_info; |
||||||
|
if (dev->physical_device->EXT_external_memory_dma_buf) { |
||||||
|
VkExportMemoryAllocateInfo *export_info = vkr_find_pnext( |
||||||
|
args->pAllocateInfo->pNext, VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO); |
||||||
|
if (export_info) { |
||||||
|
export_info->handleTypes |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; |
||||||
|
} else { |
||||||
|
local_export_info = (const VkExportMemoryAllocateInfo){ |
||||||
|
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, |
||||||
|
.pNext = args->pAllocateInfo->pNext, |
||||||
|
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, |
||||||
|
}; |
||||||
|
((VkMemoryAllocateInfo *)args->pAllocateInfo)->pNext = &local_export_info; |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/* translate VkImportMemoryResourceInfoMESA into VkImportMemoryFdInfoKHR */ |
||||||
|
VkImportMemoryResourceInfoMESA *import_resource_info = NULL; |
||||||
|
VkImportMemoryFdInfoKHR import_fd_info = { |
||||||
|
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, |
||||||
|
.fd = -1, |
||||||
|
}; |
||||||
|
VkBaseInStructure *pprev = (VkBaseInStructure *)args->pAllocateInfo; |
||||||
|
while (pprev->pNext) { |
||||||
|
if (pprev->pNext->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_RESOURCE_INFO_MESA) { |
||||||
|
import_resource_info = (VkImportMemoryResourceInfoMESA *)pprev->pNext; |
||||||
|
import_fd_info.pNext = pprev->pNext->pNext; |
||||||
|
pprev->pNext = (const struct VkBaseInStructure *)&import_fd_info; |
||||||
|
break; |
||||||
|
} |
||||||
|
pprev = (VkBaseInStructure *)pprev->pNext; |
||||||
|
} |
||||||
|
if (import_resource_info) { |
||||||
|
uint32_t res_id = import_resource_info->resourceId; |
||||||
|
struct vkr_resource_attachment *att = |
||||||
|
util_hash_table_get(ctx->resource_table, uintptr_to_pointer(res_id)); |
||||||
|
if (!att) { |
||||||
|
vkr_cs_decoder_set_fatal(&ctx->decoder); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
enum virgl_resource_fd_type fd_type = |
||||||
|
virgl_resource_export_fd(att->resource, &import_fd_info.fd); |
||||||
|
if (!vkr_get_fd_handle_type_from_virgl_fd_type(dev->physical_device, fd_type, |
||||||
|
&import_fd_info.handleType)) { |
||||||
|
close(import_fd_info.fd); |
||||||
|
args->ret = VK_ERROR_INVALID_EXTERNAL_HANDLE; |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
struct vkr_device_memory *mem = calloc(1, sizeof(*mem)); |
||||||
|
if (!mem) { |
||||||
|
if (import_resource_info) |
||||||
|
close(import_fd_info.fd); |
||||||
|
args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
mem->base.type = VK_OBJECT_TYPE_DEVICE_MEMORY; |
||||||
|
mem->base.id = vkr_cs_handle_load_id((const void **)args->pMemory, mem->base.type); |
||||||
|
|
||||||
|
vn_replace_vkAllocateMemory_args_handle(args); |
||||||
|
args->ret = vkAllocateMemory(args->device, args->pAllocateInfo, NULL, |
||||||
|
&mem->base.handle.device_memory); |
||||||
|
if (args->ret != VK_SUCCESS) { |
||||||
|
if (import_resource_info) |
||||||
|
close(import_fd_info.fd); |
||||||
|
free(mem); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
const VkPhysicalDeviceMemoryProperties *mem_props = |
||||||
|
&dev->physical_device->memory_properties; |
||||||
|
const uint32_t mt_index = args->pAllocateInfo->memoryTypeIndex; |
||||||
|
const uint32_t property_flags = mem_props->memoryTypes[mt_index].propertyFlags; |
||||||
|
|
||||||
|
/* get valid fd types */ |
||||||
|
uint32_t valid_fd_types = 0; |
||||||
|
const VkBaseInStructure *pnext = args->pAllocateInfo->pNext; |
||||||
|
while (pnext) { |
||||||
|
if (pnext->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO) { |
||||||
|
const VkExportMemoryAllocateInfo *export = (const void *)pnext; |
||||||
|
|
||||||
|
if (export->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) |
||||||
|
valid_fd_types |= 1 << VIRGL_RESOURCE_FD_OPAQUE; |
||||||
|
if (export->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) |
||||||
|
valid_fd_types |= 1 << VIRGL_RESOURCE_FD_DMABUF; |
||||||
|
|
||||||
|
break; |
||||||
|
} |
||||||
|
pnext = pnext->pNext; |
||||||
|
} |
||||||
|
|
||||||
|
mem->device = args->device; |
||||||
|
mem->property_flags = property_flags; |
||||||
|
mem->valid_fd_types = valid_fd_types; |
||||||
|
list_inithead(&mem->head); |
||||||
|
|
||||||
|
list_add(&mem->base.track_head, &dev->objects); |
||||||
|
|
||||||
|
util_hash_table_set_u64(ctx->object_table, mem->base.id, mem); |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
vkr_dispatch_vkFreeMemory(struct vn_dispatch_context *dispatch, |
||||||
|
struct vn_command_vkFreeMemory *args) |
||||||
|
{ |
||||||
|
struct vkr_context *ctx = dispatch->data; |
||||||
|
|
||||||
|
struct vkr_device_memory *mem = (struct vkr_device_memory *)(uintptr_t)args->memory; |
||||||
|
if (!mem || mem->base.type != VK_OBJECT_TYPE_DEVICE_MEMORY) { |
||||||
|
if (mem) |
||||||
|
vkr_cs_decoder_set_fatal(&ctx->decoder); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
vn_replace_vkFreeMemory_args_handle(args); |
||||||
|
vkFreeMemory(args->device, args->memory, NULL); |
||||||
|
|
||||||
|
list_del(&mem->head); |
||||||
|
list_del(&mem->base.track_head); |
||||||
|
|
||||||
|
util_hash_table_remove_u64(ctx->object_table, mem->base.id); |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
vkr_dispatch_vkGetDeviceMemoryCommitment( |
||||||
|
UNUSED struct vn_dispatch_context *dispatch, |
||||||
|
struct vn_command_vkGetDeviceMemoryCommitment *args) |
||||||
|
{ |
||||||
|
vn_replace_vkGetDeviceMemoryCommitment_args_handle(args); |
||||||
|
vkGetDeviceMemoryCommitment(args->device, args->memory, args->pCommittedMemoryInBytes); |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
vkr_dispatch_vkGetDeviceMemoryOpaqueCaptureAddress( |
||||||
|
struct vn_dispatch_context *dispatch, |
||||||
|
struct vn_command_vkGetDeviceMemoryOpaqueCaptureAddress *args) |
||||||
|
{ |
||||||
|
struct vkr_context *ctx = dispatch->data; |
||||||
|
struct vkr_device *dev = (struct vkr_device *)args->device; |
||||||
|
if (!dev || dev->base.type != VK_OBJECT_TYPE_DEVICE) { |
||||||
|
vkr_cs_decoder_set_fatal(&ctx->decoder); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
vn_replace_vkGetDeviceMemoryOpaqueCaptureAddress_args_handle(args); |
||||||
|
args->ret = dev->GetDeviceMemoryOpaqueCaptureAddress(args->device, args->pInfo); |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
vkr_dispatch_vkGetMemoryResourcePropertiesMESA( |
||||||
|
struct vn_dispatch_context *dispatch, |
||||||
|
struct vn_command_vkGetMemoryResourcePropertiesMESA *args) |
||||||
|
{ |
||||||
|
struct vkr_context *ctx = dispatch->data; |
||||||
|
struct vkr_device *dev = (struct vkr_device *)args->device; |
||||||
|
if (!dev || dev->base.type != VK_OBJECT_TYPE_DEVICE) { |
||||||
|
vkr_cs_decoder_set_fatal(&ctx->decoder); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
struct vkr_resource_attachment *att = |
||||||
|
util_hash_table_get(ctx->resource_table, uintptr_to_pointer(args->resourceId)); |
||||||
|
if (!att) { |
||||||
|
vkr_cs_decoder_set_fatal(&ctx->decoder); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
int fd = -1; |
||||||
|
enum virgl_resource_fd_type fd_type = virgl_resource_export_fd(att->resource, &fd); |
||||||
|
VkExternalMemoryHandleTypeFlagBits handle_type; |
||||||
|
if (!vkr_get_fd_handle_type_from_virgl_fd_type(dev->physical_device, fd_type, |
||||||
|
&handle_type) || |
||||||
|
handle_type != VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) { |
||||||
|
close(fd); |
||||||
|
args->ret = VK_ERROR_INVALID_EXTERNAL_HANDLE; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
VkMemoryFdPropertiesKHR mem_fd_props = { |
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR, |
||||||
|
.pNext = NULL, |
||||||
|
.memoryTypeBits = 0, |
||||||
|
}; |
||||||
|
vn_replace_vkGetMemoryResourcePropertiesMESA_args_handle(args); |
||||||
|
args->ret = |
||||||
|
dev->get_memory_fd_properties(args->device, handle_type, fd, &mem_fd_props); |
||||||
|
if (args->ret != VK_SUCCESS) { |
||||||
|
close(fd); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
args->pMemoryResourceProperties->memoryTypeBits = mem_fd_props.memoryTypeBits; |
||||||
|
|
||||||
|
VkMemoryResourceAllocationSizeProperties100000MESA *alloc_size_props = vkr_find_pnext( |
||||||
|
args->pMemoryResourceProperties->pNext, |
||||||
|
VK_STRUCTURE_TYPE_MEMORY_RESOURCE_ALLOCATION_SIZE_PROPERTIES_100000_MESA); |
||||||
|
if (alloc_size_props) |
||||||
|
alloc_size_props->allocationSize = lseek(fd, 0, SEEK_END); |
||||||
|
|
||||||
|
close(fd); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
vkr_context_init_device_memory_dispatch(struct vkr_context *ctx) |
||||||
|
{ |
||||||
|
struct vn_dispatch_context *dispatch = &ctx->dispatch; |
||||||
|
|
||||||
|
dispatch->dispatch_vkAllocateMemory = vkr_dispatch_vkAllocateMemory; |
||||||
|
dispatch->dispatch_vkFreeMemory = vkr_dispatch_vkFreeMemory; |
||||||
|
dispatch->dispatch_vkMapMemory = NULL; |
||||||
|
dispatch->dispatch_vkUnmapMemory = NULL; |
||||||
|
dispatch->dispatch_vkFlushMappedMemoryRanges = NULL; |
||||||
|
dispatch->dispatch_vkInvalidateMappedMemoryRanges = NULL; |
||||||
|
dispatch->dispatch_vkGetDeviceMemoryCommitment = |
||||||
|
vkr_dispatch_vkGetDeviceMemoryCommitment; |
||||||
|
dispatch->dispatch_vkGetDeviceMemoryOpaqueCaptureAddress = |
||||||
|
vkr_dispatch_vkGetDeviceMemoryOpaqueCaptureAddress; |
||||||
|
|
||||||
|
dispatch->dispatch_vkGetMemoryResourcePropertiesMESA = |
||||||
|
vkr_dispatch_vkGetMemoryResourcePropertiesMESA; |
||||||
|
} |
Loading…
Reference in new issue