diff --git a/runtime/dll/linux/options.cpp b/runtime/dll/linux/options.cpp index d2c346888a..7d57c3ef54 100644 --- a/runtime/dll/linux/options.cpp +++ b/runtime/dll/linux/options.cpp @@ -16,7 +16,8 @@ const char *frontEndDllName = FCL_LIBRARY_NAME; const char *igcDllName = IGC_LIBRARY_NAME; const char *libvaDllName = "libva.so.2"; const char *gmmDllName = GMM_UMD_DLL; -const char *gmmEntryName = GMM_ENTRY_NAME; +const char *gmmInitFuncName = GMM_INIT_NAME; +const char *gmmDestroyFuncName = GMM_DESTROY_NAME; const char *sysFsPciPath = "/sys/bus/pci/devices/"; const char *tbxLibName = "libtbxAccess.so"; diff --git a/runtime/dll/windows/options.cpp b/runtime/dll/windows/options.cpp index d93bbe2d9e..5f3ace92fc 100644 --- a/runtime/dll/windows/options.cpp +++ b/runtime/dll/windows/options.cpp @@ -14,7 +14,8 @@ const char *frontEndDllName = FCL_LIBRARY_NAME; const char *igcDllName = IGC_LIBRARY_NAME; const char *gdiDllName = "gdi32.dll"; const char *gmmDllName = GMM_UMD_DLL; -const char *gmmEntryName = GMM_ENTRY_NAME; +const char *gmmInitFuncName = GMM_INIT_NAME; +const char *gmmDestroyFuncName = GMM_DESTROY_NAME; // Os specific Metrics Library name #if _WIN64 diff --git a/runtime/gmm_helper/client_context/gmm_client_context.cpp b/runtime/gmm_helper/client_context/gmm_client_context.cpp index 9378b835fe..532d2440b1 100644 --- a/runtime/gmm_helper/client_context/gmm_client_context.cpp +++ b/runtime/gmm_helper/client_context/gmm_client_context.cpp @@ -8,5 +8,5 @@ #include "gmm_client_context.h" namespace NEO { -GmmClientContext::GmmClientContext(GMM_CLIENT clientType, GmmExportEntries &gmmEntries) : GmmClientContextBase(clientType, gmmEntries){}; +GmmClientContext::GmmClientContext(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc) : GmmClientContextBase(hwInfo, initFunc, destroyFunc){}; } // namespace NEO diff --git a/runtime/gmm_helper/client_context/gmm_client_context.h b/runtime/gmm_helper/client_context/gmm_client_context.h index 328dffa50c..3a1041d226 100644 --- a/runtime/gmm_helper/client_context/gmm_client_context.h +++ b/runtime/gmm_helper/client_context/gmm_client_context.h @@ -11,6 +11,6 @@ namespace NEO { class GmmClientContext : public GmmClientContextBase { public: - GmmClientContext(GMM_CLIENT clientType, GmmExportEntries &gmmEntries); + GmmClientContext(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc); }; } // namespace NEO diff --git a/runtime/gmm_helper/client_context/gmm_client_context_base.cpp b/runtime/gmm_helper/client_context/gmm_client_context_base.cpp index bc7a8f995b..d839499be6 100644 --- a/runtime/gmm_helper/client_context/gmm_client_context_base.cpp +++ b/runtime/gmm_helper/client_context/gmm_client_context_base.cpp @@ -7,12 +7,45 @@ #include "runtime/gmm_helper/client_context/gmm_client_context_base.h" +#include "core/helpers/debug_helpers.h" +#include "runtime/execution_environment/execution_environment.h" +#include "runtime/helpers/hw_info.h" +#include "runtime/os_interface/os_interface.h" +#include "runtime/platform/platform.h" +#include "runtime/sku_info/operations/sku_info_transfer.h" + namespace NEO { -GmmClientContextBase::GmmClientContextBase(GMM_CLIENT clientType, GmmExportEntries &gmmEntries) : gmmEntries(gmmEntries) { - clientContext = gmmEntries.pfnCreateClientContext(clientType); +GmmClientContextBase::GmmClientContextBase(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc) : destroyFunc(destroyFunc) { + _SKU_FEATURE_TABLE gmmFtrTable = {}; + _WA_TABLE gmmWaTable = {}; + SkuInfoTransfer::transferFtrTableForGmm(&gmmFtrTable, &hwInfo->featureTable); + SkuInfoTransfer::transferWaTableForGmm(&gmmWaTable, &hwInfo->workaroundTable); + + GMM_INIT_IN_ARGS inArgs; + GMM_INIT_OUT_ARGS outArgs; + + inArgs.ClientType = GMM_CLIENT::GMM_OCL_VISTA; + inArgs.pGtSysInfo = &hwInfo->gtSystemInfo; + inArgs.pSkuTable = &gmmFtrTable; + inArgs.pWaTable = &gmmWaTable; + inArgs.Platform = hwInfo->platform; + + auto osInterface = platform()->peekExecutionEnvironment()->osInterface.get(); + if (osInterface) { + osInterface->setGmmInputArgs(&inArgs); + } + + auto ret = initFunc(&inArgs, &outArgs); + + UNRECOVERABLE_IF(ret != GMM_SUCCESS); + + clientContext = outArgs.pGmmClientContext; } GmmClientContextBase::~GmmClientContextBase() { - gmmEntries.pfnDeleteClientContext(clientContext); + GMM_INIT_OUT_ARGS outArgs; + outArgs.pGmmClientContext = clientContext; + + destroyFunc(&outArgs); }; MEMORY_OBJECT_CONTROL_STATE GmmClientContextBase::cachePolicyGetMemoryObject(GMM_RESOURCE_INFO *pResInfo, GMM_RESOURCE_USAGE_TYPE usage) { diff --git a/runtime/gmm_helper/client_context/gmm_client_context_base.h b/runtime/gmm_helper/client_context/gmm_client_context_base.h index 80abbff17d..962dea2eed 100644 --- a/runtime/gmm_helper/client_context/gmm_client_context_base.h +++ b/runtime/gmm_helper/client_context/gmm_client_context_base.h @@ -12,6 +12,8 @@ namespace NEO { class GmmClientContext; +struct HardwareInfo; + class GmmClientContextBase { public: virtual ~GmmClientContextBase(); @@ -22,8 +24,8 @@ class GmmClientContextBase { MOCKABLE_VIRTUAL void destroyResInfoObject(GMM_RESOURCE_INFO *pResInfo); GMM_CLIENT_CONTEXT *getHandle() const; template - static std::unique_ptr create(GMM_CLIENT clientType, GmmExportEntries &gmmEntries) { - return std::make_unique(clientType, gmmEntries); + static std::unique_ptr create(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc) { + return std::make_unique(hwInfo, initFunc, destroyFunc); } MOCKABLE_VIRTUAL uint8_t getSurfaceStateCompressionFormat(GMM_RESOURCE_FORMAT format); @@ -31,7 +33,7 @@ class GmmClientContextBase { protected: GMM_CLIENT_CONTEXT *clientContext; - GmmClientContextBase(GMM_CLIENT clientType, GmmExportEntries &gmmEntries); - GmmExportEntries &gmmEntries; + GmmClientContextBase(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc); + decltype(&GmmDestroy) destroyFunc; }; } // namespace NEO diff --git a/runtime/gmm_helper/gmm_helper.cpp b/runtime/gmm_helper/gmm_helper.cpp index fa607217fd..c7265b0384 100644 --- a/runtime/gmm_helper/gmm_helper.cpp +++ b/runtime/gmm_helper/gmm_helper.cpp @@ -33,21 +33,6 @@ GmmHelper *GmmHelper::getInstance() { return platform()->peekExecutionEnvironment()->getGmmHelper(); } -void GmmHelper::initContext(const PLATFORM *platform, - const FeatureTable *featureTable, - const WorkaroundTable *workaroundTable, - const GT_SYSTEM_INFO *pGtSysInfo) { - _SKU_FEATURE_TABLE gmmFtrTable = {}; - _WA_TABLE gmmWaTable = {}; - SkuInfoTransfer::transferFtrTableForGmm(&gmmFtrTable, featureTable); - SkuInfoTransfer::transferWaTableForGmm(&gmmWaTable, workaroundTable); - loadLib(); - bool success = GMM_SUCCESS == gmmEntries.pfnCreateSingletonContext(*platform, &gmmFtrTable, &gmmWaTable, pGtSysInfo); - UNRECOVERABLE_IF(!success); - gmmClientContext = GmmHelper::createGmmContextWrapperFunc(GMM_CLIENT::GMM_OCL_VISTA, gmmEntries); - UNRECOVERABLE_IF(!gmmClientContext); -} - uint32_t GmmHelper::getMOCS(uint32_t type) { MEMORY_OBJECT_CONTROL_STATE mocs = gmmClientContext->cachePolicyGetMemoryObject(nullptr, static_cast(type)); @@ -91,10 +76,12 @@ GMM_YUV_PLANE GmmHelper::convertPlane(OCLPlane oclPlane) { return GMM_NO_PLANE; } GmmHelper::GmmHelper(const HardwareInfo *pHwInfo) : hwInfo(pHwInfo) { - initContext(&pHwInfo->platform, &pHwInfo->featureTable, &pHwInfo->workaroundTable, &pHwInfo->gtSystemInfo); + loadLib(); + gmmClientContext = GmmHelper::createGmmContextWrapperFunc(const_cast(pHwInfo), this->initGmmFunc, this->destroyGmmFunc); + UNRECOVERABLE_IF(!gmmClientContext); } -GmmHelper::~GmmHelper() { - gmmEntries.pfnDestroySingletonContext(); -}; + +GmmHelper::~GmmHelper() = default; + decltype(GmmHelper::createGmmContextWrapperFunc) GmmHelper::createGmmContextWrapperFunc = GmmClientContextBase::create; } // namespace NEO diff --git a/runtime/gmm_helper/gmm_helper.h b/runtime/gmm_helper/gmm_helper.h index c62ca93d6e..4bc1bf88ec 100644 --- a/runtime/gmm_helper/gmm_helper.h +++ b/runtime/gmm_helper/gmm_helper.h @@ -17,8 +17,6 @@ class GmmClientContext; class GraphicsAllocation; class OsLibrary; struct HardwareInfo; -struct FeatureTable; -struct WorkaroundTable; struct ImageInfo; class GmmHelper { @@ -50,15 +48,15 @@ class GmmHelper { static uint32_t getRenderMultisamplesCount(uint32_t numSamples); static GMM_YUV_PLANE convertPlane(OCLPlane oclPlane); - static std::unique_ptr (*createGmmContextWrapperFunc)(GMM_CLIENT, GmmExportEntries &); + static std::unique_ptr (*createGmmContextWrapperFunc)(HardwareInfo *, decltype(&InitializeGmm), decltype(&GmmDestroy)); protected: void loadLib(); - void initContext(const PLATFORM *platform, const FeatureTable *featureTable, const WorkaroundTable *workaroundTable, const GT_SYSTEM_INFO *pGtSysInfo); const HardwareInfo *hwInfo = nullptr; std::unique_ptr gmmLib; std::unique_ptr gmmClientContext; - GmmExportEntries gmmEntries = {}; + decltype(&InitializeGmm) initGmmFunc; + decltype(&GmmDestroy) destroyGmmFunc; }; } // namespace NEO diff --git a/runtime/gmm_helper/gmm_interface.cpp b/runtime/gmm_helper/gmm_interface.cpp index 7a2e690341..1d32451624 100644 --- a/runtime/gmm_helper/gmm_interface.cpp +++ b/runtime/gmm_helper/gmm_interface.cpp @@ -11,23 +11,17 @@ namespace Os { extern const char *gmmDllName; -extern const char *gmmEntryName; +extern const char *gmmInitFuncName; +extern const char *gmmDestroyFuncName; } // namespace Os namespace NEO { void GmmHelper::loadLib() { gmmLib.reset(OsLibrary::load(Os::gmmDllName)); - bool isLoaded = false; UNRECOVERABLE_IF(!gmmLib); - auto openGmmFunc = reinterpret_cast(gmmLib->getProcAddress(Os::gmmEntryName)); - auto status = openGmmFunc(&gmmEntries); - if (status == GMM_SUCCESS) { - isLoaded = gmmEntries.pfnCreateClientContext && - gmmEntries.pfnCreateSingletonContext && - gmmEntries.pfnDeleteClientContext && - gmmEntries.pfnDestroySingletonContext; - } - UNRECOVERABLE_IF(!isLoaded); + initGmmFunc = reinterpret_cast(gmmLib->getProcAddress(Os::gmmInitFuncName)); + destroyGmmFunc = reinterpret_cast(gmmLib->getProcAddress(Os::gmmDestroyFuncName)); + UNRECOVERABLE_IF(!initGmmFunc || !destroyGmmFunc); } } // namespace NEO diff --git a/runtime/os_interface/linux/os_interface.cpp b/runtime/os_interface/linux/os_interface.cpp index 0dcbae9caa..4cacbd35e8 100644 --- a/runtime/os_interface/linux/os_interface.cpp +++ b/runtime/os_interface/linux/os_interface.cpp @@ -27,4 +27,6 @@ uint32_t OSInterface::getDeviceHandle() const { return 0; } +void OSInterface::setGmmInputArgs(void *args) {} + } // namespace NEO diff --git a/runtime/os_interface/os_interface.h b/runtime/os_interface/os_interface.h index 2f0bb08a13..d7d926aa7a 100644 --- a/runtime/os_interface/os_interface.h +++ b/runtime/os_interface/os_interface.h @@ -25,6 +25,7 @@ class OSInterface { static bool osEnableLocalMemory; static bool are64kbPagesEnabled(); unsigned int getDeviceHandle() const; + void setGmmInputArgs(void *args); protected: OSInterfaceImpl *osInterfaceImpl = nullptr; diff --git a/runtime/os_interface/windows/os_interface.cpp b/runtime/os_interface/windows/os_interface.cpp index 21ebe51117..1585b76387 100644 --- a/runtime/os_interface/windows/os_interface.cpp +++ b/runtime/os_interface/windows/os_interface.cpp @@ -27,6 +27,10 @@ uint32_t OSInterface::getDeviceHandle() const { return static_cast(osInterfaceImpl->getDeviceHandle()); } +void OSInterface::setGmmInputArgs(void *args) { + this->get()->getWddm()->setGmmInputArg(args); +} + OSInterface::OSInterfaceImpl::OSInterfaceImpl() = default; D3DKMT_HANDLE OSInterface::OSInterfaceImpl::getAdapterHandle() const { diff --git a/runtime/os_interface/windows/wddm/wddm.cpp b/runtime/os_interface/windows/wddm/wddm.cpp index 820fa7b73c..fe5dd2e71a 100644 --- a/runtime/os_interface/windows/wddm/wddm.cpp +++ b/runtime/os_interface/windows/wddm/wddm.cpp @@ -161,6 +161,7 @@ bool Wddm::queryAdapterInfo() { SkuInfoReceiver::receiveWaTableFromAdapterInfo(workaroundTable.get(), &adapterInfo); memcpy_s(&gfxPartition, sizeof(gfxPartition), &adapterInfo.GfxPartition, sizeof(GMM_GFX_PARTITIONING)); + memcpy_s(&adapterBDF, sizeof(adapterBDF), &adapterInfo.stAdapterBDF, sizeof(ADAPTER_BDF)); deviceRegistryPath = adapterInfo.DeviceRegistryPath; @@ -972,6 +973,10 @@ void Wddm::waitOnPagingFenceFromCpu() { ; } +void Wddm::setGmmInputArg(void *args) { + reinterpret_cast(args)->stAdapterBDF = this->adapterBDF; +} + void Wddm::updatePagingFenceValue(uint64_t newPagingFenceValue) { interlockedMax(currentPagingFenceValue, newPagingFenceValue); } diff --git a/runtime/os_interface/windows/wddm/wddm.h b/runtime/os_interface/windows/wddm/wddm.h index b9ea8436d2..04593a9b46 100644 --- a/runtime/os_interface/windows/wddm/wddm.h +++ b/runtime/os_interface/windows/wddm/wddm.h @@ -144,6 +144,8 @@ class Wddm { } void waitOnPagingFenceFromCpu(); + void setGmmInputArg(void *args); + protected: std::unique_ptr gdi; D3DKMT_HANDLE adapter = 0; @@ -160,6 +162,7 @@ class Wddm { std::unique_ptr featureTable; std::unique_ptr workaroundTable; GMM_GFX_PARTITIONING gfxPartition; + ADAPTER_BDF adapterBDF; uint64_t systemSharedMemory = 0; uint64_t dedicatedVideoMemory = 0; uint32_t maxRenderFrequency = 0; diff --git a/unit_tests/gmm_helper/gmm_interface_tests.cpp b/unit_tests/gmm_helper/gmm_interface_tests.cpp index 880c72e1a3..0e2dd6ecf0 100644 --- a/unit_tests/gmm_helper/gmm_interface_tests.cpp +++ b/unit_tests/gmm_helper/gmm_interface_tests.cpp @@ -5,69 +5,57 @@ * */ +#include "runtime/execution_environment/execution_environment.h" #include "runtime/gmm_helper/gmm_helper.h" +#include "runtime/helpers/hw_info.h" +#include "runtime/os_interface/os_interface.h" +#include "runtime/platform/platform.h" +#include "runtime/sku_info/operations/sku_info_transfer.h" #include "unit_tests/helpers/variable_backup.h" #include "gtest/gtest.h" #include -GMM_CLIENT_CONTEXT *GMM_STDCALL createClientContext(GMM_CLIENT clientType) { - return reinterpret_cast(0x1); -} -void GMM_STDCALL deleteClientContext(GMM_CLIENT_CONTEXT *pGmmClientContext) { -} -void GMM_STDCALL destroySingletonContext(void) { -} #ifdef _WIN32 #ifdef _WIN64 -const char *mockGmmEntryName = "openMockGmm"; +const char *mockGmmInitFuncName = "initMockGmm"; +const char *mockGmmDestroyFuncName = "destroyMockGmm"; #else -const char *mockGmmEntryName = "_openMockGmm@4"; +const char *mockGmmInitFuncName = "_initMockGmm@8"; +const char *mockGmmDestroyFuncName = "_destroyMockGmm@4"; #endif #define EXPORT_KEYWORD __declspec(dllexport) -GMM_STATUS GMM_STDCALL createSingletonContext(const PLATFORM platform, - const SKU_FEATURE_TABLE *featureTable, - const WA_TABLE *workaroundTable, - const GT_SYSTEM_INFO *pGtSysInfo) { - return GMM_SUCCESS; -} #else -const char *mockGmmEntryName = "openMockGmm"; +const char *mockGmmInitFuncName = "initMockGmm"; +const char *mockGmmDestroyFuncName = "destroyMockGmm"; #define EXPORT_KEYWORD -GMM_STATUS GMM_STDCALL createSingletonContext(const PLATFORM platform, - const void *featureTable, - const void *workaroundTable, - const void *pGtSysInfo) { - return GMM_SUCCESS; -} #endif -bool setCreateContextFunction = true; -bool setCreateContextSingletonFunction = true; -bool setDeleteContextFunction = true; -bool setDestroyContextSingletonFunction = true; GMM_STATUS openGmmReturnValue = GMM_SUCCESS; - -extern "C" EXPORT_KEYWORD GMM_STATUS GMM_STDCALL openMockGmm(GmmExportEntries *pGmmFuncs) { - if (setCreateContextFunction) { - pGmmFuncs->pfnCreateClientContext = &createClientContext; - } - if (setCreateContextSingletonFunction) { - pGmmFuncs->pfnCreateSingletonContext = &createSingletonContext; - } - if (setDeleteContextFunction) { - pGmmFuncs->pfnDeleteClientContext = &deleteClientContext; - } - if (setDestroyContextSingletonFunction) { - pGmmFuncs->pfnDestroySingletonContext = &destroySingletonContext; +GMM_INIT_IN_ARGS passedInputArgs = {}; +SKU_FEATURE_TABLE passedFtrTable = {}; +WA_TABLE passedWaTable = {}; +bool copyInputArgs = false; +extern "C" { +EXPORT_KEYWORD GMM_STATUS GMM_STDCALL initMockGmm(GMM_INIT_IN_ARGS *pInArgs, GMM_INIT_OUT_ARGS *pOutArgs) { + if (copyInputArgs && pInArgs) { + passedInputArgs = *pInArgs; + passedFtrTable = *reinterpret_cast(pInArgs->pSkuTable); + passedWaTable = *reinterpret_cast(pInArgs->pWaTable); } + pOutArgs->pGmmClientContext = reinterpret_cast(0x01); return openGmmReturnValue; } +EXPORT_KEYWORD void GMM_STDCALL destroyMockGmm(GMM_INIT_OUT_ARGS *pInArgs) { +} +} + namespace Os { extern const char *gmmDllName; -extern const char *gmmEntryName; +extern const char *gmmInitFuncName; +extern const char *gmmDestroyFuncName; } // namespace Os namespace NEO { extern const HardwareInfo **platformDevices; @@ -77,28 +65,82 @@ struct GmmInterfaceTest : public ::testing::Test { const char *empty = ""; VariableBackup gmmDllNameBackup = {&Os::gmmDllName, empty}; - VariableBackup gmmEntryNameBackup = {&Os::gmmEntryName, mockGmmEntryName}; + VariableBackup gmmInitNameBackup = {&Os::gmmInitFuncName, mockGmmInitFuncName}; + VariableBackup gmmDestroyNameBackup = {&Os::gmmDestroyFuncName, mockGmmDestroyFuncName}; }; TEST_F(GmmInterfaceTest, givenValidGmmLibWhenCreateGmmHelperThenEverythingWorksFine) { std::unique_ptr gmmHelper; EXPECT_NO_THROW(gmmHelper.reset(new GmmHelper(*platformDevices))); } + TEST_F(GmmInterfaceTest, givenInvalidGmmLibNameWhenCreateGmmHelperThenThrowException) { std::unique_ptr gmmHelper; gmmDllNameBackup = "invalidName"; EXPECT_THROW(gmmHelper.reset(new GmmHelper(*platformDevices)), std::exception); } + TEST_F(GmmInterfaceTest, givenGmmLibWhenOpenGmmFunctionFailsThenThrowException) { std::unique_ptr gmmHelper; VariableBackup openGmmReturnValueBackup(&openGmmReturnValue, GMM_ERROR); EXPECT_THROW(gmmHelper.reset(new GmmHelper(*platformDevices)), std::exception); } -TEST_F(GmmInterfaceTest, givenGmmLibWhenAnyFunctionIsNotLoadedThenThrowExceptionDuringGmmHelperCreation) { + +TEST_F(GmmInterfaceTest, givenInvalidGmmInitFunctionNameWhenCreateGmmHelperThenThrowException) { std::unique_ptr gmmHelper; - std::array flags = {{&setCreateContextFunction, &setCreateContextSingletonFunction, &setDeleteContextFunction, &setDestroyContextSingletonFunction}}; - for (auto &flag : flags) { - VariableBackup flagBackup(flag, false); - EXPECT_THROW(gmmHelper.reset(new GmmHelper(*platformDevices)), std::exception); - } + gmmInitNameBackup = "invalidName"; + EXPECT_THROW(gmmHelper.reset(new GmmHelper(*platformDevices)), std::exception); } + +TEST_F(GmmInterfaceTest, givenInvalidGmmDestroyFunctionNameWhenCreateGmmHelperThenThrowException) { + std::unique_ptr gmmHelper; + gmmDestroyNameBackup = "invalidName"; + EXPECT_THROW(gmmHelper.reset(new GmmHelper(*platformDevices)), std::exception); +} + +TEST_F(GmmInterfaceTest, givenValidGmmFunctionsWhenCreateGmmHelperWithInitializedOsInterfaceThenProperParametersArePassed) { + std::unique_ptr gmmHelper; + auto executionEnvironment = platform()->peekExecutionEnvironment(); + size_t numDevices; + DeviceFactory::getDevices(numDevices, *executionEnvironment); + VariableBackup passedInputArgsBackup(&passedInputArgs); + VariableBackup passedFtrTableBackup(&passedFtrTable); + VariableBackup passedWaTableBackup(&passedWaTable); + VariableBackup copyInputArgsBackup(©InputArgs, true); + + auto hwInfo = platformDevices[0]; + SKU_FEATURE_TABLE expectedFtrTable = {}; + WA_TABLE expectedWaTable = {}; + SkuInfoTransfer::transferFtrTableForGmm(&expectedFtrTable, &hwInfo->featureTable); + SkuInfoTransfer::transferWaTableForGmm(&expectedWaTable, &hwInfo->workaroundTable); + + gmmHelper.reset(new GmmHelper(hwInfo)); + EXPECT_EQ(0, memcmp(&hwInfo->platform, &passedInputArgs.Platform, sizeof(PLATFORM))); + EXPECT_EQ(&hwInfo->gtSystemInfo, passedInputArgs.pGtSysInfo); + EXPECT_EQ(0, memcmp(&expectedFtrTable, &passedFtrTable, sizeof(SKU_FEATURE_TABLE))); + EXPECT_EQ(0, memcmp(&expectedWaTable, &passedWaTable, sizeof(WA_TABLE))); + EXPECT_EQ(GMM_CLIENT::GMM_OCL_VISTA, passedInputArgs.ClientType); +} + +TEST_F(GmmInterfaceTest, givenValidGmmFunctionsWhenCreateGmmHelperWithoutOsInterfaceThenInitializationDoesntCrashAndProperParametersArePassed) { + std::unique_ptr gmmHelper; + auto executionEnvironment = platform()->peekExecutionEnvironment(); + executionEnvironment->osInterface.reset(); + VariableBackup passedInputArgsBackup(&passedInputArgs); + VariableBackup passedFtrTableBackup(&passedFtrTable); + VariableBackup passedWaTableBackup(&passedWaTable); + VariableBackup copyInputArgsBackup(©InputArgs, true); + + auto hwInfo = platformDevices[0]; + SKU_FEATURE_TABLE expectedFtrTable = {}; + WA_TABLE expectedWaTable = {}; + SkuInfoTransfer::transferFtrTableForGmm(&expectedFtrTable, &hwInfo->featureTable); + SkuInfoTransfer::transferWaTableForGmm(&expectedWaTable, &hwInfo->workaroundTable); + + gmmHelper.reset(new GmmHelper(hwInfo)); + EXPECT_EQ(0, memcmp(&hwInfo->platform, &passedInputArgs.Platform, sizeof(PLATFORM))); + EXPECT_EQ(&hwInfo->gtSystemInfo, passedInputArgs.pGtSysInfo); + EXPECT_EQ(0, memcmp(&expectedFtrTable, &passedFtrTable, sizeof(SKU_FEATURE_TABLE))); + EXPECT_EQ(0, memcmp(&expectedWaTable, &passedWaTable, sizeof(WA_TABLE))); + EXPECT_EQ(GMM_CLIENT::GMM_OCL_VISTA, passedInputArgs.ClientType); +} \ No newline at end of file diff --git a/unit_tests/main.cpp b/unit_tests/main.cpp index 9928532f42..15bc362ebb 100644 --- a/unit_tests/main.cpp +++ b/unit_tests/main.cpp @@ -52,7 +52,8 @@ std::thread::id tempThreadID; } // namespace NEO namespace Os { extern const char *gmmDllName; -extern const char *gmmEntryName; +extern const char *gmmInitFuncName; +extern const char *gmmDestroyFuncName; } // namespace Os using namespace NEO; @@ -446,7 +447,8 @@ int main(int argc, char **argv) { #endif if (!useMockGmm) { Os::gmmDllName = GMM_UMD_DLL; - Os::gmmEntryName = GMM_ENTRY_NAME; + Os::gmmInitFuncName = GMM_INIT_NAME; + Os::gmmDestroyFuncName = GMM_DESTROY_NAME; } else { GmmHelper::createGmmContextWrapperFunc = GmmClientContextBase::create; } diff --git a/unit_tests/mock_gmm/mock_gmm.cpp b/unit_tests/mock_gmm/mock_gmm.cpp index 9c9b2b4f97..d061a41d1a 100644 --- a/unit_tests/mock_gmm/mock_gmm.cpp +++ b/unit_tests/mock_gmm/mock_gmm.cpp @@ -7,43 +7,18 @@ #include "GmmLib.h" -GMM_CLIENT_CONTEXT *GMM_STDCALL createClientContext(GMM_CLIENT clientType) { - return reinterpret_cast(0x1); -} -void GMM_STDCALL deleteClientContext(GMM_CLIENT_CONTEXT *pGmmClientContext) { -} -void GMM_STDCALL destroySingletonContext(void) { -} -#ifdef _WIN32 -GMM_STATUS GMM_STDCALL createSingletonContext(const PLATFORM Platform, - const SKU_FEATURE_TABLE *featureTable, - const WA_TABLE *workaroundTable, - const GT_SYSTEM_INFO *pGtSysInfo) { - if (Platform.eProductFamily == PRODUCT_FAMILY::IGFX_UNKNOWN && - Platform.eRenderCoreFamily == GFXCORE_FAMILY::IGFX_UNKNOWN_CORE && - Platform.ePCHProductFamily == PCH_PRODUCT_FAMILY::PCH_UNKNOWN) { - return GMM_ERROR; - } - return GMM_SUCCESS; -} -#else -GMM_STATUS GMM_STDCALL createSingletonContext(const PLATFORM platform, - const void *featureTable, - const void *workaroundTable, - const void *pGtSysInfo) { - return GMM_SUCCESS; -} -#endif #ifdef __cplusplus extern "C" { #endif -GMM_STATUS GMM_STDCALL openMockGmm(GmmExportEntries *pGmmFuncs) { - pGmmFuncs->pfnCreateClientContext = &createClientContext; - pGmmFuncs->pfnCreateSingletonContext = &createSingletonContext; - pGmmFuncs->pfnDeleteClientContext = &deleteClientContext; - pGmmFuncs->pfnDestroySingletonContext = &destroySingletonContext; + +GMM_STATUS GMM_STDCALL initMockGmm(GMM_INIT_IN_ARGS *pInArgs, GMM_INIT_OUT_ARGS *pOutArgs) { + pOutArgs->pGmmClientContext = reinterpret_cast(0x01); return GMM_SUCCESS; } + +void GMM_STDCALL destroyMockGmm(GMM_INIT_OUT_ARGS *pInArgs) { +} + #ifdef __cplusplus } #endif diff --git a/unit_tests/mock_gmm/mock_gmm.def b/unit_tests/mock_gmm/mock_gmm.def index 1f2e5be768..6c02920ca3 100644 --- a/unit_tests/mock_gmm/mock_gmm.def +++ b/unit_tests/mock_gmm/mock_gmm.def @@ -1,23 +1,10 @@ -; Copyright (c) 2018, Intel Corporation ; -; Permission is hereby granted, free of charge, to any person obtaining a -; copy of this software and associated documentation files (the "Software"), -; to deal in the Software without restriction, including without limitation -; the rights to use, copy, modify, merge, publish, distribute, sublicense, -; and/or sell copies of the Software, and to permit persons to whom the -; Software is furnished to do so, subject to the following conditions: +; Copyright (C) 2018-2019 Intel Corporation ; -; The above copyright notice and this permission notice shall be included -; in all copies or substantial portions of the Software. +; SPDX-License-Identifier: MIT ; -; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -; OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -; OTHER DEALINGS IN THE SOFTWARE. LIBRARY "mock_gmm" EXPORTS -openMockGmm \ No newline at end of file +initMockGmm +destroyMockGmm \ No newline at end of file diff --git a/unit_tests/mocks/mock_gmm_client_context.cpp b/unit_tests/mocks/mock_gmm_client_context.cpp index 7bca6d0582..1babca9a7a 100644 --- a/unit_tests/mocks/mock_gmm_client_context.cpp +++ b/unit_tests/mocks/mock_gmm_client_context.cpp @@ -8,6 +8,6 @@ #include "mock_gmm_client_context.h" namespace NEO { -MockGmmClientContext::MockGmmClientContext(GMM_CLIENT clientType, GmmExportEntries &gmmExportEntries) : MockGmmClientContextBase(clientType, gmmExportEntries) { +MockGmmClientContext::MockGmmClientContext(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc) : MockGmmClientContextBase(hwInfo, initFunc, destroyFunc) { } } // namespace NEO diff --git a/unit_tests/mocks/mock_gmm_client_context.h b/unit_tests/mocks/mock_gmm_client_context.h index b9d41dc205..35f206504e 100644 --- a/unit_tests/mocks/mock_gmm_client_context.h +++ b/unit_tests/mocks/mock_gmm_client_context.h @@ -11,6 +11,6 @@ namespace NEO { class MockGmmClientContext : public MockGmmClientContextBase { public: - MockGmmClientContext(GMM_CLIENT clientType, GmmExportEntries &gmmExportEntries); + MockGmmClientContext(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc); }; } // namespace NEO diff --git a/unit_tests/mocks/mock_gmm_client_context_base.cpp b/unit_tests/mocks/mock_gmm_client_context_base.cpp index 7abfcb1759..c91baa0f0d 100644 --- a/unit_tests/mocks/mock_gmm_client_context_base.cpp +++ b/unit_tests/mocks/mock_gmm_client_context_base.cpp @@ -8,7 +8,7 @@ #include "unit_tests/mocks/mock_gmm_client_context.h" namespace NEO { -MockGmmClientContextBase::MockGmmClientContextBase(GMM_CLIENT clientType, GmmExportEntries &gmmExportEntries) : GmmClientContext(clientType, gmmExportEntries) { +MockGmmClientContextBase::MockGmmClientContextBase(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFunc) : GmmClientContext(hwInfo, initFunc, destroyFunc) { } MEMORY_OBJECT_CONTROL_STATE MockGmmClientContextBase::cachePolicyGetMemoryObject(GMM_RESOURCE_INFO *pResInfo, GMM_RESOURCE_USAGE_TYPE usage) { diff --git a/unit_tests/mocks/mock_gmm_client_context_base.h b/unit_tests/mocks/mock_gmm_client_context_base.h index d01a3dd6d8..0430b4cde0 100644 --- a/unit_tests/mocks/mock_gmm_client_context_base.h +++ b/unit_tests/mocks/mock_gmm_client_context_base.h @@ -24,6 +24,6 @@ class MockGmmClientContextBase : public GmmClientContext { uint32_t getMediaSurfaceStateCompressionFormatCalled = 0u; protected: - MockGmmClientContextBase(GMM_CLIENT clientType, GmmExportEntries &gmmExportEntries); + MockGmmClientContextBase(HardwareInfo *hwInfo, decltype(&InitializeGmm) initFunc, decltype(&GmmDestroy) destroyFuncs); }; } // namespace NEO diff --git a/unit_tests/mocks/mock_wddm.h b/unit_tests/mocks/mock_wddm.h index 852203dda9..d8da3804a2 100644 --- a/unit_tests/mocks/mock_wddm.h +++ b/unit_tests/mocks/mock_wddm.h @@ -24,6 +24,7 @@ class GraphicsAllocation; class WddmMock : public Wddm { public: using Wddm::adapter; + using Wddm::adapterBDF; using Wddm::currentPagingFenceValue; using Wddm::dedicatedVideoMemory; using Wddm::device; diff --git a/unit_tests/os_interface/linux/options.cpp b/unit_tests/os_interface/linux/options.cpp index dfd800c731..a31fb5c3f9 100644 --- a/unit_tests/os_interface/linux/options.cpp +++ b/unit_tests/os_interface/linux/options.cpp @@ -21,7 +21,8 @@ const char *igcDllName = "libmock_igc.so"; const char *libvaDllName = nullptr; const char *testDllName = "libtest_dynamic_lib.so"; const char *gmmDllName = "libmock_gmm.so"; -const char *gmmEntryName = "openMockGmm"; +const char *gmmInitFuncName = "initMockGmm"; +const char *gmmDestroyFuncName = "destroyMockGmm"; const char *metricsLibraryDllName = ""; #endif const char *sysFsPciPath = "./test_files"; diff --git a/unit_tests/os_interface/windows/options.cpp b/unit_tests/os_interface/windows/options.cpp index a461610be1..d0579cdfb2 100644 --- a/unit_tests/os_interface/windows/options.cpp +++ b/unit_tests/os_interface/windows/options.cpp @@ -19,7 +19,8 @@ const char *frontEndDllName = ""; const char *igcDllName = ""; const char *gdiDllName = "gdi32_mock.dll"; const char *gmmDllName = "mock_gmm.dll"; -const char *gmmEntryName = "openMockGmm"; +const char *gmmInitFuncName = "initMockGmm"; +const char *gmmDestroyFuncName = "destroyMockGmm"; const char *testDllName = "test_dynamic_lib.dll"; const char *metricsLibraryDllName = ""; } // namespace Os diff --git a/unit_tests/os_interface/windows/os_interface_win_tests.cpp b/unit_tests/os_interface/windows/os_interface_win_tests.cpp index 974f942925..09bf118b96 100644 --- a/unit_tests/os_interface/windows/os_interface_win_tests.cpp +++ b/unit_tests/os_interface/windows/os_interface_win_tests.cpp @@ -34,3 +34,18 @@ TEST(OsContextTest, givenWddmWhenCreateOsContextAfterInitWddmThenOsContextIsInit EXPECT_EQ(osContext->getWddm(), wddm); EXPECT_EQ(1u, wddm->registerTrimCallbackResult.called); } + +TEST_F(OsInterfaceTest, whenOsInterfaceSetupGmmInputArgsThenProperAdapterBDFIsSet) { + auto wddm = new WddmMock; + osInterface->get()->setWddm(wddm); + auto hwInfo = *platformDevices[0]; + wddm->init(hwInfo); + auto &adapterBDF = wddm->adapterBDF; + adapterBDF.Bus = 0x12; + adapterBDF.Device = 0x34; + adapterBDF.Function = 0x56; + GMM_INIT_IN_ARGS gmmInputArgs = {}; + EXPECT_NE(0, memcmp(&adapterBDF, &gmmInputArgs.stAdapterBDF, sizeof(ADAPTER_BDF))); + osInterface->setGmmInputArgs(&gmmInputArgs); + EXPECT_EQ(0, memcmp(&adapterBDF, &gmmInputArgs.stAdapterBDF, sizeof(ADAPTER_BDF))); +}