diff --git a/core/os_interface/device_factory.cpp b/core/os_interface/device_factory.cpp index aa6327e9e9..e648240c80 100644 --- a/core/os_interface/device_factory.cpp +++ b/core/os_interface/device_factory.cpp @@ -89,24 +89,13 @@ bool DeviceFactory::isHwModeSelected() { bool DeviceFactory::getDevices(size_t &totalNumRootDevices, ExecutionEnvironment &executionEnvironment) { using HwDeviceIds = std::vector>; - HwDeviceIds hwDeviceIds; - - size_t numRootDevices = 1u; - if (DebugManager.flags.CreateMultipleRootDevices.get()) { - numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get(); - } - for (size_t i = 0; i < numRootDevices; i++) { - auto hwDeviceId = OSInterface::discoverDevices(); - if (hwDeviceId) { - hwDeviceIds.push_back(std::move(hwDeviceId)); - } - } - if (hwDeviceIds.empty()) { + HwDeviceIds hwDeviceIds = OSInterface::discoverDevices(); + totalNumRootDevices = hwDeviceIds.size(); + if (totalNumRootDevices == 0) { return false; } - totalNumRootDevices = numRootDevices; - executionEnvironment.prepareRootDeviceEnvironments(static_cast(numRootDevices)); + executionEnvironment.prepareRootDeviceEnvironments(static_cast(totalNumRootDevices)); uint32_t rootDeviceIndex = 0u; diff --git a/core/os_interface/linux/drm_neo.cpp b/core/os_interface/linux/drm_neo.cpp index 96fcaef6e9..d049650954 100644 --- a/core/os_interface/linux/drm_neo.cpp +++ b/core/os_interface/linux/drm_neo.cpp @@ -291,18 +291,26 @@ int Drm::setupHardwareInfo(DeviceDescriptor *device, bool setupFeatureTableAndWo return 0; } -std::unique_ptr OSInterface::discoverDevices() { +std::vector> OSInterface::discoverDevices() { + std::vector> hwDeviceIds; char fullPath[PATH_MAX]; + size_t numRootDevices = 1u; + if (DebugManager.flags.CreateMultipleRootDevices.get()) { + numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get(); + } if (DebugManager.flags.ForceDeviceId.get() != "unk") { snprintf(fullPath, PATH_MAX, "/dev/dri/by-path/pci-0000:%s-render", DebugManager.flags.ForceDeviceId.get().c_str()); int fileDescriptor = SysCalls::open(fullPath, O_RDWR); if (fileDescriptor >= 0) { if (Drm::isi915Version(fileDescriptor)) { - return std::make_unique(fileDescriptor); + while (hwDeviceIds.size() < numRootDevices) { + hwDeviceIds.push_back(std::make_unique(fileDescriptor)); + } + } else { + SysCalls::close(fileDescriptor); } - SysCalls::close(fileDescriptor); } - return nullptr; + return hwDeviceIds; } const char *pathPrefix = "/dev/dri/renderD"; @@ -314,13 +322,20 @@ std::unique_ptr OSInterface::discoverDevices() { int fileDescriptor = SysCalls::open(fullPath, O_RDWR); if (fileDescriptor >= 0) { if (Drm::isi915Version(fileDescriptor)) { - return std::make_unique(fileDescriptor); + hwDeviceIds.push_back(std::make_unique(fileDescriptor)); + break; + } else { + SysCalls::close(fileDescriptor); } - SysCalls::close(fileDescriptor); } } - - return nullptr; + if (hwDeviceIds.empty()) { + return hwDeviceIds; + } + while (hwDeviceIds.size() < numRootDevices) { + hwDeviceIds.push_back(std::make_unique(hwDeviceIds[0]->getFileDescriptor())); + } + return hwDeviceIds; } bool Drm::isi915Version(int fileDescriptor) { diff --git a/core/os_interface/os_interface.h b/core/os_interface/os_interface.h index 9acb99f1df..71743d245f 100644 --- a/core/os_interface/os_interface.h +++ b/core/os_interface/os_interface.h @@ -8,6 +8,7 @@ #pragma once #include #include +#include namespace NEO { class HwDeviceId; @@ -29,7 +30,7 @@ class OSInterface { static bool are64kbPagesEnabled(); uint32_t getDeviceHandle() const; void setGmmInputArgs(void *args); - static std::unique_ptr discoverDevices(); + static std::vector> discoverDevices(); protected: OSInterfaceImpl *osInterfaceImpl = nullptr; diff --git a/core/os_interface/windows/wddm/wddm.cpp b/core/os_interface/windows/wddm/wddm.cpp index d61e23a187..8cfe504f42 100644 --- a/core/os_interface/windows/wddm/wddm.cpp +++ b/core/os_interface/windows/wddm/wddm.cpp @@ -225,17 +225,25 @@ bool Wddm::destroyDevice() { return true; } -std::unique_ptr OSInterface::discoverDevices() { +std::unique_ptr createHwDeviceIdFromAdapterLuid(Gdi &gdi, LUID adapterLuid) { + D3DKMT_OPENADAPTERFROMLUID OpenAdapterData = {{0}}; + OpenAdapterData.AdapterLuid = adapterLuid; + auto status = gdi.openAdapterFromLuid(&OpenAdapterData); + + if (status == STATUS_SUCCESS) { + return std::make_unique(OpenAdapterData.hAdapter, adapterLuid, std::make_unique()); + } + return nullptr; +} + +std::vector> OSInterface::discoverDevices() { + std::vector> hwDeviceIds; auto gdi = std::make_unique(); - D3DKMT_HANDLE adapter = 0; - LUID adapterLuid{}; if (!gdi->isInitialized()) { - return nullptr; + return hwDeviceIds; } - NTSTATUS status = STATUS_UNSUCCESSFUL; - D3DKMT_OPENADAPTERFROMLUID OpenAdapterData = {{0}}; DXGI_ADAPTER_DESC1 OpenAdapterDesc = {{0}}; IDXGIFactory1 *pFactory = nullptr; @@ -246,12 +254,13 @@ std::unique_ptr OSInterface::discoverDevices() { HRESULT hr = Wddm::createDxgiFactory(__uuidof(IDXGIFactory), (void **)(&pFactory)); if ((hr != S_OK) || (pFactory == nullptr)) { - return nullptr; + return hwDeviceIds; } while (pFactory->EnumAdapters1(iDevNum++, &pAdapter) != DXGI_ERROR_NOT_FOUND) { hr = pAdapter->GetDesc1(&OpenAdapterDesc); if (hr == S_OK) { + bool createHwDeviceId = false; // Check for adapters that include either "Intel" or "Citrix" (which may // be virtualizing one of our adapters) in the description if ((wcsstr(OpenAdapterDesc.Description, L"Intel") != 0) || @@ -263,17 +272,24 @@ std::unique_ptr OSInterface::discoverDevices() { if (choosenDevice) { if (wcsstr(OpenAdapterDesc.Description, L"DCH-D") != 0) { if (wcsstr(igdrclPath.c_str(), L"_dch_d.inf") != 0) { - break; + createHwDeviceId = true; } } else if (wcsstr(OpenAdapterDesc.Description, L"DCH-I") != 0) { if (wcsstr(igdrclPath.c_str(), L"_dch_i.inf") != 0) { - break; + createHwDeviceId = true; } } else { - break; + createHwDeviceId = true; } } } + if (createHwDeviceId) { + auto hwDeviceId = createHwDeviceIdFromAdapterLuid(*gdi, OpenAdapterDesc.AdapterLuid); + if (hwDeviceId) { + hwDeviceIds.push_back(std::move(hwDeviceId)); + break; + } + } } // Release all the non-Intel adapters pAdapter->Release(); @@ -281,9 +297,6 @@ std::unique_ptr OSInterface::discoverDevices() { } if (pAdapter != nullptr) { - OpenAdapterData.AdapterLuid = OpenAdapterDesc.AdapterLuid; - status = gdi->openAdapterFromLuid(&OpenAdapterData); - // If an Intel adapter was found, release it here pAdapter->Release(); pAdapter = nullptr; } @@ -291,15 +304,19 @@ std::unique_ptr OSInterface::discoverDevices() { pFactory->Release(); pFactory = nullptr; } + size_t numRootDevices = 1u; + if (DebugManager.flags.CreateMultipleRootDevices.get()) { + numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get(); + } + if (hwDeviceIds.empty()) { + return hwDeviceIds; + } - if (status == STATUS_SUCCESS) { - adapter = OpenAdapterData.hAdapter; - adapterLuid = OpenAdapterDesc.AdapterLuid; + while (hwDeviceIds.size() < numRootDevices) { + hwDeviceIds.push_back(std::make_unique(hwDeviceIds[0]->getAdapter(), hwDeviceIds[0]->getAdapterLuid(), std::make_unique())); } - if (status == STATUS_SUCCESS) { - return std::make_unique(adapter, adapterLuid, std::move(gdi)); - } - return nullptr; + + return hwDeviceIds; } bool Wddm::evict(const D3DKMT_HANDLE *handleList, uint32_t numOfHandles, uint64_t &sizeToTrim) { diff --git a/unit_tests/linux/drm_wrap.h b/unit_tests/linux/drm_wrap.h index e9feed0c4a..4f32eab01c 100644 --- a/unit_tests/linux/drm_wrap.h +++ b/unit_tests/linux/drm_wrap.h @@ -15,9 +15,9 @@ class DrmWrap : public NEO::Drm { public: static NEO::Drm *createDrm(RootDeviceEnvironment &rootDeviceEnvironment) { - auto hwDeviceId = OSInterface::discoverDevices(); - if (hwDeviceId != nullptr) { - return NEO::Drm::create(std::move(hwDeviceId), rootDeviceEnvironment); + auto hwDeviceIds = OSInterface::discoverDevices(); + if (!hwDeviceIds.empty()) { + return NEO::Drm::create(std::move(hwDeviceIds[0]), rootDeviceEnvironment); } return nullptr; } diff --git a/unit_tests/linux/main_linux_dll.cpp b/unit_tests/linux/main_linux_dll.cpp index 3f6b38bf7a..d3668b87bd 100644 --- a/unit_tests/linux/main_linux_dll.cpp +++ b/unit_tests/linux/main_linux_dll.cpp @@ -64,8 +64,8 @@ TEST(DrmTest, GivenSelectedNotExistingDeviceWhenGetDeviceFdThenFail) { VariableBackup backupOpenFull(&openFull); openFull = testOpen; openRetVal = -1; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_EQ(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_TRUE(hwDeviceIds.empty()); } TEST(DrmTest, GivenSelectedExistingDeviceWhenGetDeviceFdThenReturnFd) { @@ -74,8 +74,9 @@ TEST(DrmTest, GivenSelectedExistingDeviceWhenGetDeviceFdThenReturnFd) { VariableBackup backupOpenFull(&openFull); openRetVal = 1023; // fakeFd openFull = testOpen; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_NE(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_EQ(1u, hwDeviceIds.size()); + EXPECT_NE(nullptr, hwDeviceIds[0].get()); } TEST(DrmTest, GivenSelectedIncorectDeviceWhenGetDeviceFdThenFail) { @@ -85,8 +86,8 @@ TEST(DrmTest, GivenSelectedIncorectDeviceWhenGetDeviceFdThenFail) { openFull = testOpen; openRetVal = 1024; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_EQ(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_TRUE(hwDeviceIds.empty()); } TEST_F(DrmTests, createReturnsDrm) { diff --git a/unit_tests/os_interface/device_factory_tests.cpp b/unit_tests/os_interface/device_factory_tests.cpp index 2e60a65e03..6578835552 100644 --- a/unit_tests/os_interface/device_factory_tests.cpp +++ b/unit_tests/os_interface/device_factory_tests.cpp @@ -258,8 +258,8 @@ TEST(DeviceFactory, givenNonHwModeSelectedWhenIsHwModeSelectedIsCalledThenFalseI TEST(DiscoverDevices, whenDiscoverDevicesAndForceDeviceIdIsDifferentFromTheExistingDeviceThenReturnNullptr) { DebugManagerStateRestore stateRestore; DebugManager.flags.ForceDeviceId.set("invalid"); - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_EQ(nullptr, hwDeviceId); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_TRUE(hwDeviceIds.empty()); } TEST(DiscoverDevices, whenDiscoverDevicesAndForceDeviceIdIsDifferentFromTheExistingDeviceThenGetDevicesReturnsFalse) { diff --git a/unit_tests/os_interface/linux/sys_calls_linux_ult.cpp b/unit_tests/os_interface/linux/sys_calls_linux_ult.cpp index 7a2f385b27..69629788e8 100644 --- a/unit_tests/os_interface/linux/sys_calls_linux_ult.cpp +++ b/unit_tests/os_interface/linux/sys_calls_linux_ult.cpp @@ -30,7 +30,10 @@ int open(const char *file, int flags) { if (strcmp(file, "/dev/dri/by-path/pci-0000:invalid-render") == 0) { return 0; } - return fakeFileDescriptor; + if (strcmp(file, "/dev/dri/renderD129") == 0) { + return fakeFileDescriptor; + } + return 0; } int ioctl(int fileDescriptor, unsigned long int request, void *arg) { if (fileDescriptor == fakeFileDescriptor) { diff --git a/unit_tests/os_interface/windows/wddm20_tests.cpp b/unit_tests/os_interface/windows/wddm20_tests.cpp index b30568697d..71753f16df 100644 --- a/unit_tests/os_interface/windows/wddm20_tests.cpp +++ b/unit_tests/os_interface/windows/wddm20_tests.cpp @@ -105,8 +105,8 @@ TEST(WddmDiscoverDevices, WhenAdapterDescriptionContainsDCHDAndgdrclPathDoesntCo VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); igdrclPathBackup = L"intel_dch.inf"; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_EQ(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_TRUE(hwDeviceIds.empty()); } TEST(WddmDiscoverDevices, WhenAdapterDescriptionContainsDCHIAndgdrclPathDoesntContainDchIThenNoDeviceIsDiscovered) { @@ -115,8 +115,8 @@ TEST(WddmDiscoverDevices, WhenAdapterDescriptionContainsDCHIAndgdrclPathDoesntCo VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); igdrclPathBackup = L"intel_dch.inf"; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_EQ(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_TRUE(hwDeviceIds.empty()); } TEST(WddmDiscoverDevices, WhenAdapterDescriptionContainsDCHDAndgdrclPathContainsDchDThenAdapterIsDiscovered) { @@ -125,8 +125,9 @@ TEST(WddmDiscoverDevices, WhenAdapterDescriptionContainsDCHDAndgdrclPathContains VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); igdrclPathBackup = L"intel_dch_d.inf"; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_NE(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_EQ(1u, hwDeviceIds.size()); + EXPECT_NE(nullptr, hwDeviceIds[0].get()); } TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHIAndgdrclPathContainsDchIThenAdapterIsDiscovered) { @@ -135,16 +136,18 @@ TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHIAndgdrclPathConta VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); igdrclPathBackup = L"intel_dch_i.inf"; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_NE(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_EQ(1u, hwDeviceIds.size()); + EXPECT_NE(nullptr, hwDeviceIds[0].get()); } TEST(WddmDiscoverDevices, WhenAdapterDescriptionContainsVirtualRenderThenAdapterIsDiscovered) { VariableBackup descriptionBackup(&UltIDXGIAdapter1::description); descriptionBackup = L"Virtual Render"; - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_NE(nullptr, hwDeviceId.get()); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_EQ(1u, hwDeviceIds.size()); + EXPECT_NE(nullptr, hwDeviceIds[0].get()); } TEST(Wddm20EnumAdaptersTest, expectTrue) { @@ -1046,7 +1049,7 @@ TEST_F(WddmGfxPartitionTest, initGfxPartitionHeapStandard64KBSplit) { struct MockWddm : public Wddm { using Wddm::gfxPartition; - MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(OSInterface::discoverDevices(), rootDeviceEnvironment) {} + MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(std::move(OSInterface::discoverDevices()[0]), rootDeviceEnvironment) {} }; MockWddm wddm(*executionEnvironment->rootDeviceEnvironments[0].get()); @@ -1066,8 +1069,9 @@ TEST_F(WddmGfxPartitionTest, initGfxPartitionHeapStandard64KBSplit) { TEST_F(Wddm20Tests, givenWddmWhenDiscoverDevicesAndForceDeviceIdIsTheSameAsTheExistingDeviceThenReturnTheAdapter) { DebugManagerStateRestore stateRestore; DebugManager.flags.ForceDeviceId.set("1234"); // Existing device Id - auto hwDeviceId = OSInterface::discoverDevices(); - EXPECT_NE(nullptr, hwDeviceId); + auto hwDeviceIds = OSInterface::discoverDevices(); + EXPECT_EQ(1u, hwDeviceIds.size()); + EXPECT_NE(nullptr, hwDeviceIds[0].get()); } TEST_F(WddmTest, WhenFeatureFlagHwQueueIsDisabledThenReturnWddm20Version) { diff --git a/unit_tests/windows/wddm_create_tests.cpp b/unit_tests/windows/wddm_create_tests.cpp index ad6e63c1c7..11c592e085 100644 --- a/unit_tests/windows/wddm_create_tests.cpp +++ b/unit_tests/windows/wddm_create_tests.cpp @@ -20,7 +20,7 @@ using namespace NEO; TEST(wddmCreateTests, givenInputVersionWhenCreatingThenCreateRequestedObject) { MockExecutionEnvironment executionEnvironment; RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment); - auto hwDeviceId = OSInterface::discoverDevices(); - std::unique_ptr wddm(Wddm::createWddm(std::move(hwDeviceId), rootDeviceEnvironment)); + auto hwDeviceIds = OSInterface::discoverDevices(); + std::unique_ptr wddm(Wddm::createWddm(std::move(hwDeviceIds[0]), rootDeviceEnvironment)); EXPECT_EQ(typeid(*wddm.get()), typeid(Wddm)); }