From 8deb4bcdba3086165d86531d68115fa2ba3a4cdb Mon Sep 17 00:00:00 2001 From: Jaroslaw Chodor Date: Thu, 22 Apr 2021 12:18:31 +0200 Subject: [PATCH] Adding helper for QUERYREGISTRY_DRIVERSTOREPATH Signed-off-by: Jaroslaw Chodor --- .../os_interface/windows/CMakeLists.txt | 4 +- .../windows/wddm/adapter_info.cpp | 49 +++++++++++++ .../os_interface/windows/wddm/adapter_info.h | 20 ++++++ .../os_interface/windows/CMakeLists.txt | 3 +- .../windows/adapter_info_tests.cpp | 69 +++++++++++++++++++ 5 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 shared/source/os_interface/windows/wddm/adapter_info.cpp create mode 100644 shared/source/os_interface/windows/wddm/adapter_info.h create mode 100644 shared/test/unit_test/os_interface/windows/adapter_info_tests.cpp diff --git a/shared/source/os_interface/windows/CMakeLists.txt b/shared/source/os_interface/windows/CMakeLists.txt index 9b808dccf4..96ff140b88 100644 --- a/shared/source/os_interface/windows/CMakeLists.txt +++ b/shared/source/os_interface/windows/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2019-2020 Intel Corporation +# Copyright (C) 2019-2021 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -49,6 +49,8 @@ set(NEO_CORE_OS_INTERFACE_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/print.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sys_calls.h ${CMAKE_CURRENT_SOURCE_DIR}/thk_wrapper.h + ${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_info.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_info.h ${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm.h ${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm_defs.h diff --git a/shared/source/os_interface/windows/wddm/adapter_info.cpp b/shared/source/os_interface/windows/wddm/adapter_info.cpp new file mode 100644 index 0000000000..bc2351f561 --- /dev/null +++ b/shared/source/os_interface/windows/wddm/adapter_info.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/os_interface/windows/wddm/adapter_info.h" + +#include "shared/source/helpers/debug_helpers.h" +#include "shared/source/os_interface/windows/gdi_interface.h" + +#include + +namespace NEO { +std::wstring queryAdapterDriverStorePath(const Gdi &gdi, D3DKMT_HANDLE adapter) { + D3DDDI_QUERYREGISTRY_INFO queryRegistryInfoSizeDesc = {}; + queryRegistryInfoSizeDesc.QueryType = D3DDDI_QUERYREGISTRY_DRIVERSTOREPATH; + queryRegistryInfoSizeDesc.ValueType = 0; + queryRegistryInfoSizeDesc.PhysicalAdapterIndex = 0; + + D3DKMT_QUERYADAPTERINFO queryAdapterInfoDesc = {0}; + queryAdapterInfoDesc.hAdapter = adapter; + queryAdapterInfoDesc.Type = KMTQAITYPE_QUERYREGISTRY; + queryAdapterInfoDesc.pPrivateDriverData = &queryRegistryInfoSizeDesc; + queryAdapterInfoDesc.PrivateDriverDataSize = static_cast(sizeof(queryRegistryInfoSizeDesc)); + + NTSTATUS status = gdi.queryAdapterInfo(&queryAdapterInfoDesc); + UNRECOVERABLE_IF(status != STATUS_SUCCESS); + DEBUG_BREAK_IF(queryRegistryInfoSizeDesc.Status != D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW); + + const auto privateDataSizeNeeded = queryRegistryInfoSizeDesc.OutputValueSize + sizeof(D3DDDI_QUERYREGISTRY_INFO); + std::unique_ptr storage{new uint64_t[(privateDataSizeNeeded + sizeof(uint64_t) - 1) / sizeof(uint64_t)]}; + D3DDDI_QUERYREGISTRY_INFO &queryRegistryInfoValueDesc = *reinterpret_cast(storage.get()); + queryRegistryInfoValueDesc = {}; + queryRegistryInfoValueDesc.QueryType = D3DDDI_QUERYREGISTRY_DRIVERSTOREPATH; + queryRegistryInfoValueDesc.ValueType = 0; + queryRegistryInfoValueDesc.PhysicalAdapterIndex = 0; + + queryAdapterInfoDesc.pPrivateDriverData = &queryRegistryInfoValueDesc; + queryAdapterInfoDesc.PrivateDriverDataSize = static_cast(privateDataSizeNeeded); + + status = gdi.queryAdapterInfo(&queryAdapterInfoDesc); + UNRECOVERABLE_IF(status != STATUS_SUCCESS); + UNRECOVERABLE_IF(queryRegistryInfoValueDesc.Status != D3DDDI_QUERYREGISTRY_STATUS_SUCCESS); + + return std::wstring(std::wstring(queryRegistryInfoValueDesc.OutputString, queryRegistryInfoValueDesc.OutputString + queryRegistryInfoValueDesc.OutputValueSize / sizeof(wchar_t)).c_str()); +} +} // namespace NEO diff --git a/shared/source/os_interface/windows/wddm/adapter_info.h b/shared/source/os_interface/windows/wddm/adapter_info.h new file mode 100644 index 0000000000..59e10cc369 --- /dev/null +++ b/shared/source/os_interface/windows/wddm/adapter_info.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2021 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include + +typedef unsigned int D3DKMT_HANDLE; + +namespace NEO { + +class Gdi; + +std::wstring queryAdapterDriverStorePath(const Gdi &gdi, D3DKMT_HANDLE adapter); + +} // namespace NEO diff --git a/shared/test/unit_test/os_interface/windows/CMakeLists.txt b/shared/test/unit_test/os_interface/windows/CMakeLists.txt index b4c6e76bfe..c0ccb97254 100644 --- a/shared/test/unit_test/os_interface/windows/CMakeLists.txt +++ b/shared/test/unit_test/os_interface/windows/CMakeLists.txt @@ -1,11 +1,12 @@ # -# Copyright (C) 2019-2020 Intel Corporation +# Copyright (C) 2019-2021 Intel Corporation # # SPDX-License-Identifier: MIT # set(NEO_CORE_OS_INTERFACE_TESTS_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/adapter_info_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gdi_interface_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gmm_helper_tests_win.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_gdi_interface.cpp diff --git a/shared/test/unit_test/os_interface/windows/adapter_info_tests.cpp b/shared/test/unit_test/os_interface/windows/adapter_info_tests.cpp new file mode 100644 index 0000000000..39c5847bb9 --- /dev/null +++ b/shared/test/unit_test/os_interface/windows/adapter_info_tests.cpp @@ -0,0 +1,69 @@ +/* + * 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/adapter_info.h" + +#include "test.h" + +TEST(AdapterInfoTest, whenQueryingForDriverStorePathThenProvidesEnoughMemoryForReturnString) { + static constexpr D3DKMT_HANDLE validHandle = 0x7; + static constexpr auto error = STATUS_SUCCESS + 1; + static const wchar_t *driverStorePathStr = L"some/path/fffff"; + struct QueryAdapterInfoMock { + static NTSTATUS(APIENTRY queryadapterinfo)( + const D3DKMT_QUERYADAPTERINFO *queryAdapterInfo) { + EXPECT_NE(nullptr, queryAdapterInfo); + if (nullptr == queryAdapterInfo) { + return error; + } + EXPECT_EQ(validHandle, queryAdapterInfo->hAdapter); + EXPECT_EQ(KMTQAITYPE_QUERYREGISTRY, queryAdapterInfo->Type); + if (KMTQAITYPE_QUERYREGISTRY != queryAdapterInfo->Type) { + return error; + } + + EXPECT_NE(nullptr, queryAdapterInfo->pPrivateDriverData); + EXPECT_LE(sizeof(D3DDDI_QUERYREGISTRY_INFO), queryAdapterInfo->PrivateDriverDataSize); + if ((nullptr == queryAdapterInfo->pPrivateDriverData) || (sizeof(D3DDDI_QUERYREGISTRY_INFO) > queryAdapterInfo->PrivateDriverDataSize)) { + return error; + } + + D3DDDI_QUERYREGISTRY_INFO *queryRegistryInfo = reinterpret_cast(queryAdapterInfo->pPrivateDriverData); + EXPECT_EQ(D3DDDI_QUERYREGISTRY_DRIVERSTOREPATH, queryRegistryInfo->QueryType); + EXPECT_EQ(0U, queryRegistryInfo->QueryFlags.Value); + bool regValueNameIsEmpty = std::wstring(std::wstring(queryRegistryInfo->ValueName[0], queryRegistryInfo->ValueName[0] + sizeof(queryRegistryInfo->ValueName)).c_str()).empty(); + EXPECT_TRUE(regValueNameIsEmpty); + EXPECT_EQ(0U, queryRegistryInfo->ValueType); + EXPECT_EQ(0U, queryRegistryInfo->PhysicalAdapterIndex); + + if (D3DDDI_QUERYREGISTRY_DRIVERSTOREPATH != queryRegistryInfo->QueryType) { + return error; + } + + queryRegistryInfo->OutputValueSize = static_cast(std::wstring(driverStorePathStr).size() * sizeof(wchar_t)); + if (queryAdapterInfo->PrivateDriverDataSize < queryRegistryInfo->OutputValueSize + sizeof(D3DDDI_QUERYREGISTRY_INFO)) { + EXPECT_EQ(sizeof(D3DDDI_QUERYREGISTRY_INFO), queryAdapterInfo->PrivateDriverDataSize); + queryRegistryInfo->Status = D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW; + return STATUS_SUCCESS; + } + + memcpy_s(queryRegistryInfo->OutputString, queryAdapterInfo->PrivateDriverDataSize - sizeof(D3DDDI_QUERYREGISTRY_INFO), + driverStorePathStr, queryRegistryInfo->OutputValueSize); + + queryRegistryInfo->Status = D3DDDI_QUERYREGISTRY_STATUS_SUCCESS; + return STATUS_SUCCESS; + } + }; + NEO::Gdi gdi; + auto handle = validHandle; + gdi.queryAdapterInfo.mFunc = QueryAdapterInfoMock::queryadapterinfo; + + auto ret = NEO::queryAdapterDriverStorePath(gdi, handle); + + EXPECT_EQ(std::wstring(driverStorePathStr), ret) << "Expected " << driverStorePathStr << ", got : " << ret; +}