mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-20 08:53:55 +08:00
Add NTHandle sharing
Signed-off-by: Kamil Diedrich <kamil.diedrich@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
8133b6d213
commit
465bec3d76
@@ -156,7 +156,7 @@ ze_result_t ContextImp::allocDeviceMem(ze_device_handle_t hDevice,
|
||||
deviceBitfields[rootDeviceIndex] = neoDevice->getDeviceBitfield();
|
||||
|
||||
NEO::SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::DEVICE_UNIFIED_MEMORY, this->driverHandle->rootDeviceIndices, deviceBitfields);
|
||||
unifiedMemoryProperties.allocationFlags.flags.shareable = static_cast<uint32_t>(lookupTable.isSharedHandle);
|
||||
unifiedMemoryProperties.allocationFlags.flags.shareable = static_cast<uint32_t>(lookupTable.exportMemory);
|
||||
unifiedMemoryProperties.device = neoDevice;
|
||||
|
||||
if (deviceDesc->flags & ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_UNCACHED) {
|
||||
@@ -554,6 +554,13 @@ ze_result_t ContextImp::getMemAllocProperties(const void *ptr,
|
||||
}
|
||||
uint64_t handle = alloc->gpuAllocations.getDefaultGraphicsAllocation()->peekInternalHandle(this->driverHandle->getMemoryManager());
|
||||
extendedMemoryExportProperties->fd = static_cast<int>(handle);
|
||||
} else if (extendedProperties->stype == ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_WIN32) {
|
||||
ze_external_memory_export_win32_handle_t *exportStructure = reinterpret_cast<ze_external_memory_export_win32_handle_t *>(extendedProperties);
|
||||
if (exportStructure->flags != ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
|
||||
}
|
||||
uint64_t handle = alloc->gpuAllocations.getDefaultGraphicsAllocation()->peekInternalHandle(this->driverHandle->getMemoryManager());
|
||||
exportStructure->handle = reinterpret_cast<void *>(reinterpret_cast<uintptr_t *>(handle));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1173,6 +1173,158 @@ TEST_F(MemoryExportImportTest,
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
}
|
||||
|
||||
struct DriverHandleGetWinHandleMock : public L0::DriverHandleImp {
|
||||
void *importNTHandle(ze_device_handle_t hDevice, void *handle) override {
|
||||
if (mockHandle == allocationMap.second) {
|
||||
return allocationMap.first;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint64_t mockHandle = 57;
|
||||
std::pair<void *, uint64_t> allocationMap;
|
||||
};
|
||||
|
||||
struct ContextHandleMock : public L0::ContextImp {
|
||||
ContextHandleMock(DriverHandleGetWinHandleMock *inDriverHandle) : L0::ContextImp(static_cast<L0::DriverHandle *>(inDriverHandle)) {
|
||||
driverHandle = inDriverHandle;
|
||||
}
|
||||
ze_result_t allocDeviceMem(ze_device_handle_t hDevice,
|
||||
const ze_device_mem_alloc_desc_t *deviceDesc,
|
||||
size_t size,
|
||||
size_t alignment, void **ptr) override {
|
||||
ze_result_t res = L0::ContextImp::allocDeviceMem(hDevice, deviceDesc, size, alignment, ptr);
|
||||
if (ZE_RESULT_SUCCESS == res) {
|
||||
driverHandle->allocationMap.first = *ptr;
|
||||
driverHandle->allocationMap.second = driverHandle->mockHandle;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ze_result_t getMemAllocProperties(const void *ptr,
|
||||
ze_memory_allocation_properties_t *pMemAllocProperties,
|
||||
ze_device_handle_t *phDevice) override {
|
||||
ze_result_t res = ContextImp::getMemAllocProperties(ptr, pMemAllocProperties, phDevice);
|
||||
if (ZE_RESULT_SUCCESS == res && pMemAllocProperties->pNext) {
|
||||
_ze_external_memory_export_win32_handle_t *extendedMemoryExportProperties =
|
||||
reinterpret_cast<_ze_external_memory_export_win32_handle_t *>(pMemAllocProperties->pNext);
|
||||
extendedMemoryExportProperties->handle = reinterpret_cast<void *>(reinterpret_cast<uintptr_t *>(driverHandle->mockHandle));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
DriverHandleGetWinHandleMock *driverHandle = nullptr;
|
||||
};
|
||||
|
||||
struct MemoryExportImportWinHandleTest : public ::testing::Test {
|
||||
void SetUp() override {
|
||||
NEO::MockCompilerEnableGuard mock(true);
|
||||
neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get());
|
||||
auto mockBuiltIns = new MockBuiltins();
|
||||
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->builtins.reset(mockBuiltIns);
|
||||
NEO::DeviceVector devices;
|
||||
devices.push_back(std::unique_ptr<NEO::Device>(neoDevice));
|
||||
driverHandle = std::make_unique<DriverHandleGetWinHandleMock>();
|
||||
driverHandle->initialize(std::move(devices));
|
||||
device = driverHandle->devices[0];
|
||||
|
||||
context = std::make_unique<ContextHandleMock>(driverHandle.get());
|
||||
EXPECT_NE(context, nullptr);
|
||||
context->getDevices().insert(std::make_pair(device->toHandle(), device));
|
||||
auto neoDevice = device->getNEODevice();
|
||||
context->rootDeviceIndices.insert(neoDevice->getRootDeviceIndex());
|
||||
context->deviceBitfields.insert({neoDevice->getRootDeviceIndex(), neoDevice->getDeviceBitfield()});
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
}
|
||||
std::unique_ptr<DriverHandleGetWinHandleMock> driverHandle;
|
||||
NEO::MockDevice *neoDevice = nullptr;
|
||||
L0::Device *device = nullptr;
|
||||
ze_context_handle_t hContext;
|
||||
std::unique_ptr<ContextHandleMock> context;
|
||||
};
|
||||
|
||||
TEST_F(MemoryExportImportWinHandleTest,
|
||||
givenCallToDeviceAllocWithExtendedExportDescriptorAndNTHandleFlagThenAllocationIsMade) {
|
||||
size_t size = 10;
|
||||
size_t alignment = 1u;
|
||||
void *ptr = nullptr;
|
||||
|
||||
ze_device_mem_alloc_desc_t deviceDesc = {};
|
||||
ze_external_memory_export_desc_t extendedDesc = {};
|
||||
extendedDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC;
|
||||
extendedDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32;
|
||||
deviceDesc.pNext = &extendedDesc;
|
||||
ze_result_t result = context->allocDeviceMem(device->toHandle(),
|
||||
&deviceDesc,
|
||||
size, alignment, &ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_NE(nullptr, ptr);
|
||||
|
||||
result = context->freeMem(ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
}
|
||||
|
||||
TEST_F(MemoryExportImportWinHandleTest,
|
||||
givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndUnsupportedFlagThenUnsupportedEnumerationIsReturned) {
|
||||
size_t size = 10;
|
||||
size_t alignment = 1u;
|
||||
void *ptr = nullptr;
|
||||
|
||||
ze_device_mem_alloc_desc_t deviceDesc = {};
|
||||
ze_result_t result = context->allocDeviceMem(device->toHandle(),
|
||||
&deviceDesc,
|
||||
size, alignment, &ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_NE(nullptr, ptr);
|
||||
|
||||
ze_memory_allocation_properties_t memoryProperties = {};
|
||||
ze_external_memory_export_win32_handle_t extendedProperties = {};
|
||||
extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_WIN32;
|
||||
extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_D3D12_HEAP;
|
||||
extendedProperties.handle = nullptr;
|
||||
memoryProperties.pNext = &extendedProperties;
|
||||
|
||||
ze_device_handle_t deviceHandle;
|
||||
result = context->getMemAllocProperties(ptr, &memoryProperties, &deviceHandle);
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION, result);
|
||||
EXPECT_EQ(extendedProperties.handle, nullptr);
|
||||
|
||||
result = context->freeMem(ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
}
|
||||
|
||||
TEST_F(MemoryExportImportWinHandleTest,
|
||||
givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndSupportedFlagThenValidFileDescriptorIsReturned) {
|
||||
size_t size = 10;
|
||||
size_t alignment = 1u;
|
||||
void *ptr = nullptr;
|
||||
|
||||
ze_device_mem_alloc_desc_t deviceDesc = {};
|
||||
ze_result_t result = context->allocDeviceMem(device->toHandle(),
|
||||
&deviceDesc,
|
||||
size, alignment, &ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_NE(nullptr, ptr);
|
||||
|
||||
ze_memory_allocation_properties_t memoryProperties = {};
|
||||
ze_external_memory_export_win32_handle_t extendedProperties = {};
|
||||
extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_WIN32;
|
||||
extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32;
|
||||
memoryProperties.pNext = &extendedProperties;
|
||||
|
||||
ze_device_handle_t deviceHandle;
|
||||
result = context->getMemAllocProperties(ptr, &memoryProperties, &deviceHandle);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_EQ(extendedProperties.handle, reinterpret_cast<void *>(reinterpret_cast<uintptr_t *>(driverHandle->mockHandle)));
|
||||
|
||||
result = context->freeMem(ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
}
|
||||
|
||||
using MemoryIPCTests = MemoryExportImportTest;
|
||||
|
||||
TEST_F(MemoryIPCTests,
|
||||
|
||||
@@ -426,8 +426,7 @@ TEST_F(WddmTestWithMockGdiDll, givenShareableAllocationWhenCreateThenSharedHandl
|
||||
allocation.setDefaultGmm(gmm.get());
|
||||
auto status = memoryManager.createGpuAllocationsWithRetry(&allocation);
|
||||
EXPECT_TRUE(status);
|
||||
EXPECT_NE(0u, allocation.resourceHandle);
|
||||
EXPECT_NE(0u, allocation.peekSharedHandle());
|
||||
EXPECT_NE(0u, allocation.peekInternalHandle(&memoryManager));
|
||||
}
|
||||
|
||||
TEST(WddmAllocationTest, whenAllocationIsShareableThenSharedHandleToModifyIsSharedHandleOfAllocation) {
|
||||
@@ -435,7 +434,7 @@ TEST(WddmAllocationTest, whenAllocationIsShareableThenSharedHandleToModifyIsShar
|
||||
auto sharedHandleToModify = allocation.getSharedHandleToModify();
|
||||
EXPECT_NE(nullptr, sharedHandleToModify);
|
||||
*sharedHandleToModify = 1234u;
|
||||
EXPECT_EQ(*sharedHandleToModify, allocation.peekSharedHandle());
|
||||
EXPECT_EQ(*sharedHandleToModify, allocation.peekInternalHandle(nullptr));
|
||||
}
|
||||
|
||||
TEST(WddmAllocationTest, whenAllocationIsNotShareableThenItDoesntReturnSharedHandleToModify) {
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace NEO {
|
||||
|
||||
using osHandle = unsigned int;
|
||||
inline osHandle toOsHandle(const void *handle) {
|
||||
|
||||
return static_cast<osHandle>(castToUint64(handle));
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ set(NEO_CORE_OS_INTERFACE_WDDM
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/configure_device_address_space_${DRIVER_MODEL}.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/set_gmm_input_args_${DRIVER_MODEL}.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/max_mem_alloc_size_${DRIVER_MODEL}.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/helper_${DRIVER_MODEL}.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm_defs.h
|
||||
@@ -108,12 +109,14 @@ set(NEO_CORE_OS_INTERFACE_WDDM
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_residency_controller.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows_defs.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows_wrapper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sys_calls_wrapper.h
|
||||
)
|
||||
|
||||
if(NOT WIN32 AND NOT DISABLE_WDDM_LINUX)
|
||||
list(APPEND NEO_CORE_OS_INTERFACE_WDDM
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_create_dxcore.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/trim_callback_stub.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sys_calls_wrapper_drm_or_wddm.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ bool Gdi::setupHwQueueProcAddresses() {
|
||||
bool Gdi::getAllProcAddresses() {
|
||||
openAdapterFromLuid = gdiDll->getProcAddress("D3DKMTOpenAdapterFromLuid");
|
||||
createAllocation_ = gdiDll->getProcAddress("D3DKMTCreateAllocation");
|
||||
shareObjects = reinterpret_cast<decltype(shareObjects)>(gdiDll->getProcAddress("D3DKMTShareObjects"));
|
||||
createAllocation2 = gdiDll->getProcAddress("D3DKMTCreateAllocation2");
|
||||
destroyAllocation2 = gdiDll->getProcAddress("D3DKMTDestroyAllocation2");
|
||||
queryAdapterInfo = gdiDll->getProcAddress("D3DKMTQueryAdapterInfo");
|
||||
@@ -82,7 +83,7 @@ bool Gdi::getAllProcAddresses() {
|
||||
|
||||
// clang-format off
|
||||
if (openAdapterFromLuid && createAllocation2
|
||||
&& destroyAllocation2 && queryAdapterInfo && closeAdapter && createDevice
|
||||
&& destroyAllocation2 && shareObjects && queryAdapterInfo && closeAdapter && createDevice
|
||||
&& destroyDevice && escape && createContext && destroyContext
|
||||
&& openResource && queryResourceInfo
|
||||
&& createSynchronizationObject && createSynchronizationObject2
|
||||
|
||||
@@ -24,6 +24,8 @@ class Gdi {
|
||||
ThkWrapper<IN OUT D3DKMT_OPENADAPTERFROMLUID *> openAdapterFromLuid{};
|
||||
ThkWrapper<IN OUT D3DKMT_CREATEALLOCATION *> createAllocation_{};
|
||||
ThkWrapper<IN OUT D3DKMT_CREATEALLOCATION *> createAllocation2{};
|
||||
NTSTATUS(APIENTRY *shareObjects)
|
||||
(UINT cObjects, const D3DKMT_HANDLE *hObjects, POBJECT_ATTRIBUTES pObjectAttributes, DWORD dwDesiredAccess, HANDLE *phSharedNtHandle) = {};
|
||||
ThkWrapper<IN CONST D3DKMT_DESTROYALLOCATION *> destroyAllocation{};
|
||||
ThkWrapper<IN CONST D3DKMT_DESTROYALLOCATION2 *> destroyAllocation2{};
|
||||
ThkWrapper<IN CONST D3DKMT_QUERYADAPTERINFO *> queryAdapterInfo{};
|
||||
|
||||
16
shared/source/os_interface/windows/sys_calls_wrapper.h
Normal file
16
shared/source/os_interface/windows/sys_calls_wrapper.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/source/os_interface/windows/d3dkmthk_wrapper.h"
|
||||
|
||||
namespace NEO {
|
||||
namespace SysCalls {
|
||||
BOOL closeHandle(HANDLE hObject);
|
||||
}
|
||||
} // namespace NEO
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/os_interface/windows/sys_calls_wrapper.h"
|
||||
|
||||
namespace NEO {
|
||||
namespace SysCalls {
|
||||
BOOL closeHandle(HANDLE hObject) {
|
||||
return TRUE;
|
||||
}
|
||||
} // namespace SysCalls
|
||||
} // namespace NEO
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/os_interface/windows/gdi_interface.h"
|
||||
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||
|
||||
namespace NEO {
|
||||
NTSTATUS Wddm::createNTHandle(const D3DKMT_HANDLE *resourceHandle, HANDLE *ntHandle) {
|
||||
return getGdi()->shareObjects(1, resourceHandle, nullptr, SHARED_ALLOCATION_WRITE, ntHandle);
|
||||
}
|
||||
} // namespace NEO
|
||||
19
shared/source/os_interface/windows/wddm/helper_wddm.cpp
Normal file
19
shared/source/os_interface/windows/wddm/helper_wddm.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/os_interface/windows/gdi_interface.h"
|
||||
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
NTSTATUS Wddm::createNTHandle(const D3DKMT_HANDLE *resourceHandle, HANDLE *ntHandle) {
|
||||
OBJECT_ATTRIBUTES objAttr = {};
|
||||
objAttr.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
|
||||
return getGdi()->shareObjects(1, resourceHandle, &objAttr, SHARED_ALLOCATION_WRITE, ntHandle);
|
||||
}
|
||||
} // namespace NEO
|
||||
@@ -495,7 +495,7 @@ bool Wddm::freeGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size)
|
||||
return status == STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, D3DKMT_HANDLE *outSharedHandle) {
|
||||
NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle) {
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
D3DDDI_ALLOCATIONINFO2 AllocationInfo = {};
|
||||
D3DKMT_CREATEALLOCATION CreateAllocation = {};
|
||||
@@ -522,7 +522,17 @@ NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKM
|
||||
outHandle = AllocationInfo.hAllocation;
|
||||
outResourceHandle = CreateAllocation.hResource;
|
||||
if (outSharedHandle) {
|
||||
*outSharedHandle = CreateAllocation.hGlobalShare;
|
||||
HANDLE ntSharedHandle = NULL;
|
||||
status = this->createNTHandle(&outResourceHandle, &ntSharedHandle);
|
||||
if (status != STATUS_SUCCESS) {
|
||||
DEBUG_BREAK_IF(true);
|
||||
[[maybe_unused]] auto destroyStatus = this->destroyAllocations(&outHandle, 1, outResourceHandle);
|
||||
outHandle = NULL_HANDLE;
|
||||
outResourceHandle = NULL_HANDLE;
|
||||
DEBUG_BREAK_IF(destroyStatus != STATUS_SUCCESS);
|
||||
return status;
|
||||
}
|
||||
*outSharedHandle = castToUint64(ntSharedHandle);
|
||||
}
|
||||
kmDafListener->notifyWriteTarget(featureTable->ftrKmdDaf, getAdapter(), device, outHandle, getGdi()->escape);
|
||||
|
||||
@@ -531,7 +541,7 @@ NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKM
|
||||
|
||||
bool Wddm::createAllocation(const Gmm *gmm, D3DKMT_HANDLE &outHandle) {
|
||||
D3DKMT_HANDLE outResourceHandle = NULL_HANDLE;
|
||||
D3DKMT_HANDLE *outSharedHandle = nullptr;
|
||||
uint64_t *outSharedHandle = nullptr;
|
||||
auto result = this->createAllocation(nullptr, gmm, outHandle, outResourceHandle, outSharedHandle);
|
||||
return STATUS_SUCCESS == result;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class Wddm : public DriverModel {
|
||||
MOCKABLE_VIRTUAL void applyAdditionalContextFlags(CREATECONTEXT_PVTDATA &privateData, OsContextWin &osContext, const HardwareInfo &hwInfo);
|
||||
MOCKABLE_VIRTUAL void applyAdditionalMapGPUVAFields(D3DDDI_MAPGPUVIRTUALADDRESS &MapGPUVA, Gmm *gmm);
|
||||
MOCKABLE_VIRTUAL bool freeGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size);
|
||||
MOCKABLE_VIRTUAL NTSTATUS createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, D3DKMT_HANDLE *outSharedHandle);
|
||||
MOCKABLE_VIRTUAL NTSTATUS createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle);
|
||||
MOCKABLE_VIRTUAL bool createAllocation(const Gmm *gmm, D3DKMT_HANDLE &outHandle);
|
||||
MOCKABLE_VIRTUAL NTSTATUS createAllocationsAndMapGpuVa(OsHandleStorage &osHandles);
|
||||
MOCKABLE_VIRTUAL bool destroyAllocations(const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle);
|
||||
@@ -92,6 +92,7 @@ class Wddm : public DriverModel {
|
||||
|
||||
MOCKABLE_VIRTUAL bool destroyContext(D3DKMT_HANDLE context);
|
||||
MOCKABLE_VIRTUAL bool queryAdapterInfo();
|
||||
MOCKABLE_VIRTUAL NTSTATUS createNTHandle(const D3DKMT_HANDLE *resourceHandle, HANDLE *ntHandle);
|
||||
|
||||
MOCKABLE_VIRTUAL bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments);
|
||||
MOCKABLE_VIRTUAL bool waitFromCpu(uint64_t lastFenceValue, const MonitoredFence &monitoredFence);
|
||||
|
||||
@@ -69,9 +69,13 @@ class WddmAllocation : public GraphicsAllocation {
|
||||
handles[handleIndex] = handle;
|
||||
}
|
||||
|
||||
D3DKMT_HANDLE *getSharedHandleToModify() {
|
||||
uint64_t peekInternalHandle(MemoryManager *memoryManager) override {
|
||||
return ntSecureHandle;
|
||||
}
|
||||
|
||||
uint64_t *getSharedHandleToModify() {
|
||||
if (shareable) {
|
||||
return &sharingInfo.sharedHandle;
|
||||
return &ntSecureHandle;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -102,6 +106,7 @@ class WddmAllocation : public GraphicsAllocation {
|
||||
bool allocInFrontWindowPool = false;
|
||||
|
||||
protected:
|
||||
uint64_t ntSecureHandle = 0u;
|
||||
std::string getHandleInfoString() const {
|
||||
std::stringstream ss;
|
||||
for (auto &handle : handles) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "shared/source/os_interface/hw_info_config.h"
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/source/os_interface/windows/os_context_win.h"
|
||||
#include "shared/source/os_interface/windows/sys_calls_wrapper.h"
|
||||
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||
#include "shared/source/os_interface/windows/wddm_allocation.h"
|
||||
#include "shared/source/os_interface/windows/wddm_residency_allocations_container.h"
|
||||
@@ -499,13 +500,17 @@ void WddmMemoryManager::freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation
|
||||
for (auto handleId = 0u; handleId < gfxAllocation->getNumGmms(); handleId++) {
|
||||
delete gfxAllocation->getGmm(handleId);
|
||||
}
|
||||
if (input->peekInternalHandle(nullptr) != 0u) {
|
||||
[[maybe_unused]] auto status = SysCalls::closeHandle(reinterpret_cast<void *>(reinterpret_cast<uintptr_t *>(input->peekInternalHandle(nullptr))));
|
||||
DEBUG_BREAK_IF(!status);
|
||||
}
|
||||
|
||||
if (input->peekSharedHandle() == false &&
|
||||
input->getDriverAllocatedCpuPtr() == nullptr &&
|
||||
input->fragmentsStorage.fragmentCount > 0) {
|
||||
cleanGraphicsMemoryCreatedFromHostPtr(gfxAllocation);
|
||||
} else {
|
||||
if (input->peekSharedHandle()) {
|
||||
if (input->peekSharedHandle() || input->peekInternalHandle(nullptr) != 0) {
|
||||
[[maybe_unused]] auto status = tryDeferDeletions(nullptr, 0, input->resourceHandle, gfxAllocation->getRootDeviceIndex());
|
||||
DEBUG_BREAK_IF(!status);
|
||||
} else {
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#pragma once
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#include <winternl.h>
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4005)
|
||||
#include <ntstatus.h>
|
||||
@@ -24,7 +27,9 @@
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-value"
|
||||
#endif
|
||||
|
||||
#include <winadapter.h>
|
||||
|
||||
#if __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@ D3DKMTCloseAdapter
|
||||
D3DKMTCreateDevice
|
||||
D3DKMTDestroyDevice
|
||||
D3DKMTEscape
|
||||
D3DKMTShareObjects
|
||||
D3DKMTCreateContextVirtual
|
||||
D3DKMTDestroyContext
|
||||
D3DKMTOpenResource
|
||||
|
||||
@@ -168,6 +168,11 @@ NTSTATUS __stdcall D3DKMTCreateAllocation2(IN OUT D3DKMT_CREATEALLOCATION *alloc
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS __stdcall D3DKMTShareObjects(UINT cObjects, const D3DKMT_HANDLE *hObjects, POBJECT_ATTRIBUTES pObjectAttributes, DWORD dwDesiredAccess, HANDLE *phSharedNtHandle) {
|
||||
*phSharedNtHandle = reinterpret_cast<HANDLE>(reinterpret_cast<void *>(reinterpret_cast<uintptr_t *>(0x123)));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static unsigned int DestroyAllocationWithResourceHandleCalled = 0u;
|
||||
static D3DKMT_DESTROYALLOCATION2 destroyalloc2 = {0};
|
||||
static D3DKMT_HANDLE LastDestroyedResourceHandle = 0;
|
||||
|
||||
@@ -89,7 +89,7 @@ NTSTATUS WddmMock::createAllocation(WddmAllocation *wddmAllocation) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
NTSTATUS WddmMock::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, D3DKMT_HANDLE *outSharedHandle) {
|
||||
NTSTATUS WddmMock::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle) {
|
||||
createAllocationResult.called++;
|
||||
if (callBaseDestroyAllocations) {
|
||||
createAllocationStatus = Wddm::createAllocation(alignedCpuPtr, gmm, outHandle, outResourceHandle, outSharedHandle);
|
||||
|
||||
@@ -57,7 +57,7 @@ class WddmMock : public Wddm {
|
||||
bool mapGpuVirtualAddress(Gmm *gmm, D3DKMT_HANDLE handle, D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_VIRTUAL_ADDRESS preferredAddress, D3DGPU_VIRTUAL_ADDRESS &gpuPtr) override;
|
||||
bool mapGpuVirtualAddress(WddmAllocation *allocation);
|
||||
bool freeGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size) override;
|
||||
NTSTATUS createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResource, D3DKMT_HANDLE *outSharedHandle) override;
|
||||
NTSTATUS createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResource, uint64_t *outSharedHandle) override;
|
||||
bool createAllocation(const Gmm *gmm, D3DKMT_HANDLE &outHandle) override;
|
||||
bool destroyAllocations(const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle) override;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ set(NEO_CORE_OS_INTERFACE_TESTS_WINDOWS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_preemption_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_special_heap_test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_shared_allocations_test.cpp
|
||||
)
|
||||
|
||||
set_property(GLOBAL PROPERTY NEO_CORE_OS_INTERFACE_TESTS_WINDOWS ${NEO_CORE_OS_INTERFACE_TESTS_WINDOWS})
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/gmm_helper/gmm.h"
|
||||
#include "shared/test/common/fixtures/mock_execution_environment_gmm_fixture.h"
|
||||
#include "shared/test/common/mocks/mock_wddm.h"
|
||||
#include "shared/test/common/os_interface/windows/wddm_fixture.h"
|
||||
|
||||
#include "test.h"
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
class WddmSharedAllocationsMock : public WddmMock {
|
||||
public:
|
||||
WddmSharedAllocationsMock(RootDeviceEnvironment &rootDeviceEnvironment) : WddmMock(rootDeviceEnvironment) {}
|
||||
WddmSharedAllocationsMock(std::unique_ptr<HwDeviceIdWddm> hwDeviceId, RootDeviceEnvironment &rootDeviceEnvironment) : WddmMock(std::move(hwDeviceId), rootDeviceEnvironment) {}
|
||||
NTSTATUS createNTHandle(const D3DKMT_HANDLE *resourceHandle, HANDLE *ntHandle) override {
|
||||
return static_cast<NTSTATUS>(0xfff);
|
||||
}
|
||||
};
|
||||
|
||||
class WddmSharedTestsFixture : public GdiDllFixture, public MockExecutionEnvironmentGmmFixture {
|
||||
public:
|
||||
void SetUp() override {
|
||||
MockExecutionEnvironmentGmmFixture::SetUp();
|
||||
GdiDllFixture::SetUp();
|
||||
rootDeviceEnvironment = executionEnvironment->rootDeviceEnvironments[0].get();
|
||||
wddm = new WddmSharedAllocationsMock(*rootDeviceEnvironment);
|
||||
wddmMockInterface = new WddmMockInterface20(*wddm);
|
||||
wddm->wddmInterface.reset(wddmMockInterface);
|
||||
rootDeviceEnvironment->osInterface = std::make_unique<OSInterface>();
|
||||
rootDeviceEnvironment->osInterface->setDriverModel(std::unique_ptr<DriverModel>(wddm));
|
||||
rootDeviceEnvironment->memoryOperationsInterface = std::make_unique<WddmMemoryOperationsHandler>(wddm);
|
||||
osInterface = rootDeviceEnvironment->osInterface.get();
|
||||
}
|
||||
|
||||
void init() {
|
||||
auto preemptionMode = PreemptionHelper::getDefaultPreemptionMode(*defaultHwInfo);
|
||||
wddmMockInterface = static_cast<WddmMockInterface20 *>(wddm->wddmInterface.release());
|
||||
wddm->init();
|
||||
wddm->wddmInterface.reset(wddmMockInterface);
|
||||
|
||||
auto hwInfo = rootDeviceEnvironment->getHardwareInfo();
|
||||
auto engine = HwHelper::get(defaultHwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*hwInfo)[0];
|
||||
osContext = std::make_unique<OsContextWin>(*osInterface->getDriverModel()->as<Wddm>(), 0u, EngineDescriptorHelper::getDefaultDescriptor(engine, preemptionMode));
|
||||
osContext->ensureContextInitialized();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
GdiDllFixture::TearDown();
|
||||
}
|
||||
|
||||
WddmSharedAllocationsMock *wddm = nullptr;
|
||||
OSInterface *osInterface;
|
||||
std::unique_ptr<OsContextWin> osContext;
|
||||
WddmMockInterface20 *wddmMockInterface = nullptr;
|
||||
RootDeviceEnvironment *rootDeviceEnvironment = nullptr;
|
||||
};
|
||||
|
||||
using WdmmSharedTests = Test<WddmSharedTestsFixture>;
|
||||
|
||||
TEST_F(WdmmSharedTests, WhenCreatingSharedAllocationAndGetNTHandleFailedThenAllocationIsDeletedAndHandlesAreSetToZero) {
|
||||
init();
|
||||
|
||||
D3DKMT_HANDLE handle = 32u;
|
||||
D3DKMT_HANDLE resourceHandle = 32u;
|
||||
uint64_t ntHandle = 0u;
|
||||
Gmm gmm(executionEnvironment->rootDeviceEnvironments[0]->getGmmClientContext(), nullptr, 20, 0, false, true, true, {});
|
||||
|
||||
EXPECT_NE(STATUS_SUCCESS, wddm->createAllocation(nullptr, &gmm, handle, resourceHandle, &ntHandle));
|
||||
EXPECT_EQ(wddm->destroyAllocationResult.called++, 1u);
|
||||
EXPECT_EQ(handle, 0u);
|
||||
EXPECT_EQ(resourceHandle, 0u);
|
||||
}
|
||||
Reference in New Issue
Block a user