From c5546a5cfbe121a43358817f8401b22abf8d1d32 Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Mon, 19 Apr 2021 19:53:46 +0000 Subject: [PATCH] add method for setting allocation priority Signed-off-by: Mateusz Jablonski --- opencl/test/unit_test/mocks/mock_wddm.cpp | 11 ++++++++ opencl/test/unit_test/mocks/mock_wddm.h | 3 +++ .../os_interface/windows/gdi_dll_fixture.h | 3 +++ .../os_interface/windows/wddm20_tests.cpp | 20 ++++++++++++++ .../os_interface/windows/gdi_interface.cpp | 1 + .../os_interface/windows/gdi_interface.h | 3 ++- .../source/os_interface/windows/thk_wrapper.h | 3 ++- .../source/os_interface/windows/wddm/wddm.cpp | 23 ++++++++++++++++ .../source/os_interface/windows/wddm/wddm.h | 2 ++ shared/test/common/mock_gdi/gdi32_mock.def | 2 ++ shared/test/common/mock_gdi/mock_gdi.cpp | 27 +++++++++++++++++++ shared/test/common/mock_gdi/mock_gdi.h | 1 + 12 files changed, 97 insertions(+), 2 deletions(-) diff --git a/opencl/test/unit_test/mocks/mock_wddm.cpp b/opencl/test/unit_test/mocks/mock_wddm.cpp index ce69800691..d2652e6a93 100644 --- a/opencl/test/unit_test/mocks/mock_wddm.cpp +++ b/opencl/test/unit_test/mocks/mock_wddm.cpp @@ -301,6 +301,17 @@ void WddmMock::createPagingFenceLogger() { } } +bool WddmMock::setAllocationPriority(const D3DKMT_HANDLE *handles, uint32_t allocationCount, uint32_t priority) { + if (callBaseSetAllocationPriority) { + auto status = Wddm::setAllocationPriority(handles, allocationCount, priority); + setAllocationPriorityResult.success = status; + setAllocationPriorityResult.called++; + setAllocationPriorityResult.uint64ParamPassed = priority; + return status; + } + return setAllocationPriorityResult.success; +} + void *GmockWddm::virtualAllocWrapper(void *inPtr, size_t size, uint32_t flags, uint32_t type) { void *tmp = reinterpret_cast(virtualAllocAddress); size += MemoryConstants::pageSize; diff --git a/opencl/test/unit_test/mocks/mock_wddm.h b/opencl/test/unit_test/mocks/mock_wddm.h index 66b7869e19..40cc1d2243 100644 --- a/opencl/test/unit_test/mocks/mock_wddm.h +++ b/opencl/test/unit_test/mocks/mock_wddm.h @@ -96,6 +96,7 @@ class WddmMock : public Wddm { } return verifyAdapterLuidReturnValue; } + bool setAllocationPriority(const D3DKMT_HANDLE *handles, uint32_t allocationCount, uint32_t priority) override; bool configureDeviceAddressSpace() { configureDeviceAddressSpaceResult.called++; @@ -147,6 +148,7 @@ class WddmMock : public Wddm { WddmMockHelpers::CallResult getPagingFenceAddressResult; WddmMockHelpers::CallResult reserveGpuVirtualAddressResult; WddmMockHelpers::CallResult waitOnPagingFenceFromCpuResult; + WddmMockHelpers::CallResult setAllocationPriorityResult; NTSTATUS createAllocationStatus = STATUS_SUCCESS; bool verifyAdapterLuidReturnValue = true; @@ -163,6 +165,7 @@ class WddmMock : public Wddm { bool callBaseMakeResident = true; bool callBaseCreatePagingLogger = true; bool shutdownStatus = false; + bool callBaseSetAllocationPriority = true; }; struct GmockWddm : WddmMock { diff --git a/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h b/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h index 7417041b20..46d22e4bc8 100644 --- a/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h +++ b/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h @@ -49,6 +49,8 @@ struct GdiDllFixture { reinterpret_cast(mockGdiDll->getProcAddress("getCreateSynchronizationObject2FailCall")); getRegisterTrimNotificationFailCallFcn = reinterpret_cast(mockGdiDll->getProcAddress("getRegisterTrimNotificationFailCall")); + getLastPriorityFcn = + reinterpret_cast(mockGdiDll->getProcAddress("getLastPriority")); setMockLastDestroyedResHandleFcn((D3DKMT_HANDLE)0); *getDestroySynchronizationObjectDataFcn() = {}; *getCreateSynchronizationObject2FailCallFcn() = false; @@ -86,4 +88,5 @@ struct GdiDllFixture { decltype(&getMonitorFenceCpuFenceAddress) getMonitorFenceCpuFenceAddressFcn = nullptr; decltype(&getCreateSynchronizationObject2FailCall) getCreateSynchronizationObject2FailCallFcn = nullptr; decltype(&getRegisterTrimNotificationFailCall) getRegisterTrimNotificationFailCallFcn = nullptr; + decltype(&getLastPriority) getLastPriorityFcn = nullptr; }; 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 8877ad3189..fb8fb4a4e7 100644 --- a/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp +++ b/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp @@ -1533,3 +1533,23 @@ TEST(VerifyAdapterType, whenAdapterSupportsRenderThenCreateHwDeviceId) { auto hwDeviceId = createHwDeviceIdFromAdapterLuid(*osEnv, adapterLuid); EXPECT_NE(nullptr, hwDeviceId.get()); } + +TEST_F(WddmTestWithMockGdiDll, givenInvalidInputwhenSettingAllocationPriorityThenFalseIsReturned) { + init(); + EXPECT_FALSE(wddm->setAllocationPriority(nullptr, 0, DXGI_RESOURCE_PRIORITY_MAXIMUM)); + EXPECT_FALSE(wddm->setAllocationPriority(nullptr, 5, DXGI_RESOURCE_PRIORITY_MAXIMUM)); + { + D3DKMT_HANDLE handles[] = {ALLOCATION_HANDLE, 0}; + EXPECT_FALSE(wddm->setAllocationPriority(handles, 2, DXGI_RESOURCE_PRIORITY_MAXIMUM)); + } +} + +TEST_F(WddmTestWithMockGdiDll, givenValidInputwhenSettingAllocationPriorityThenTrueIsReturned) { + init(); + D3DKMT_HANDLE handles[] = {ALLOCATION_HANDLE, ALLOCATION_HANDLE + 1}; + EXPECT_TRUE(wddm->setAllocationPriority(handles, 2, DXGI_RESOURCE_PRIORITY_MAXIMUM)); + EXPECT_EQ(DXGI_RESOURCE_PRIORITY_MAXIMUM, getLastPriorityFcn()); + + EXPECT_TRUE(wddm->setAllocationPriority(handles, 2, DXGI_RESOURCE_PRIORITY_NORMAL)); + EXPECT_EQ(DXGI_RESOURCE_PRIORITY_NORMAL, getLastPriorityFcn()); +} \ No newline at end of file diff --git a/shared/source/os_interface/windows/gdi_interface.cpp b/shared/source/os_interface/windows/gdi_interface.cpp index 2339a90857..ec41a3fa1a 100644 --- a/shared/source/os_interface/windows/gdi_interface.cpp +++ b/shared/source/os_interface/windows/gdi_interface.cpp @@ -79,6 +79,7 @@ bool Gdi::getAllProcAddresses() { evict = reinterpret_cast(gdiDll.getProcAddress("D3DKMTEvict")); registerTrimNotification = reinterpret_cast(gdiDll.getProcAddress("D3DKMTRegisterTrimNotification")); unregisterTrimNotification = reinterpret_cast(gdiDll.getProcAddress("D3DKMTUnregisterTrimNotification")); + setAllocationPriority = reinterpret_cast(gdiDll.getProcAddress("D3DKMTSetAllocationPriority")); // For debug purposes getDeviceState = reinterpret_cast(gdiDll.getProcAddress("D3DKMTGetDeviceState")); diff --git a/shared/source/os_interface/windows/gdi_interface.h b/shared/source/os_interface/windows/gdi_interface.h index 8a6a4403ee..a4abd34b70 100644 --- a/shared/source/os_interface/windows/gdi_interface.h +++ b/shared/source/os_interface/windows/gdi_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2020 Intel Corporation + * Copyright (C) 2017-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -64,6 +64,7 @@ class Gdi { ThkWrapper evict; ThkWrapper registerTrimNotification; ThkWrapper unregisterTrimNotification; + ThkWrapper setAllocationPriority; // HW queue ThkWrapper createHwQueue; diff --git a/shared/source/os_interface/windows/thk_wrapper.h b/shared/source/os_interface/windows/thk_wrapper.h index 4c71df55c1..eeac9eccd7 100644 --- a/shared/source/os_interface/windows/thk_wrapper.h +++ b/shared/source/os_interface/windows/thk_wrapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2020 Intel Corporation + * Copyright (C) 2017-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -106,5 +106,6 @@ class ThkWrapper { GET_ID(D3DKMT_CREATEHWQUEUE *, SYSTIMER_ID_CREATEHWQUEUE) GET_ID(CONST D3DKMT_DESTROYHWQUEUE *, SYSTIMER_ID_DESTROYHWQUEUE) GET_ID(CONST D3DKMT_SUBMITCOMMANDTOHWQUEUE *, SYSTIMER_ID_SUBMITCOMMANDTOHWQUEUE) + GET_ID(CONST D3DKMT_SETALLOCATIONPRIORITY *, SYSTIMER_ID_SETALLOCATIONPRIORITY) }; } // namespace NEO diff --git a/shared/source/os_interface/windows/wddm/wddm.cpp b/shared/source/os_interface/windows/wddm/wddm.cpp index 73a669585a..4c54d61826 100644 --- a/shared/source/os_interface/windows/wddm/wddm.cpp +++ b/shared/source/os_interface/windows/wddm/wddm.cpp @@ -504,6 +504,29 @@ NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKM return status; } +bool Wddm::setAllocationPriority(const D3DKMT_HANDLE *handles, uint32_t allocationCount, uint32_t priority) { + D3DKMT_SETALLOCATIONPRIORITY setAllocationPriority = {}; + + StackVec priorities{}; + + priorities.resize(allocationCount); + for (auto i = 0u; i < allocationCount; i++) { + priorities[i] = priority; + } + + setAllocationPriority.hDevice = device; + setAllocationPriority.AllocationCount = allocationCount; + setAllocationPriority.hResource = NULL; + setAllocationPriority.phAllocationList = handles; + setAllocationPriority.pPriorities = priorities.data(); + + auto status = getGdi()->setAllocationPriority(&setAllocationPriority); + + DEBUG_BREAK_IF(STATUS_SUCCESS != status); + + return STATUS_SUCCESS == status; +} + bool Wddm::createAllocation64k(const Gmm *gmm, D3DKMT_HANDLE &outHandle) { NTSTATUS status = STATUS_SUCCESS; D3DDDI_ALLOCATIONINFO AllocationInfo = {0}; diff --git a/shared/source/os_interface/windows/wddm/wddm.h b/shared/source/os_interface/windows/wddm/wddm.h index 44c4f8d96f..0410dd0663 100644 --- a/shared/source/os_interface/windows/wddm/wddm.h +++ b/shared/source/os_interface/windows/wddm/wddm.h @@ -75,6 +75,8 @@ class Wddm { MOCKABLE_VIRTUAL void kmDafLock(D3DKMT_HANDLE handle); MOCKABLE_VIRTUAL bool isKmDafEnabled() const { return featureTable->ftrKmdDaf; } + MOCKABLE_VIRTUAL bool setAllocationPriority(const D3DKMT_HANDLE *handles, uint32_t allocationCount, uint32_t priority); + MOCKABLE_VIRTUAL bool destroyContext(D3DKMT_HANDLE context); MOCKABLE_VIRTUAL bool queryAdapterInfo(); diff --git a/shared/test/common/mock_gdi/gdi32_mock.def b/shared/test/common/mock_gdi/gdi32_mock.def index a1860a19cb..16c7922766 100644 --- a/shared/test/common/mock_gdi/gdi32_mock.def +++ b/shared/test/common/mock_gdi/gdi32_mock.def @@ -52,6 +52,7 @@ D3DKMTUnregisterTrimNotification D3DKMTCreateHwQueue D3DKMTDestroyHwQueue D3DKMTSubmitCommandToHwQueue +D3DKMTSetAllocationPriority MockSetAdapterInfo MockSetSizes GetMockSizes @@ -72,3 +73,4 @@ getDestroySynchronizationObjectData getMonitorFenceCpuFenceAddress getCreateSynchronizationObject2FailCall getRegisterTrimNotificationFailCall +getLastPriority diff --git a/shared/test/common/mock_gdi/mock_gdi.cpp b/shared/test/common/mock_gdi/mock_gdi.cpp index 50e82dc514..09eee60c30 100644 --- a/shared/test/common/mock_gdi/mock_gdi.cpp +++ b/shared/test/common/mock_gdi/mock_gdi.cpp @@ -15,6 +15,7 @@ D3DDDI_RESERVEGPUVIRTUALADDRESS gLastCallReserveGpuVaArg = {0}; uint32_t gMapGpuVaFailConfigCount = 0; uint32_t gMapGpuVaFailConfigMax = 0; uint64_t gGpuAddressSpace = 0ull; +uint32_t gLastPriority = 0ull; #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface @@ -396,6 +397,28 @@ NTSTATUS __stdcall D3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESYNCHR return STATUS_SUCCESS; } +NTSTATUS __stdcall D3DKMTSetAllocationPriority(IN CONST D3DKMT_SETALLOCATIONPRIORITY *setAllocationPriority) { + if (setAllocationPriority == nullptr || setAllocationPriority->hDevice != DEVICE_HANDLE) { + return STATUS_INVALID_PARAMETER; + } + + if (setAllocationPriority->hResource == NULL && (setAllocationPriority->AllocationCount == 0 || setAllocationPriority->phAllocationList == NULL)) { + return STATUS_INVALID_PARAMETER; + } + if (setAllocationPriority->pPriorities == NULL) { + return STATUS_INVALID_PARAMETER; + } + auto priority = setAllocationPriority->pPriorities[0]; + gLastPriority = priority; + for (auto i = 0u; i < setAllocationPriority->AllocationCount; i++) { + if (setAllocationPriority->phAllocationList[i] == 0 || setAllocationPriority->pPriorities[i] != priority) { + return STATUS_INVALID_PARAMETER; + } + } + + return STATUS_SUCCESS; +} + static D3DKMT_CREATEHWQUEUE createHwQueueData = {}; NTSTATUS __stdcall D3DKMTCreateHwQueue(IN OUT D3DKMT_CREATEHWQUEUE *createHwQueue) { @@ -524,3 +547,7 @@ bool *getCreateSynchronizationObject2FailCall() { bool *getRegisterTrimNotificationFailCall() { return ®isterTrimNotificationFailCall; } + +uint32_t getLastPriority() { + return gLastPriority; +} \ No newline at end of file diff --git a/shared/test/common/mock_gdi/mock_gdi.h b/shared/test/common/mock_gdi/mock_gdi.h index 57eee66f3c..fe3ed5fbba 100644 --- a/shared/test/common/mock_gdi/mock_gdi.h +++ b/shared/test/common/mock_gdi/mock_gdi.h @@ -78,3 +78,4 @@ void InitGfxPartition(); VOID *getMonitorFenceCpuFenceAddress(); bool *getCreateSynchronizationObject2FailCall(); bool *getRegisterTrimNotificationFailCall(); +uint32_t getLastPriority();