wsl/libhsakmt: refactor ipc implementation
Signed-off-by: Flora Cui <flora.cui@amd.com> Reviewed-by: Tianci Yin <tianci.yin@amd.com> Part-of: <http://10.67.69.192/wsl/rocr-runtime/-/merge_requests/85>
This commit is contained in:
+28
-11
@@ -82,14 +82,17 @@ HSAKMTAPI int amdgpu_device_get_fd(amdgpu_device_handle dev) {
|
||||
}
|
||||
|
||||
HSAKMTAPI int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu) {
|
||||
wsl::thunk::GpuMemory *gpu_mem = get_gpu_mem(bo);
|
||||
wsl::thunk::GpuMemory *gpu_mem = reinterpret_cast<wsl::thunk::GpuMemory *>(bo);
|
||||
if (gpu_mem->IsSysMemFd())
|
||||
*cpu = gpu_mem->CpuAddress();
|
||||
return 0;
|
||||
}
|
||||
|
||||
HSAKMTAPI int amdgpu_bo_free(amdgpu_bo_handle buf_handle) {
|
||||
return 0;
|
||||
wsl::thunk::GpuMemory *gpu_mem = reinterpret_cast<wsl::thunk::GpuMemory *>(buf_handle);
|
||||
void *MemoryAddress = gpu_mem->IsVaAllocated() ? (void*)gpu_mem->GpuAddress() : (void*)gpu_mem->HandleApeAddress();
|
||||
auto ret = hsaKmtFreeMemory((void*)MemoryAddress, gpu_mem->Size());
|
||||
return ret == HSAKMT_STATUS_SUCCESS ? 0 : -1;
|
||||
}
|
||||
|
||||
HSAKMTAPI int amdgpu_bo_export(amdgpu_bo_handle bo,
|
||||
@@ -102,14 +105,22 @@ HSAKMTAPI int amdgpu_bo_import(amdgpu_device_handle dev,
|
||||
enum amdgpu_bo_handle_type type,
|
||||
uint32_t shared_handle,
|
||||
struct amdgpu_bo_import_result *output) {
|
||||
wsl::thunk::WDDMDevice *pDevice = reinterpret_cast<wsl::thunk::WDDMDevice *>(dev);
|
||||
HsaGraphicsResourceInfo GraphicsResourceInfo = {};
|
||||
GraphicsResourceInfo.NodeId = pDevice->NodeId();
|
||||
if (type != amdgpu_bo_handle_type_dma_buf_fd) {
|
||||
pr_err("not implemented\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
HSAKMT_STATUS ret = hsaKmtImportDMABufHandle(shared_handle, &GraphicsResourceInfo);
|
||||
|
||||
wsl::thunk::WDDMDevice *pDevice = reinterpret_cast<wsl::thunk::WDDMDevice *>(dev);
|
||||
wsl::thunk::GpuMemoryHandle mem_handle;
|
||||
bool is_ipc_memfd = is_ipc_sysmemfd(shared_handle);
|
||||
bool alloc_va = is_ipc_memfd;
|
||||
|
||||
HSAKMT_STATUS ret = import_dmabuf_fd(shared_handle, pDevice->NodeId(),
|
||||
alloc_va, is_ipc_memfd, &mem_handle);
|
||||
if (ret == HSAKMT_STATUS_SUCCESS) {
|
||||
//use GpuMemory object's address as drm buf handle
|
||||
output->buf_handle = reinterpret_cast<amdgpu_bo_handle>(GraphicsResourceInfo.MemoryAddress);
|
||||
//use GpuMemory object handle as drm buf handle
|
||||
output->buf_handle = reinterpret_cast<amdgpu_bo_handle>(mem_handle);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
@@ -122,14 +133,20 @@ HSAKMTAPI int amdgpu_bo_va_op(amdgpu_bo_handle bo,
|
||||
uint64_t addr,
|
||||
uint64_t flags,
|
||||
uint32_t ops) {
|
||||
wsl::thunk::GpuMemory *gpu_mem = get_gpu_mem(bo);
|
||||
wsl::thunk::GpuMemory *gpu_mem = reinterpret_cast<wsl::thunk::GpuMemory *>(bo);
|
||||
assert(gpu_mem != nullptr);
|
||||
if (gpu_mem->IsSysMemFd())
|
||||
return 0;
|
||||
|
||||
switch(ops) {
|
||||
case AMDGPU_VA_OP_MAP:
|
||||
{
|
||||
if (gpu_mem->GpuAddress() == addr) {
|
||||
pr_info("bo is mapped already\n");
|
||||
return 0;
|
||||
} else if (gpu_mem->GpuAddress()) {
|
||||
pr_err("amdgpu_bo_va_op: GPU memory already mapped at %p, but requested to map at %p\n",
|
||||
reinterpret_cast<void *>(gpu_mem->GpuAddress()), reinterpret_cast<void *>(addr));
|
||||
return -1;
|
||||
}
|
||||
auto code = gpu_mem->MapGpuVirtualAddress(reinterpret_cast<gpusize>(addr), size, offset);
|
||||
if (code != ErrorCode::Success)
|
||||
return -1;
|
||||
|
||||
+5
-3
@@ -226,8 +226,10 @@ uint32_t get_vgpr_size_per_cu(HSA_ENGINE_ID id);
|
||||
|
||||
bool is_ipc_sysmemfd(int fd);
|
||||
|
||||
HSAKMT_STATUS hsaKmtImportDMABufHandle(int DMABufFd,
|
||||
HsaGraphicsResourceInfo *GraphicsResourceInfo,
|
||||
HSA_REGISTER_MEM_FLAGS RegisterFlags = {0});
|
||||
HSAKMT_STATUS import_dmabuf_fd(int DMABufFd,
|
||||
uint32_t NodeId,
|
||||
bool alloc_va,
|
||||
bool is_ipc_memfd,
|
||||
wsl::thunk::GpuMemoryHandle *GpuMemHandle);
|
||||
|
||||
#endif
|
||||
|
||||
+46
-29
@@ -192,7 +192,7 @@ HSAKMT_STATUS hsaKmtAllocMemoryAlignInternal(HSAuint32 PreferredNode,
|
||||
MemFlags.ui32.CoarseGrain = 1;
|
||||
|
||||
// AllocateNonPaged == AllocateIPC
|
||||
create_info.flags.imported_sys_memfd = !!(MemFlags.ui32.NonPaged && !MemFlags.ui32.GTTAccess);
|
||||
create_info.flags.sysmem_ipc_sig_exporter = !!(MemFlags.ui32.NonPaged && !MemFlags.ui32.GTTAccess);
|
||||
|
||||
create_info.domain = thunk_proxy::AllocDomain::kSystem;
|
||||
} else {
|
||||
@@ -207,6 +207,7 @@ HSAKMT_STATUS hsaKmtAllocMemoryAlignInternal(HSAuint32 PreferredNode,
|
||||
create_info.mem_flags |= thunk_proxy::kKernarg;
|
||||
|
||||
create_info.flags.physical_only = MemFlags.ui32.NoAddress;
|
||||
create_info.flags.alloc_va = !create_info.flags.physical_only;
|
||||
create_info.flags.interprocess = MemFlags.ui32.NoAddress;
|
||||
create_info.flags.interprocess |= MemFlags.ui32.Contiguous;
|
||||
create_info.flags.physical_contiguous = MemFlags.ui32.Contiguous;
|
||||
@@ -252,7 +253,7 @@ after_trim:
|
||||
else
|
||||
*MemoryAddress = reinterpret_cast<void *>(gpu_mem->GpuAddress());
|
||||
|
||||
(*allocation_map_)[*MemoryAddress] = Allocation(
|
||||
(*allocation_map_)[*MemoryAddress] = Allocation(
|
||||
gpu_mem->GetGpuMemoryHandle(), *MemoryAddress, (uint64_t)*MemoryAddress,
|
||||
create_info.size, false, nullptr, SizeInBytes,
|
||||
MemFlags.ui32.GTTAccess ? 0 : PreferredNode, MemFlags.Value);
|
||||
@@ -460,23 +461,37 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtRegisterGraphicsHandleToNodesExt(HSAuint64 Graphic
|
||||
uint32_t *gpu_id_array = NULL;
|
||||
HSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;
|
||||
|
||||
pr_debug("number of nodes %lu\n", NumberOfNodes);
|
||||
if (NumberOfNodes == 0) {
|
||||
RegisterFlags.ui32.requiresVAddr = 0;
|
||||
NumberOfNodes = 1;
|
||||
NodeArray = (HSAuint32*)&(dxg_runtime->default_node);
|
||||
}
|
||||
|
||||
if (is_ipc_sysmemfd(GraphicsResourceHandle)) {
|
||||
GraphicsResourceInfo->NodeId = dxg_runtime->default_node;
|
||||
pr_info("skip register sysmemfd. It would be released in next step\n");
|
||||
return HSAKMT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
GraphicsResourceInfo->NodeId = NodeArray[0];
|
||||
return hsaKmtImportDMABufHandle(GraphicsResourceHandle,
|
||||
GraphicsResourceInfo,
|
||||
RegisterFlags);
|
||||
if (NumberOfNodes == 0) {
|
||||
RegisterFlags.ui32.requiresVAddr = 0;
|
||||
NumberOfNodes = 1;
|
||||
NodeArray = (HSAuint32*)&(dxg_runtime->default_node);
|
||||
}
|
||||
|
||||
pr_debug("number of nodes %lu\n", NumberOfNodes);
|
||||
wsl::thunk::GpuMemoryHandle mem_handle;
|
||||
ret = import_dmabuf_fd(GraphicsResourceHandle, NodeArray[0],
|
||||
RegisterFlags.ui32.requiresVAddr,
|
||||
false, &mem_handle);
|
||||
if (ret != HSAKMT_STATUS_SUCCESS) {
|
||||
pr_err("hsaKmtRegisterGraphicsHandleToNodesExt: import_dmabuf_fd failed, "
|
||||
"GraphicsResourceHandle: %lu, NodeId: %u\n",
|
||||
GraphicsResourceHandle, NodeArray[0]);
|
||||
return ret;
|
||||
}
|
||||
wsl::thunk::GpuMemory *gpu_mem = wsl::thunk::GpuMemory::Convert(mem_handle);
|
||||
GraphicsResourceInfo->NodeId = gpu_mem->GetDevice()->NodeId();
|
||||
GraphicsResourceInfo->SizeInBytes = gpu_mem->ClientSize();
|
||||
GraphicsResourceInfo->MemoryAddress = RegisterFlags.ui32.requiresVAddr ?
|
||||
reinterpret_cast<void *>(gpu_mem->GpuAddress()):
|
||||
reinterpret_cast<void*>(gpu_mem->HandleApeAddress());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HSAKMT_STATUS HSAKMTAPI hsaKmtExportDMABufHandle(void *MemoryAddress,
|
||||
@@ -506,25 +521,27 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtExportDMABufHandle(void *MemoryAddress,
|
||||
}
|
||||
|
||||
|
||||
HSAKMT_STATUS hsaKmtImportDMABufHandle(int DMABufFd,
|
||||
HsaGraphicsResourceInfo *GraphicsResourceInfo,
|
||||
HSA_REGISTER_MEM_FLAGS RegisterFlags) {
|
||||
HSAKMT_STATUS import_dmabuf_fd(int DMABufFd,
|
||||
uint32_t NodeId,
|
||||
bool alloc_va,
|
||||
bool is_ipc_memfd,
|
||||
wsl::thunk::GpuMemoryHandle *GpuMemHandle) {
|
||||
CHECK_DXG_OPEN();
|
||||
|
||||
wsl::thunk::WDDMDevice* dev = get_wddmdev(GraphicsResourceInfo->NodeId);
|
||||
*GpuMemHandle = nullptr;
|
||||
wsl::thunk::WDDMDevice* dev = get_wddmdev(NodeId);
|
||||
wsl::thunk::GpuMemory *gpu_mem = nullptr;
|
||||
wsl::thunk::GpuMemoryCreateInfo create_info{};
|
||||
create_info.dmabuf_fd = DMABufFd;
|
||||
create_info.flags.imported_vram_alloc_va = RegisterFlags.ui32.requiresVAddr;
|
||||
create_info.flags.alloc_va = alloc_va;
|
||||
|
||||
if (is_ipc_sysmemfd(DMABufFd)) {
|
||||
if (is_ipc_memfd) {
|
||||
struct stat st;
|
||||
fstat(DMABufFd, &st);
|
||||
uint64_t sz = st.st_size;
|
||||
if (4096 <= sz && sz < dev->SystemHeapSize() && (sz & 0xfff) == 0) {
|
||||
pr_debug("DMABufFd %d is sys mem fd(IPC signal), get size:%ld from it\n", DMABufFd, st.st_size);
|
||||
create_info.flags.imported_sys_memfd = 1; // set to 1 when backend is system memory
|
||||
create_info.flags.imported_vram_alloc_va = 0; // set to 1 when backend is vram
|
||||
create_info.flags.sysmem_ipc_sig_importer = 1; // set to 1 when backend is system memory
|
||||
create_info.size = st.st_size;
|
||||
}
|
||||
}
|
||||
@@ -532,23 +549,23 @@ HSAKMT_STATUS hsaKmtImportDMABufHandle(int DMABufFd,
|
||||
auto code = dev->CreateGpuMemory(create_info, &gpu_mem);
|
||||
if (code == ErrorCode::Success) {
|
||||
void *MemoryAddress;
|
||||
if (create_info.flags.imported_sys_memfd || create_info.flags.imported_vram_alloc_va)
|
||||
if (alloc_va)
|
||||
MemoryAddress = reinterpret_cast<void *>(gpu_mem->GpuAddress());
|
||||
else
|
||||
MemoryAddress = reinterpret_cast<void*>(gpu_mem->HandleApeAddress());
|
||||
|
||||
*GpuMemHandle = gpu_mem->GetGpuMemoryHandle();
|
||||
|
||||
std::lock_guard<std::mutex> gard(*allocation_map_lock_);
|
||||
/*
|
||||
* the gpu_mem->Flags() need convert back from GpuMemoryCreateFlags to
|
||||
* HsaMemFlags, reference hsaKmtAllocMemoryAlign
|
||||
* */
|
||||
(*allocation_map_)[MemoryAddress] = Allocation(
|
||||
gpu_mem->GetGpuMemoryHandle(), MemoryAddress, (uint64_t)MemoryAddress,
|
||||
*GpuMemHandle, MemoryAddress, (uint64_t)MemoryAddress,
|
||||
gpu_mem->Size(), false, nullptr, gpu_mem->ClientSize(),
|
||||
GraphicsResourceInfo->NodeId, gpu_mem->Flags());
|
||||
NodeId, gpu_mem->Flags());
|
||||
|
||||
GraphicsResourceInfo->MemoryAddress = MemoryAddress;
|
||||
GraphicsResourceInfo->SizeInBytes = gpu_mem->ClientSize();
|
||||
return HSAKMT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -624,7 +641,7 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtDeregisterMemory(void *MemoryAddress) {
|
||||
if (it_ipc != allocation_map_->end()) {
|
||||
wsl::thunk::GpuMemoryDescFlags flags;
|
||||
flags.reserved = it_ipc->second.mem_flags_value;
|
||||
if (flags.is_imported_vram_alloc_va || flags.is_imported_sys_memfd) {
|
||||
if (flags.is_imported_vram_ipc) {
|
||||
wsl::thunk::GpuMemory *gpu_mem;
|
||||
gpu_mem = wsl::thunk::GpuMemory::Convert(it_ipc->second.handle);
|
||||
allocation_map_->erase(it_ipc);
|
||||
@@ -677,7 +694,7 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtMapMemoryToGPUNodes(
|
||||
if (it_ipc != allocation_map_->end()) {
|
||||
wsl::thunk::GpuMemoryDescFlags flags;
|
||||
flags.reserved = it_ipc->second.mem_flags_value;
|
||||
if (flags.is_imported_vram_alloc_va) {
|
||||
if (flags.is_imported_vram_ipc) {
|
||||
wsl::thunk::GpuMemory *gpu_mem;
|
||||
gpu_mem = wsl::thunk::GpuMemory::Convert(it_ipc->second.handle);
|
||||
|
||||
@@ -782,7 +799,7 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtUnmapMemoryToGPU(void *MemoryAddress) {
|
||||
if (it_ipc != allocation_map_->end()) {
|
||||
wsl::thunk::GpuMemoryDescFlags flags;
|
||||
flags.reserved = it_ipc->second.mem_flags_value;
|
||||
if (flags.is_imported_vram_alloc_va) {
|
||||
if (flags.is_imported_vram_ipc) {
|
||||
wsl::thunk::GpuMemory *gpu_mem;
|
||||
gpu_mem = wsl::thunk::GpuMemory::Convert(it_ipc->second.handle);
|
||||
|
||||
|
||||
+94
-88
@@ -62,7 +62,9 @@ ErrorCode GpuMemory::Init(const GpuMemoryCreateInfo &create_info) {
|
||||
desc_.flags.is_virtual = create_info.flags.virtual_alloc;
|
||||
desc_.flags.is_physical_only = create_info.flags.physical_only;
|
||||
desc_.flags.is_physical_contiguous = create_info.flags.physical_contiguous;
|
||||
desc_.flags.is_imported_sys_memfd = create_info.flags.imported_sys_memfd;
|
||||
desc_.flags.is_imported_sys_memfd = create_info.flags.sysmem_ipc_sig_importer;
|
||||
desc_.flags.is_sysmem_exporter = create_info.flags.sysmem_ipc_sig_exporter;
|
||||
desc_.flags.is_va_required = create_info.flags.alloc_va;
|
||||
|
||||
/* we can't tell the allocation is regular vmm or ipc mem at creation stage,
|
||||
they share same creation parameters, so forcing all vram allocations to
|
||||
@@ -241,13 +243,15 @@ ErrorCode GpuMemory::MapGpuVirtualAddress(const gpusize addr, const gpusize size
|
||||
map_size -= block_size;
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
ErrorCode GpuMemory::ReserveGpuVirtualAddress(gpusize base_virt_addr, gpusize size, gpusize alignment) {
|
||||
ErrorCode status;
|
||||
gpusize gpu_virt_addr = 0;
|
||||
if (desc_.flags.is_imported_sys_memfd && desc_.domain == thunk_proxy::AllocDomain::kSystem) {
|
||||
if ((desc_.flags.is_sysmem_exporter || desc_.flags.is_imported_sys_memfd)
|
||||
&& desc_.domain == thunk_proxy::AllocDomain::kSystem) {
|
||||
int mfd = (mem_fd_ > -1)? mem_fd_ : -1;
|
||||
status = device_->ReserveIPCSysMem(Size(), &gpu_virt_addr, desc_.alignment, mfd, desc_.flags.is_locked);
|
||||
if (status == ErrorCode::Success)
|
||||
@@ -419,7 +423,7 @@ ErrorCode GpuMemory::ImportPhysicalHandle(const GpuMemoryCreateInfo &create_info
|
||||
if (dmabuf_fd <= 0)
|
||||
return ErrorCode::InvalidateParams;
|
||||
|
||||
if(create_info.flags.imported_sys_memfd) {
|
||||
if(create_info.flags.sysmem_ipc_sig_importer) {
|
||||
// the ipc signal sys mem fd will be closed in Runtime::IPCClientImport, dup to hold a reference
|
||||
mem_fd_ = dup(dmabuf_fd);
|
||||
desc_.client_size = create_info.size;
|
||||
@@ -429,7 +433,8 @@ ErrorCode GpuMemory::ImportPhysicalHandle(const GpuMemoryCreateInfo &create_info
|
||||
desc_.alignment = 0x1000;
|
||||
desc_.mem_flags = create_info.mem_flags;
|
||||
desc_.engine_flag = create_info.engine_flag;
|
||||
desc_.flags.is_imported_sys_memfd = create_info.flags.imported_sys_memfd;
|
||||
desc_.flags.is_imported_sys_memfd = create_info.flags.sysmem_ipc_sig_importer;
|
||||
desc_.flags.is_va_required = create_info.flags.alloc_va;
|
||||
desc_.flags.is_virtual = create_info.flags.virtual_alloc;
|
||||
desc_.flags.is_physical_only = create_info.flags.physical_only;
|
||||
desc_.flags.is_physical_contiguous = create_info.flags.physical_contiguous;
|
||||
@@ -475,91 +480,92 @@ ErrorCode GpuMemory::ImportPhysicalHandle(const GpuMemoryCreateInfo &create_info
|
||||
code = ErrorCode::Unknown;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
memset(&query_args, 0, sizeof(query_args));
|
||||
query_args.hDevice = device_->DeviceHandle();
|
||||
query_args.hNtHandle = reinterpret_cast<HANDLE>(dmabuf_fd);
|
||||
auto ret = d3dthunk::QueryResourceInfoFromNtHandle(&query_args);
|
||||
if (ret != ErrorCode::Success) {
|
||||
pr_err("query resource info from nt handle failed %d\n", static_cast<int>(ret));
|
||||
return ErrorCode::InvalidateParams;
|
||||
}
|
||||
pr_debug("wsl-thunk: import from nt handle %d, get allocation number %d,"
|
||||
" runtime data size %#x total driver data size %#x resource data size=%#x\n",
|
||||
dmabuf_fd,
|
||||
query_args.NumAllocations,
|
||||
query_args.PrivateRuntimeDataSize,
|
||||
query_args.TotalPrivateDriverDataSize,
|
||||
query_args.ResourcePrivateDriverDataSize);
|
||||
|
||||
SharedHandleInfo shared_info;
|
||||
if(sizeof(shared_info) != query_args.PrivateRuntimeDataSize) {
|
||||
pr_err("shared hanle info size mismatch:%d vs %ld\n",
|
||||
query_args.PrivateRuntimeDataSize, sizeof(shared_info));
|
||||
return ErrorCode::UnSupported;
|
||||
}
|
||||
|
||||
uint32_t total_size = query_args.NumAllocations * sizeof(D3DDDI_OPENALLOCATIONINFO2) +
|
||||
query_args.TotalPrivateDriverDataSize +
|
||||
query_args.ResourcePrivateDriverDataSize;
|
||||
D3DDDI_OPENALLOCATIONINFO2 *open_info =
|
||||
reinterpret_cast<D3DDDI_OPENALLOCATIONINFO2*> (calloc(1, total_size));
|
||||
if (!open_info) {
|
||||
pr_err("alloc open_info failed, NumAllocations:%d\n",
|
||||
query_args.NumAllocations);
|
||||
return ErrorCode::OutOfMemory;
|
||||
}
|
||||
|
||||
auto guard = MakeScopeGuard([&open_info]() { free(open_info); });
|
||||
|
||||
alloc_handles_ptr_ = new WinAllocationHandle[query_args.NumAllocations];
|
||||
|
||||
D3DKMT_OPENRESOURCEFROMNTHANDLE open_args;
|
||||
memset(&open_args, 0, sizeof(open_args));
|
||||
open_args.hDevice = query_args.hDevice;
|
||||
open_args.hNtHandle = query_args.hNtHandle;
|
||||
open_args.NumAllocations = query_args.NumAllocations;
|
||||
open_args.pOpenAllocationInfo2 = open_info;
|
||||
open_args.TotalPrivateDriverDataBufferSize = query_args.TotalPrivateDriverDataSize;
|
||||
open_args.pTotalPrivateDriverDataBuffer = reinterpret_cast<void*>
|
||||
(open_args.pOpenAllocationInfo2 + open_args.NumAllocations);
|
||||
open_args.ResourcePrivateDriverDataSize = query_args.ResourcePrivateDriverDataSize;
|
||||
open_args.pResourcePrivateDriverData = reinterpret_cast<void*>
|
||||
(((uint64_t)open_args.pTotalPrivateDriverDataBuffer) +
|
||||
open_args.TotalPrivateDriverDataBufferSize);
|
||||
open_args.PrivateRuntimeDataSize = query_args.PrivateRuntimeDataSize;
|
||||
open_args.pPrivateRuntimeData = reinterpret_cast<void*> (&shared_info);
|
||||
|
||||
ret = d3dthunk::OpenResourceFromNtHandle(&open_args);
|
||||
if (ret != ErrorCode::Success) {
|
||||
ret = ErrorCode::InvalidateParams;
|
||||
pr_err("open resource failed %d\n", static_cast<int>(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
desc_.size = shared_info.size;
|
||||
desc_.client_size = shared_info.client_size;
|
||||
desc_.domain = shared_info.domain;
|
||||
desc_.flags.reserved = shared_info.flags;
|
||||
desc_.mem_flags = shared_info.mem_flags;
|
||||
desc_.adapter_luid = shared_info.adapter_luid;
|
||||
resource_ = open_args.hResource;
|
||||
num_allocations_ = open_args.NumAllocations;
|
||||
for (int i = 0; i < num_allocations_; i++)
|
||||
alloc_handles_ptr_[i] = open_info[i].hAllocation;
|
||||
|
||||
|
||||
if (create_info.flags.imported_vram_alloc_va) {
|
||||
desc_.flags.is_imported_vram_alloc_va = true;
|
||||
|
||||
ret = ReserveGpuVirtualAddress(create_info.va_hint, desc_.size, create_info.alignment);
|
||||
if (ret != ErrorCode::Success)
|
||||
pr_err("failed to allocate svm range, error:%d\n", static_cast<int>(ret));
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
return device_->HandleApertureAlloc(desc_.size, &desc_.handle_ape_addr);
|
||||
// vmem importer / ipc vram importer
|
||||
memset(&query_args, 0, sizeof(query_args));
|
||||
query_args.hDevice = device_->DeviceHandle();
|
||||
query_args.hNtHandle = reinterpret_cast<HANDLE>(dmabuf_fd);
|
||||
auto ret = d3dthunk::QueryResourceInfoFromNtHandle(&query_args);
|
||||
if (ret != ErrorCode::Success) {
|
||||
pr_err("query resource info from nt handle failed %d\n", static_cast<int>(ret));
|
||||
return ErrorCode::InvalidateParams;
|
||||
}
|
||||
pr_debug("wsl-thunk: import from nt handle %d, get allocation number %d,"
|
||||
" runtime data size %#x total driver data size %#x resource data size=%#x\n",
|
||||
dmabuf_fd,
|
||||
query_args.NumAllocations,
|
||||
query_args.PrivateRuntimeDataSize,
|
||||
query_args.TotalPrivateDriverDataSize,
|
||||
query_args.ResourcePrivateDriverDataSize);
|
||||
|
||||
SharedHandleInfo shared_info;
|
||||
if(sizeof(shared_info) != query_args.PrivateRuntimeDataSize) {
|
||||
pr_err("shared hanle info size mismatch:%d vs %ld\n",
|
||||
query_args.PrivateRuntimeDataSize, sizeof(shared_info));
|
||||
return ErrorCode::UnSupported;
|
||||
}
|
||||
|
||||
uint32_t total_size = query_args.NumAllocations * sizeof(D3DDDI_OPENALLOCATIONINFO2) +
|
||||
query_args.TotalPrivateDriverDataSize +
|
||||
query_args.ResourcePrivateDriverDataSize;
|
||||
D3DDDI_OPENALLOCATIONINFO2 *open_info =
|
||||
reinterpret_cast<D3DDDI_OPENALLOCATIONINFO2*> (calloc(1, total_size));
|
||||
if (!open_info) {
|
||||
pr_err("alloc open_info failed, NumAllocations:%d\n",
|
||||
query_args.NumAllocations);
|
||||
return ErrorCode::OutOfMemory;
|
||||
}
|
||||
|
||||
auto guard = MakeScopeGuard([&open_info]() { free(open_info); });
|
||||
|
||||
alloc_handles_ptr_ = new WinAllocationHandle[query_args.NumAllocations];
|
||||
|
||||
D3DKMT_OPENRESOURCEFROMNTHANDLE open_args;
|
||||
memset(&open_args, 0, sizeof(open_args));
|
||||
open_args.hDevice = query_args.hDevice;
|
||||
open_args.hNtHandle = query_args.hNtHandle;
|
||||
open_args.NumAllocations = query_args.NumAllocations;
|
||||
open_args.pOpenAllocationInfo2 = open_info;
|
||||
open_args.TotalPrivateDriverDataBufferSize = query_args.TotalPrivateDriverDataSize;
|
||||
open_args.pTotalPrivateDriverDataBuffer = reinterpret_cast<void*>
|
||||
(open_args.pOpenAllocationInfo2 + open_args.NumAllocations);
|
||||
open_args.ResourcePrivateDriverDataSize = query_args.ResourcePrivateDriverDataSize;
|
||||
open_args.pResourcePrivateDriverData = reinterpret_cast<void*>
|
||||
(((uint64_t)open_args.pTotalPrivateDriverDataBuffer) +
|
||||
open_args.TotalPrivateDriverDataBufferSize);
|
||||
open_args.PrivateRuntimeDataSize = query_args.PrivateRuntimeDataSize;
|
||||
open_args.pPrivateRuntimeData = reinterpret_cast<void*> (&shared_info);
|
||||
|
||||
ret = d3dthunk::OpenResourceFromNtHandle(&open_args);
|
||||
if (ret != ErrorCode::Success) {
|
||||
ret = ErrorCode::InvalidateParams;
|
||||
pr_err("open resource failed %d\n", static_cast<int>(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
desc_.size = shared_info.size;
|
||||
desc_.client_size = shared_info.client_size;
|
||||
desc_.domain = shared_info.domain;
|
||||
desc_.flags.reserved = shared_info.flags;
|
||||
desc_.mem_flags = shared_info.mem_flags;
|
||||
desc_.adapter_luid = shared_info.adapter_luid;
|
||||
resource_ = open_args.hResource;
|
||||
num_allocations_ = open_args.NumAllocations;
|
||||
for (int i = 0; i < num_allocations_; i++)
|
||||
alloc_handles_ptr_[i] = open_info[i].hAllocation;
|
||||
|
||||
desc_.flags.is_va_required = create_info.flags.alloc_va;
|
||||
if (desc_.flags.is_va_required) {
|
||||
desc_.flags.is_imported_vram_ipc = 1;
|
||||
ret = ReserveGpuVirtualAddress(create_info.va_hint, desc_.size, create_info.alignment);
|
||||
if (ret != ErrorCode::Success)
|
||||
pr_err("failed to allocate svm range, error:%d\n", static_cast<int>(ret));
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
desc_.flags.is_imported_vram_vmem = 1;
|
||||
return device_->HandleApertureAlloc(desc_.size, &desc_.handle_ape_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Fai riferimento in un nuovo problema
Block a user