diff --git a/opencl/extensions/public/cl_ext_private.h b/opencl/extensions/public/cl_ext_private.h index 77da6f9e82..c370af790a 100644 --- a/opencl/extensions/public/cl_ext_private.h +++ b/opencl/extensions/public/cl_ext_private.h @@ -210,3 +210,18 @@ typedef cl_bitfield cl_device_feature_capabilities_intel; /* For GPU devices, version 1.0.0: */ #define CL_DEVICE_FEATURE_FLAG_DP4A_INTEL (1 << 0) + +/**************************************** + * cl_khr_pci_bus_info extension * + ***************************************/ +#define cl_khr_pci_bus_info 1 + +// New queries for clGetDeviceInfo: +#define CL_DEVICE_PCI_BUS_INFO_KHR 0x410F + +typedef struct _cl_device_pci_bus_info_khr { + cl_uint pci_domain; + cl_uint pci_bus; + cl_uint pci_device; + cl_uint pci_function; +} cl_device_pci_bus_info_khr; diff --git a/opencl/source/cl_device/cl_device.cpp b/opencl/source/cl_device/cl_device.cpp index d571590aad..8e91f56472 100644 --- a/opencl/source/cl_device/cl_device.cpp +++ b/opencl/source/cl_device/cl_device.cpp @@ -263,4 +263,9 @@ void ClDevice::getQueueFamilyName(char *outputName, size_t maxOutputNameLength, Platform *ClDevice::getPlatform() const { return castToObject(platformId); } +bool ClDevice::isPciBusInfoValid() const { + return deviceInfo.pciBusInfo.pci_domain != PhysicalDevicePciBusInfo::InvalidValue && deviceInfo.pciBusInfo.pci_bus != PhysicalDevicePciBusInfo::InvalidValue && + deviceInfo.pciBusInfo.pci_device != PhysicalDevicePciBusInfo::InvalidValue && deviceInfo.pciBusInfo.pci_function != PhysicalDevicePciBusInfo::InvalidValue; +} + } // namespace NEO diff --git a/opencl/source/cl_device/cl_device.h b/opencl/source/cl_device/cl_device.h index 5e65f9cfa1..99d1a0de66 100644 --- a/opencl/source/cl_device/cl_device.h +++ b/opencl/source/cl_device/cl_device.h @@ -121,6 +121,7 @@ class ClDevice : public BaseObject<_cl_device_id> { DeviceBitfield getDeviceBitfield() const; bool isDeviceEnqueueSupported() const; bool arePipesSupported() const; + bool isPciBusInfoValid() const; static cl_command_queue_capabilities_intel getQueueFamilyCapabilitiesAll(); MOCKABLE_VIRTUAL cl_command_queue_capabilities_intel getQueueFamilyCapabilities(EngineGroupType type); diff --git a/opencl/source/cl_device/cl_device_caps.cpp b/opencl/source/cl_device/cl_device_caps.cpp index ca27764e05..d1c21b93c9 100644 --- a/opencl/source/cl_device/cl_device_caps.cpp +++ b/opencl/source/cl_device/cl_device_caps.cpp @@ -202,6 +202,21 @@ void ClDevice::initializeCaps() { deviceExtensions += sharingFactory.getExtensions(driverInfo.get()); } + PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); + + if (driverInfo) { + pciBusInfo = driverInfo->getPciBusInfo(); + } + + deviceInfo.pciBusInfo.pci_domain = pciBusInfo.pciDomain; + deviceInfo.pciBusInfo.pci_bus = pciBusInfo.pciBus; + deviceInfo.pciBusInfo.pci_device = pciBusInfo.pciDevice; + deviceInfo.pciBusInfo.pci_function = pciBusInfo.pciFunction; + + if (isPciBusInfoValid()) { + deviceExtensions += "cl_khr_pci_bus_info "; + } + deviceExtensions += hwHelper.getExtensions(); deviceInfo.deviceExtensions = deviceExtensions.c_str(); diff --git a/opencl/source/cl_device/cl_device_info.cpp b/opencl/source/cl_device/cl_device_info.cpp index 69f9516b93..d93e8cca56 100644 --- a/opencl/source/cl_device/cl_device_info.cpp +++ b/opencl/source/cl_device/cl_device_info.cpp @@ -286,6 +286,12 @@ cl_int ClDevice::getDeviceInfo(cl_device_info paramName, retSize = srcSize = sizeof(cl_device_feature_capabilities_intel); break; } + case CL_DEVICE_PCI_BUS_INFO_KHR: + if (isPciBusInfoValid()) { + src = &deviceInfo.pciBusInfo; + retSize = srcSize = sizeof(deviceInfo.pciBusInfo); + } + break; default: if (getDeviceInfoForImage(paramName, src, srcSize, retSize) && !getSharedDeviceInfo().imageSupport) { src = &value; diff --git a/opencl/source/cl_device/cl_device_info.h b/opencl/source/cl_device/cl_device_info.h index 43a0eb6db4..002a8733fa 100644 --- a/opencl/source/cl_device/cl_device_info.h +++ b/opencl/source/cl_device/cl_device_info.h @@ -129,6 +129,7 @@ struct ClDeviceInfo { cl_uint internalDriverVersion; cl_uint grfSize; bool preemptionSupported; + cl_device_pci_bus_info_khr pciBusInfo; /* Extensions supported */ bool nv12Extension; bool vmeExtension; diff --git a/opencl/test/unit_test/device/device_caps_tests.cpp b/opencl/test/unit_test/device/device_caps_tests.cpp index 1820d79fc5..038bbffbf9 100644 --- a/opencl/test/unit_test/device/device_caps_tests.cpp +++ b/opencl/test/unit_test/device/device_caps_tests.cpp @@ -8,11 +8,11 @@ #include "shared/source/command_stream/command_stream_receiver.h" #include "shared/source/helpers/hw_helper.h" #include "shared/source/memory_manager/os_agnostic_memory_manager.h" -#include "shared/source/os_interface/driver_info.h" #include "shared/source/os_interface/os_interface.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/variable_backup.h" #include "shared/test/common/mocks/mock_device.h" +#include "shared/test/common/mocks/mock_driver_info.h" #include "shared/test/common/mocks/mock_sip.h" #include "opencl/source/platform/extensions.h" @@ -1219,31 +1219,57 @@ HWTEST_F(DeviceGetCapsTest, givenDeviceThatHasHighNumberOfExecutionUnitsWhenMaxW EXPECT_EQ(device->getSharedDeviceInfo().maxWorkGroupSize / hwHelper.getMinimalSIMDSize(), device->getDeviceInfo().maxNumOfSubGroups); } -class DriverInfoMock : public DriverInfo { - public: - DriverInfoMock(){}; - - const static std::string testDeviceName; - const static std::string testVersion; - - std::string getDeviceName(std::string defaultName) override { return testDeviceName; }; - std::string getVersion(std::string defaultVersion) override { return testVersion; }; -}; - -const std::string DriverInfoMock::testDeviceName = "testDeviceName"; -const std::string DriverInfoMock::testVersion = "testVersion"; - TEST_F(DeviceGetCapsTest, givenSystemWithDriverInfoWhenGettingNameAndVersionThenReturnValuesFromDriverInfo) { auto device = std::make_unique(MockDevice::createWithNewExecutionEnvironment(defaultHwInfo.get())); + const std::string testDeviceName = "testDeviceName"; + const std::string testVersion = "testVersion"; + DriverInfoMock *driverInfoMock = new DriverInfoMock(); + driverInfoMock->setDeviceName(testDeviceName); + driverInfoMock->setVersion(testVersion); + device->driverInfo.reset(driverInfoMock); device->initializeCaps(); const auto &caps = device->getDeviceInfo(); - EXPECT_STREQ(DriverInfoMock::testDeviceName.c_str(), caps.name); - EXPECT_STREQ(DriverInfoMock::testVersion.c_str(), caps.driverVersion); + EXPECT_STREQ(testDeviceName.c_str(), caps.name); + EXPECT_STREQ(testVersion.c_str(), caps.driverVersion); +} + +TEST_F(DeviceGetCapsTest, givenNoPciBusInfoThenPciBusInfoExtensionNotAvailable) { + const PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); + + DriverInfoMock *driverInfoMock = new DriverInfoMock(); + driverInfoMock->setPciBusInfo(pciBusInfo); + + auto device = std::make_unique(MockDevice::createWithNewExecutionEnvironment(defaultHwInfo.get())); + device->driverInfo.reset(driverInfoMock); + device->initializeCaps(); + + const auto &caps = device->getDeviceInfo(); + EXPECT_THAT(caps.deviceExtensions, testing::Not(testing::HasSubstr("cl_khr_pci_bus_info"))); +} + +TEST_F(DeviceGetCapsTest, givenPciBusInfoThenPciBusInfoExtensionAvailable) { + const PhysicalDevicePciBusInfo pciBusInfo(1, 2, 3, 4); + + DriverInfoMock *driverInfoMock = new DriverInfoMock(); + driverInfoMock->setPciBusInfo(pciBusInfo); + + auto device = std::make_unique(MockDevice::createWithNewExecutionEnvironment(defaultHwInfo.get())); + device->driverInfo.reset(driverInfoMock); + device->initializeCaps(); + + const auto &caps = device->getDeviceInfo(); + + EXPECT_THAT(caps.deviceExtensions, testing::HasSubstr("cl_khr_pci_bus_info")); + + EXPECT_EQ(caps.pciBusInfo.pci_domain, pciBusInfo.pciDomain); + EXPECT_EQ(caps.pciBusInfo.pci_bus, pciBusInfo.pciBus); + EXPECT_EQ(caps.pciBusInfo.pci_device, pciBusInfo.pciDevice); + EXPECT_EQ(caps.pciBusInfo.pci_function, pciBusInfo.pciFunction); } static bool getPlanarYuvHeightCalled = false; diff --git a/opencl/test/unit_test/device/device_tests.cpp b/opencl/test/unit_test/device/device_tests.cpp index 592f29f472..c8cf8d095e 100644 --- a/opencl/test/unit_test/device/device_tests.cpp +++ b/opencl/test/unit_test/device/device_tests.cpp @@ -13,6 +13,7 @@ #include "shared/test/common/helpers/ult_hw_config.h" #include "shared/test/common/helpers/unit_test_helper.h" #include "shared/test/common/helpers/variable_backup.h" +#include "shared/test/common/mocks/mock_driver_info.h" #include "shared/test/common/mocks/ult_device_factory.h" #include "opencl/source/command_stream/tbx_command_stream_receiver.h" @@ -147,6 +148,36 @@ TEST_F(DeviceTest, WhenRetainingThenReferenceIsOneAndApiIsUsed) { ASSERT_EQ(1, pClDevice->getReference()); } +TEST_F(DeviceTest, givenNoPciBusInfoThenIsPciBusInfoValidReturnsFalse) { + PhysicalDevicePciBusInfo invalidPciBusInfoList[] = { + PhysicalDevicePciBusInfo(0, 1, 2, PhysicalDevicePciBusInfo::InvalidValue), + PhysicalDevicePciBusInfo(0, 1, PhysicalDevicePciBusInfo::InvalidValue, 3), + PhysicalDevicePciBusInfo(0, PhysicalDevicePciBusInfo::InvalidValue, 2, 3), + PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, 1, 2, 3)}; + + for (auto pciBusInfo : invalidPciBusInfoList) { + auto driverInfo = new DriverInfoMock(); + driverInfo->setPciBusInfo(pciBusInfo); + + pClDevice->driverInfo.reset(driverInfo); + pClDevice->initializeCaps(); + + EXPECT_FALSE(pClDevice->isPciBusInfoValid()); + } +} + +TEST_F(DeviceTest, givenPciBusInfoThenIsPciBusInfoValidReturnsTrue) { + PhysicalDevicePciBusInfo pciBusInfo(0, 1, 2, 3); + + auto driverInfo = new DriverInfoMock(); + driverInfo->setPciBusInfo(pciBusInfo); + + pClDevice->driverInfo.reset(driverInfo); + pClDevice->initializeCaps(); + + EXPECT_TRUE(pClDevice->isPciBusInfoValid()); +} + HWTEST_F(DeviceTest, WhenDeviceIsCreatedThenActualEngineTypeIsSameAsDefault) { HardwareInfo hwInfo = *defaultHwInfo; if (hwInfo.capabilityTable.defaultEngineType == aub_stream::EngineType::ENGINE_CCS) { diff --git a/opencl/test/unit_test/device/get_device_info_tests.cpp b/opencl/test/unit_test/device/get_device_info_tests.cpp index 023bab1c5a..5b2926eb65 100644 --- a/opencl/test/unit_test/device/get_device_info_tests.cpp +++ b/opencl/test/unit_test/device/get_device_info_tests.cpp @@ -7,6 +7,7 @@ #include "shared/source/helpers/get_info.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" +#include "shared/test/common/mocks/mock_driver_info.h" #include "opencl/source/cl_device/cl_device_info_map.h" #include "opencl/source/helpers/cl_hw_helper.h" @@ -994,6 +995,48 @@ TEST(GetDeviceInfoTest, givenDeviceWithSubDevicesWhenGettingNumberOfComputeUnits EXPECT_EQ(sizeof(numComputeUnits), retSize); } +TEST(GetDeviceInfoTest, givenPciBusInfoWhenGettingPciBusInfoForDeviceThenPciBusInfoIsReturned) { + PhysicalDevicePciBusInfo pciBusInfo(0, 1, 2, 3); + + auto driverInfo = new DriverInfoMock(); + driverInfo->setPciBusInfo(pciBusInfo); + + auto device = std::make_unique(MockDevice::createWithNewExecutionEnvironment(nullptr)); + device->driverInfo.reset(driverInfo); + device->initializeCaps(); + + cl_device_pci_bus_info_khr devicePciBusInfo; + + size_t sizeReturned = 0; + auto retVal = device->getDeviceInfo(CL_DEVICE_PCI_BUS_INFO_KHR, 0, nullptr, &sizeReturned); + + ASSERT_EQ(retVal, CL_SUCCESS); + ASSERT_EQ(sizeReturned, sizeof(devicePciBusInfo)); + + retVal = device->getDeviceInfo(CL_DEVICE_PCI_BUS_INFO_KHR, sizeof(devicePciBusInfo), &devicePciBusInfo, nullptr); + ASSERT_EQ(CL_SUCCESS, retVal); + + EXPECT_EQ(devicePciBusInfo.pci_domain, pciBusInfo.pciDomain); + EXPECT_EQ(devicePciBusInfo.pci_bus, pciBusInfo.pciBus); + EXPECT_EQ(devicePciBusInfo.pci_device, pciBusInfo.pciDevice); + EXPECT_EQ(devicePciBusInfo.pci_function, pciBusInfo.pciFunction); +} + +TEST(GetDeviceInfoTest, givenPciBusInfoIsNotAvailableWhenGettingPciBusInfoForDeviceThenInvalidValueIsReturned) { + PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); + + auto driverInfo = new DriverInfoMock(); + driverInfo->setPciBusInfo(pciBusInfo); + + auto device = std::make_unique(MockDevice::createWithNewExecutionEnvironment(nullptr)); + device->driverInfo.reset(driverInfo); + device->initializeCaps(); + + auto retVal = device->getDeviceInfo(CL_DEVICE_PCI_BUS_INFO_KHR, 0, nullptr, nullptr); + + ASSERT_EQ(retVal, CL_INVALID_VALUE); +} + struct DeviceAttributeQueryTest : public ::testing::TestWithParam { void SetUp() override { param = GetParam(); diff --git a/opencl/test/unit_test/linux/main_linux_dll.cpp b/opencl/test/unit_test/linux/main_linux_dll.cpp index b8c42ae4bd..d0eec47b27 100644 --- a/opencl/test/unit_test/linux/main_linux_dll.cpp +++ b/opencl/test/unit_test/linux/main_linux_dll.cpp @@ -9,6 +9,7 @@ #include "shared/source/helpers/aligned_memory.h" #include "shared/source/helpers/basic_math.h" #include "shared/source/memory_manager/memory_manager.h" +#include "shared/source/os_interface/driver_info.h" #include "shared/source/os_interface/linux/allocator_helper.h" #include "shared/source/os_interface/linux/os_interface.h" #include "shared/source/os_interface/linux/sys_calls.h" @@ -716,3 +717,49 @@ TEST(PlatformsDestructor, whenGlobalPlatformsDestructorIsCalledThenGlobalPlatfor EXPECT_EQ(nullptr, platformsImpl); platformsImpl = new std::vector>; } + +TEST_F(DrmTests, givenInvalidPciPathThenPciBusInfoIsNotAvailable) { + VariableBackup backupOpenFull(&openFull); + VariableBackup backupOpenDir(&failOnOpenDir, false); + VariableBackup backupEntryIndex(&entryIndex, 0u); + + openFull = openWithCounter; + entryIndex = 1; + openCounter = 1; + + const uint32_t invVal = PhysicalDevicePciBusInfo::InvalidValue; + + auto drm = DrmWrap::createDrm(*rootDeviceEnvironment); + ASSERT_NE(drm, nullptr); + EXPECT_EQ(drm->getPciBusInfo().pciDomain, invVal); + EXPECT_EQ(drm->getPciBusInfo().pciBus, invVal); + EXPECT_EQ(drm->getPciBusInfo().pciDevice, invVal); + EXPECT_EQ(drm->getPciBusInfo().pciFunction, invVal); +} + +TEST_F(DrmTests, givenValidPciPathThenPciBusInfoIsAvailable) { + VariableBackup backupOpenFull(&openFull); + VariableBackup backupOpenDir(&failOnOpenDir, false); + VariableBackup backupEntryIndex(&entryIndex, 0u); + + openFull = openWithCounter; + entryIndex = 4; + openCounter = 2; + + auto drm = DrmWrap::createDrm(*rootDeviceEnvironment); + ASSERT_NE(drm, nullptr); + EXPECT_EQ(drm->getPciBusInfo().pciDomain, 0u); + EXPECT_EQ(drm->getPciBusInfo().pciBus, 0u); + EXPECT_EQ(drm->getPciBusInfo().pciDevice, 2u); + EXPECT_EQ(drm->getPciBusInfo().pciFunction, 1u); + + entryIndex = 5; + openCounter = 1; + + drm = DrmWrap::createDrm(*rootDeviceEnvironment); + ASSERT_NE(drm, nullptr); + EXPECT_EQ(drm->getPciBusInfo().pciDomain, 0u); + EXPECT_EQ(drm->getPciBusInfo().pciBus, 3u); + EXPECT_EQ(drm->getPciBusInfo().pciDevice, 0u); + EXPECT_EQ(drm->getPciBusInfo().pciFunction, 0u); +} diff --git a/opencl/test/unit_test/linux/mock_os_layer.cpp b/opencl/test/unit_test/linux/mock_os_layer.cpp index ec62800ad0..b6b98c3f37 100644 --- a/opencl/test/unit_test/linux/mock_os_layer.cpp +++ b/opencl/test/unit_test/linux/mock_os_layer.cpp @@ -102,17 +102,19 @@ DIR *opendir(const char *name) { int closedir(DIR *dirp) { return 0u; } -uint32_t entryIndex = 0u; -const uint32_t numEntries = 4u; struct dirent entries[] = { {0, 0, 0, 0, "."}, {0, 0, 0, 0, "pci-0000:test1-render"}, {0, 0, 0, 0, "pci-0000:test2-render"}, {0, 0, 0, 0, "pci-0000:1234-render"}, - + {0, 0, 0, 0, "pci-0000:0:2.1-render"}, + {0, 0, 0, 0, "pci-0000:3:0.0-render"}, }; +uint32_t entryIndex = 0u; +const uint32_t numEntries = sizeof(entries) / sizeof(entries[0]); + struct dirent *readdir(DIR *dir) { if (entryIndex >= numEntries) { entryIndex = 0; diff --git a/opencl/test/unit_test/os_interface/windows/driver_info_tests.cpp b/opencl/test/unit_test/os_interface/windows/driver_info_tests.cpp index a94ae0cc67..8f9ba1e67e 100644 --- a/opencl/test/unit_test/os_interface/windows/driver_info_tests.cpp +++ b/opencl/test/unit_test/os_interface/windows/driver_info_tests.cpp @@ -83,7 +83,7 @@ class MockDriverInfoWindows : public DriverInfoWindows { static MockDriverInfoWindows *create(std::string path) { - auto result = new MockDriverInfoWindows(""); + auto result = new MockDriverInfoWindows("", PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue)); result->reader = new TestedRegistryReader(path); result->registryReader.reset(result->reader); @@ -152,7 +152,7 @@ struct DriverInfoWindowsTest : public ::testing::Test { DriverInfoWindows::createRegistryReaderFunc = [](const std::string &) -> std::unique_ptr { return std::make_unique(); }; - driverInfo = std::make_unique(""); + driverInfo = std::make_unique("", PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue)); } VariableBackup createFuncBackup{&DriverInfoWindows::createRegistryReaderFunc}; @@ -178,7 +178,7 @@ TEST_F(DriverInfoWindowsTest, GivenDriverInfoWhenThenReturnNonNullptr) { }; TEST(DriverInfo, givenDriverInfoWhenGetStringReturnNotMeaningEmptyStringThenEnableSharingSupport) { - MockDriverInfoWindows driverInfo(""); + MockDriverInfoWindows driverInfo("", PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue)); MockRegistryReader *registryReaderMock = new MockRegistryReader(); driverInfo.registryReader.reset(registryReaderMock); @@ -190,7 +190,7 @@ TEST(DriverInfo, givenDriverInfoWhenGetStringReturnNotMeaningEmptyStringThenEnab }; TEST(DriverInfo, givenDriverInfoWhenGetStringReturnMeaningEmptyStringThenDisableSharingSupport) { - MockDriverInfoWindows driverInfo(""); + MockDriverInfoWindows driverInfo("", PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue)); MockRegistryReader *registryReaderMock = new MockRegistryReader(); registryReaderMock->returnString = "<>"; driverInfo.registryReader.reset(registryReaderMock); @@ -206,7 +206,7 @@ TEST(DriverInfo, givenFullPathToRegistryWhenCreatingDriverInfoWindowsThenTheRegi std::string registryPath = "Path\\In\\Registry"; std::string fullRegistryPath = "\\REGISTRY\\MACHINE\\" + registryPath; std::string expectedTrimmedRegistryPath = registryPath; - MockDriverInfoWindows driverInfo(std::move(fullRegistryPath)); + MockDriverInfoWindows driverInfo(std::move(fullRegistryPath), PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue)); EXPECT_STREQ(expectedTrimmedRegistryPath.c_str(), driverInfo.path.c_str()); }; diff --git a/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp b/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp index 62c8a81eb6..9940187860 100644 --- a/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp +++ b/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp @@ -1553,3 +1553,83 @@ TEST_F(WddmTestWithMockGdiDll, givenValidInputwhenSettingAllocationPriorityThenT EXPECT_TRUE(wddm->setAllocationPriority(handles, 2, DXGI_RESOURCE_PRIORITY_NORMAL)); EXPECT_EQ(DXGI_RESOURCE_PRIORITY_NORMAL, getLastPriorityFcn()); } + +struct GdiWithMockedQueryAdapterInfoFunc : public MockGdi { + GdiWithMockedQueryAdapterInfoFunc() : MockGdi() { + queryAdapterInfo = mockQueryAdapterInfo; + GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled = 0u; + } + static NTSTATUS __stdcall mockQueryAdapterInfo(IN CONST D3DKMT_QUERYADAPTERINFO *adapterInfo) { + ++queryAdapterInfoCalled; + + if (queryAdapterInfoCallAlwaysReturnsUnsuccessful) { + return STATUS_UNSUCCESSFUL; + } + + if (adapterInfo->Type != KMTQAITYPE_ADAPTERADDRESS) { + return STATUS_NOT_IMPLEMENTED; + } + + if (adapterInfo->PrivateDriverDataSize != sizeof(D3DKMT_ADAPTERADDRESS)) { + return STATUS_INFO_LENGTH_MISMATCH; + } + + D3DKMT_ADAPTERADDRESS *adapterAddress = static_cast(adapterInfo->pPrivateDriverData); + adapterAddress->BusNumber = 1; + adapterAddress->DeviceNumber = 2; + adapterAddress->FunctionNumber = 3; + + return STATUS_SUCCESS; + } + static uint32_t queryAdapterInfoCalled; + static bool queryAdapterInfoCallAlwaysReturnsUnsuccessful; +}; + +uint32_t GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled; +bool GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCallAlwaysReturnsUnsuccessful; + +TEST(VerifyPciBusInfo, givenQueryAdapterInfoCallReturnsSuccesThenPciBusInfoIsValid) { + GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCallAlwaysReturnsUnsuccessful = false; + + auto osEnv = std::make_unique(); + osEnv->gdi = std::make_unique(); + + MockExecutionEnvironment executionEnvironment; + executionEnvironment.osEnvironment = std::move(osEnv); + + RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment); + + std::unique_ptr wddm(Wddm::createWddm(nullptr, rootDeviceEnvironment)); + + auto pciBusInfo = wddm->getPciBusInfo(); + + EXPECT_EQ(GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled, 1u); + + EXPECT_EQ(pciBusInfo.pciDomain, 0u); + EXPECT_EQ(pciBusInfo.pciBus, 1u); + EXPECT_EQ(pciBusInfo.pciDevice, 2u); + EXPECT_EQ(pciBusInfo.pciFunction, 3u); +} + +TEST(VerifyPciBusInfo, givenQueryAdapterInfoCallReturnsErrorThenPciBusInfoIsNotValid) { + GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCallAlwaysReturnsUnsuccessful = true; + + auto osEnv = std::make_unique(); + osEnv->gdi = std::make_unique(); + + MockExecutionEnvironment executionEnvironment; + executionEnvironment.osEnvironment = std::move(osEnv); + + RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment); + + std::unique_ptr wddm(Wddm::createWddm(nullptr, rootDeviceEnvironment)); + + auto pciBusInfo = wddm->getPciBusInfo(); + + EXPECT_EQ(GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled, 1u); + + EXPECT_EQ(pciBusInfo.pciDomain, PhysicalDevicePciBusInfo::InvalidValue); + EXPECT_EQ(pciBusInfo.pciBus, PhysicalDevicePciBusInfo::InvalidValue); + EXPECT_EQ(pciBusInfo.pciDevice, PhysicalDevicePciBusInfo::InvalidValue); + EXPECT_EQ(pciBusInfo.pciFunction, PhysicalDevicePciBusInfo::InvalidValue); +} diff --git a/shared/source/os_interface/driver_info.h b/shared/source/os_interface/driver_info.h index e387444fef..f33df3d88c 100644 --- a/shared/source/os_interface/driver_info.h +++ b/shared/source/os_interface/driver_info.h @@ -7,6 +7,8 @@ #pragma once +#include +#include #include namespace NEO { @@ -14,9 +16,24 @@ namespace NEO { struct HardwareInfo; class OSInterface; +struct PhysicalDevicePciBusInfo { + PhysicalDevicePciBusInfo(uint32_t domain, uint32_t bus, uint32_t device, uint32_t function) + : pciDomain(domain), pciBus(bus), pciDevice(device), pciFunction(function) {} + + uint32_t pciDomain; + uint32_t pciBus; + uint32_t pciDevice; + uint32_t pciFunction; + + static const uint32_t InvalidValue = std::numeric_limits::max(); +}; + class DriverInfo { public: - static DriverInfo *create(const HardwareInfo *hwInfo, OSInterface *osInterface); + DriverInfo() + : pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue) {} + + static DriverInfo *create(const HardwareInfo *hwInfo, const OSInterface *osInterface); virtual ~DriverInfo() = default; @@ -24,6 +41,10 @@ class DriverInfo { virtual std::string getVersion(std::string defaultVersion) { return defaultVersion; } virtual bool getMediaSharingSupport() { return true; } virtual bool getImageSupport() { return true; } + virtual PhysicalDevicePciBusInfo getPciBusInfo() { return pciBusInfo; } + + protected: + PhysicalDevicePciBusInfo pciBusInfo; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/driver_info_linux.cpp b/shared/source/os_interface/linux/driver_info_linux.cpp index e852b28e54..c39be15cf1 100644 --- a/shared/source/os_interface/linux/driver_info_linux.cpp +++ b/shared/source/os_interface/linux/driver_info_linux.cpp @@ -7,19 +7,35 @@ #include "shared/source/os_interface/linux/driver_info_linux.h" +#include "shared/source/helpers/debug_helpers.h" #include "shared/source/helpers/hw_info.h" +#include "shared/source/os_interface/linux/drm_neo.h" +#include "shared/source/os_interface/linux/os_interface.h" namespace NEO { -DriverInfo *DriverInfo::create(const HardwareInfo *hwInfo, OSInterface *osInterface) { +DriverInfo *DriverInfo::create(const HardwareInfo *hwInfo, const OSInterface *osInterface) { + PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); + if (osInterface) { + auto osInterfaceImpl = osInterface->get(); + UNRECOVERABLE_IF(osInterfaceImpl == nullptr); + + auto drm = osInterface->get()->getDrm(); + UNRECOVERABLE_IF(drm == nullptr); + + pciBusInfo = drm->getPciBusInfo(); + } if (hwInfo) { auto imageSupport = hwInfo->capabilityTable.supportsImages; - return new DriverInfoLinux(imageSupport); + return new DriverInfoLinux(imageSupport, pciBusInfo); } return nullptr; }; -DriverInfoLinux::DriverInfoLinux(bool imageSupport) : imageSupport(imageSupport) {} +DriverInfoLinux::DriverInfoLinux(bool imageSupport, const PhysicalDevicePciBusInfo &pciBusInfo) + : imageSupport(imageSupport) { + this->pciBusInfo = pciBusInfo; +} bool DriverInfoLinux::getImageSupport() { return imageSupport; } diff --git a/shared/source/os_interface/linux/driver_info_linux.h b/shared/source/os_interface/linux/driver_info_linux.h index 1ad3351c26..31d4a27b08 100644 --- a/shared/source/os_interface/linux/driver_info_linux.h +++ b/shared/source/os_interface/linux/driver_info_linux.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -13,7 +13,7 @@ namespace NEO { class DriverInfoLinux : public DriverInfo { public: - DriverInfoLinux(bool imageSupport); + DriverInfoLinux(bool imageSupport, const PhysicalDevicePciBusInfo &pciBusInfo); bool getImageSupport() override; protected: diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index f4ee5c1063..942620a468 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -15,6 +15,7 @@ #include "shared/source/helpers/hw_helper.h" #include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/ptr_math.h" +#include "shared/source/os_interface/driver_info.h" #include "shared/source/os_interface/linux/hw_device_id.h" #include "shared/source/os_interface/linux/os_inc.h" #include "shared/source/os_interface/linux/os_interface.h" @@ -693,6 +694,21 @@ bool Drm::translateTopologyInfo(const drm_i915_query_topology_info *queryTopolog return (data.sliceCount && data.subSliceCount && data.euCount); } +PhysicalDevicePciBusInfo Drm::getPciBusInfo() const { + PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); + + UNRECOVERABLE_IF(hwDeviceId == nullptr); + + const int pciBusInfoTokensNum = 3; + pciBusInfo.pciDomain = 0; + + if (std::sscanf(hwDeviceId->getPciPath(), "%02x:%02x.%01x", &(pciBusInfo.pciBus), &(pciBusInfo.pciDevice), &(pciBusInfo.pciFunction)) != pciBusInfoTokensNum) { + pciBusInfo.pciDomain = pciBusInfo.pciBus = pciBusInfo.pciDevice = pciBusInfo.pciFunction = PhysicalDevicePciBusInfo::InvalidValue; + } + + return pciBusInfo; +} + Drm::~Drm() { destroyVirtualMemoryAddressSpace(); this->printIoctlStatistics(); diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 134d1675b7..fb4df92ba6 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -8,6 +8,7 @@ #pragma once #include "shared/source/gmm_helper/gmm_lib.h" #include "shared/source/helpers/basic_math.h" +#include "shared/source/os_interface/driver_info.h" #include "shared/source/os_interface/linux/cache_info.h" #include "shared/source/os_interface/linux/engine_info.h" #include "shared/source/os_interface/linux/hw_device_id.h" @@ -128,6 +129,8 @@ class Drm { void setupSystemInfo(HardwareInfo *hwInfo, SystemInfo &sysInfo); void setupCacheInfo(const HardwareInfo &hwInfo); + PhysicalDevicePciBusInfo getPciBusInfo() const; + bool areNonPersistentContextsSupported() const { return nonPersistentContextsSupported; } void checkNonPersistentContextsSupport(); void setNonPersistentContext(uint32_t drmContextId); diff --git a/shared/source/os_interface/windows/driver_info_windows.cpp b/shared/source/os_interface/windows/driver_info_windows.cpp index f137e637c3..cc64c62d06 100644 --- a/shared/source/os_interface/windows/driver_info_windows.cpp +++ b/shared/source/os_interface/windows/driver_info_windows.cpp @@ -34,20 +34,24 @@ std::string getCurrentLibraryPath() { namespace NEO { -DriverInfo *DriverInfo::create(const HardwareInfo *hwInfo, OSInterface *osInterface) { - if (osInterface) { - auto wddm = osInterface->get()->getWddm(); - DEBUG_BREAK_IF(wddm == nullptr); - - std::string path(wddm->getDeviceRegistryPath()); - return new DriverInfoWindows(std::move(path)); +DriverInfo *DriverInfo::create(const HardwareInfo *hwInfo, const OSInterface *osInterface) { + if (osInterface == nullptr) { + return nullptr; } - return nullptr; + auto osInterfaceImpl = osInterface->get(); + UNRECOVERABLE_IF(osInterfaceImpl == nullptr); + + auto wddm = osInterfaceImpl->getWddm(); + UNRECOVERABLE_IF(wddm == nullptr); + + return new DriverInfoWindows(wddm->getDeviceRegistryPath(), wddm->getPciBusInfo()); }; -DriverInfoWindows::DriverInfoWindows(std::string &&fullPath) : path(DriverInfoWindows::trimRegistryKey(fullPath)), - registryReader(createRegistryReaderFunc(path)) {} +DriverInfoWindows::DriverInfoWindows(const std::string &fullPath, const PhysicalDevicePciBusInfo &pciBusInfo) + : path(DriverInfoWindows::trimRegistryKey(fullPath)), registryReader(createRegistryReaderFunc(path)) { + this->pciBusInfo = pciBusInfo; +} DriverInfoWindows::~DriverInfoWindows() = default; @@ -80,7 +84,7 @@ bool DriverInfoWindows::isCompatibleDriverStore() const { } bool isCompatibleDriverStore(std::string &&deviceRegistryPath) { - DriverInfoWindows driverInfo(std::move(deviceRegistryPath)); + DriverInfoWindows driverInfo(deviceRegistryPath, PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue)); return driverInfo.isCompatibleDriverStore(); } diff --git a/shared/source/os_interface/windows/driver_info_windows.h b/shared/source/os_interface/windows/driver_info_windows.h index f231c12e3f..af3061eb0f 100644 --- a/shared/source/os_interface/windows/driver_info_windows.h +++ b/shared/source/os_interface/windows/driver_info_windows.h @@ -19,7 +19,7 @@ class SettingsReader; class DriverInfoWindows : public DriverInfo { public: - DriverInfoWindows(std::string &&path); + DriverInfoWindows(const std::string &path, const PhysicalDevicePciBusInfo &pciBusInfo); ~DriverInfoWindows(); std::string getDeviceName(std::string defaultName) override; std::string getVersion(std::string defaultVersion) override; diff --git a/shared/source/os_interface/windows/wddm/wddm.cpp b/shared/source/os_interface/windows/wddm/wddm.cpp index 7d6642700f..2e211a0cf5 100644 --- a/shared/source/os_interface/windows/wddm/wddm.cpp +++ b/shared/source/os_interface/windows/wddm/wddm.cpp @@ -260,8 +260,7 @@ bool validDriverStorePath(OsEnvironmentWin &osEnvironment, D3DKMT_HANDLE adapter return nullptr; } - std::string deviceRegistryPath = adapterInfo.DeviceRegistryPath; - DriverInfoWindows driverInfo(std::move(deviceRegistryPath)); + DriverInfoWindows driverInfo(adapterInfo.DeviceRegistryPath, PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue)); return driverInfo.isCompatibleDriverStore(); } @@ -1169,4 +1168,24 @@ void Wddm::createPagingFenceLogger() { residencyLogger = std::make_unique(device, pagingFenceAddress); } } + +PhysicalDevicePciBusInfo Wddm::getPciBusInfo() const { + D3DKMT_ADAPTERADDRESS adapterAddress; + D3DKMT_QUERYADAPTERINFO queryAdapterInfo; + + queryAdapterInfo.hAdapter = getAdapter(); + queryAdapterInfo.Type = KMTQAITYPE_ADAPTERADDRESS; + queryAdapterInfo.pPrivateDriverData = &adapterAddress; + queryAdapterInfo.PrivateDriverDataSize = sizeof(adapterAddress); + + auto gdi = getGdi(); + UNRECOVERABLE_IF(gdi == nullptr); + + if (gdi->queryAdapterInfo(&queryAdapterInfo) == STATUS_SUCCESS) { + return PhysicalDevicePciBusInfo(0, adapterAddress.BusNumber, adapterAddress.DeviceNumber, adapterAddress.FunctionNumber); + } + + return PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); +} + } // namespace NEO diff --git a/shared/source/os_interface/windows/wddm/wddm.h b/shared/source/os_interface/windows/wddm/wddm.h index 5e01cd0175..967df1cb49 100644 --- a/shared/source/os_interface/windows/wddm/wddm.h +++ b/shared/source/os_interface/windows/wddm/wddm.h @@ -10,6 +10,7 @@ #include "shared/source/gmm_helper/gmm_lib.h" #include "shared/source/helpers/debug_helpers.h" #include "shared/source/memory_manager/gfx_partition.h" +#include "shared/source/os_interface/driver_info.h" #include "shared/source/os_interface/os_context.h" #include "shared/source/os_interface/windows/hw_device_id.h" #include "shared/source/os_interface/windows/wddm/wddm_defs.h" @@ -171,6 +172,8 @@ class Wddm { const uint32_t getTimestampFrequency() const { return timestampFrequency; } + PhysicalDevicePciBusInfo getPciBusInfo() const; + protected: std::unique_ptr hwDeviceId; D3DKMT_HANDLE device = 0; diff --git a/shared/test/common/mocks/mock_driver_info.h b/shared/test/common/mocks/mock_driver_info.h new file mode 100644 index 0000000000..21641710fe --- /dev/null +++ b/shared/test/common/mocks/mock_driver_info.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2018-2021 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/os_interface/driver_info.h" + +namespace NEO { + +class DriverInfoMock : public DriverInfo { + public: + DriverInfoMock(){}; + + std::string getDeviceName(std::string defaultName) override { return deviceName; }; + std::string getVersion(std::string defaultVersion) override { return version; }; + + void setDeviceName(const std::string &name) { deviceName = name; } + void setVersion(const std::string &versionString) { version = versionString; } + + void setPciBusInfo(const PhysicalDevicePciBusInfo &info) { + pciBusInfo.pciDomain = info.pciDomain; + pciBusInfo.pciBus = info.pciBus; + pciBusInfo.pciDevice = info.pciDevice; + pciBusInfo.pciFunction = info.pciFunction; + } + + private: + std::string deviceName; + std::string version; +}; + +} // namespace NEO