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