From 44e54ef69b7fb2320b61630fc4a6ed531f3355fb Mon Sep 17 00:00:00 2001 From: "Dunajski, Bartosz" Date: Tue, 8 May 2018 13:19:26 +0200 Subject: [PATCH] Wddm interface [2/n]: Move WddmMock to igdrcl_mocks + more cleanup Change-Id: I993312c1e17fb474e142424b154666f8af6a4170 --- .../windows/deferrable_deletion_win.h | 4 +- runtime/os_interface/windows/os_time.cpp | 5 +- runtime/os_interface/windows/wddm.cpp | 1 - .../windows/wddm_memory_manager.cpp | 6 - .../os_interface/windows/windows_wrapper.h | 9 +- unit_tests/device/device_win_timers_tests.cpp | 4 +- unit_tests/mock_gdi/mock_gdi.cpp | 9 +- unit_tests/mocks/CMakeLists.txt | 2 + unit_tests/mocks/mock_wddm.cpp | 238 +++++++++++ unit_tests/mocks/mock_wddm.h | 131 ++++++ .../os_interface/windows/CMakeLists.txt | 3 +- .../windows/deferrable_deletion_win_tests.cpp | 4 +- .../windows/device_command_stream_tests.cpp | 12 +- .../windows/driver_info_tests.cpp | 2 +- .../windows/mock_performance_counters_win.cpp | 1 + .../windows/mock_performance_counters_win.h | 3 +- .../performance_counters_win_tests.cpp | 2 + .../windows/wddm_address_space_tests.cpp | 152 +++++++ .../os_interface/windows/wddm_create.cpp | 2 +- .../os_interface/windows/wddm_fixture.h | 385 +----------------- .../windows/wddm_kmdaf_listener_tests.cpp | 8 +- .../windows/wddm_memory_manager_tests.cpp | 3 +- .../windows/wddm_preemption_tests.cpp | 111 +++++ .../os_interface/windows/wddm_tests.cpp | 138 ------- unit_tests/os_interface/windows/wddm_tests.h | 68 ---- 25 files changed, 678 insertions(+), 625 deletions(-) create mode 100644 unit_tests/mocks/mock_wddm.cpp create mode 100644 unit_tests/mocks/mock_wddm.h create mode 100644 unit_tests/os_interface/windows/wddm_address_space_tests.cpp create mode 100644 unit_tests/os_interface/windows/wddm_preemption_tests.cpp delete mode 100644 unit_tests/os_interface/windows/wddm_tests.h diff --git a/runtime/os_interface/windows/deferrable_deletion_win.h b/runtime/os_interface/windows/deferrable_deletion_win.h index d50096e90c..42947019f3 100644 --- a/runtime/os_interface/windows/deferrable_deletion_win.h +++ b/runtime/os_interface/windows/deferrable_deletion_win.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2017 - 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"), @@ -22,6 +22,8 @@ #pragma once #include "runtime/memory_manager/deferrable_deletion.h" +#include "runtime/os_interface/windows/windows_wrapper.h" +#include namespace OCLRT { diff --git a/runtime/os_interface/windows/os_time.cpp b/runtime/os_interface/windows/os_time.cpp index 1bbcf2773f..6436bf4c44 100644 --- a/runtime/os_interface/windows/os_time.cpp +++ b/runtime/os_interface/windows/os_time.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, Intel Corporation +* Copyright (c) 2017 - 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"), @@ -21,9 +21,6 @@ */ #include -#include -//For not redefining STATUS_* from ntstatus.h -#define WIN32_NO_STATUS #include "runtime/os_interface/windows/wddm.h" #include "runtime/os_interface/windows/os_interface.h" #include "runtime/os_interface/windows/os_time.h" diff --git a/runtime/os_interface/windows/wddm.cpp b/runtime/os_interface/windows/wddm.cpp index baaf3877e5..ddf2678e3b 100644 --- a/runtime/os_interface/windows/wddm.cpp +++ b/runtime/os_interface/windows/wddm.cpp @@ -38,7 +38,6 @@ #include "runtime/sku_info/operations/sku_info_receiver.h" #include "runtime/utilities/stackvec.h" #include -#include #include "CL/cl.h" namespace OCLRT { diff --git a/runtime/os_interface/windows/wddm_memory_manager.cpp b/runtime/os_interface/windows/wddm_memory_manager.cpp index c678bfc941..0cd54ec13e 100644 --- a/runtime/os_interface/windows/wddm_memory_manager.cpp +++ b/runtime/os_interface/windows/wddm_memory_manager.cpp @@ -33,12 +33,6 @@ #include "runtime/os_interface/windows/wddm_allocation.h" #include "runtime/os_interface/windows/wddm.h" #include -#pragma warning(push) -#pragma warning(disable : 4005) -#include -#pragma warning(pop) - -#undef max namespace OCLRT { diff --git a/runtime/os_interface/windows/windows_wrapper.h b/runtime/os_interface/windows/windows_wrapper.h index bd51801e6c..118389147e 100644 --- a/runtime/os_interface/windows/windows_wrapper.h +++ b/runtime/os_interface/windows/windows_wrapper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2017 - 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"), @@ -22,9 +22,10 @@ #pragma once #include -#ifndef NTSTATUS -#define NTSTATUS LONG -#endif +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) // There is a conflict with max/min defined as macro in windows headers with std::max/std::min #undef min #undef max diff --git a/unit_tests/device/device_win_timers_tests.cpp b/unit_tests/device/device_win_timers_tests.cpp index a264c7b111..34dc9219c9 100644 --- a/unit_tests/device/device_win_timers_tests.cpp +++ b/unit_tests/device/device_win_timers_tests.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, Intel Corporation +* Copyright (c) 2017 - 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"), @@ -23,7 +23,7 @@ #include "unit_tests/mocks/mock_ostime.h" #include "unit_tests/fixtures/device_fixture.h" #include "unit_tests/mocks/mock_ostime_win.h" -#include "unit_tests/os_interface/windows/wddm_fixture.h" +#include "unit_tests/mocks/mock_wddm.h" #include "test.h" using namespace OCLRT; diff --git a/unit_tests/mock_gdi/mock_gdi.cpp b/unit_tests/mock_gdi/mock_gdi.cpp index f4d333457c..a431712719 100644 --- a/unit_tests/mock_gdi/mock_gdi.cpp +++ b/unit_tests/mock_gdi/mock_gdi.cpp @@ -20,15 +20,8 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#define UMDF_USING_NTSTATUS -#include - -#ifndef NTSTATUS -#define NTSTATUS LONG -#endif -#include "mock_gdi.h" -#include #include "runtime/os_interface/windows/os_time.h" +#include "mock_gdi.h" ADAPTER_INFO gAdapterInfo = {0}; D3DDDI_MAPGPUVIRTUALADDRESS gLastCallMapGpuVaArg = {0}; diff --git a/unit_tests/mocks/CMakeLists.txt b/unit_tests/mocks/CMakeLists.txt index 70a4e18345..6e2690a8af 100644 --- a/unit_tests/mocks/CMakeLists.txt +++ b/unit_tests/mocks/CMakeLists.txt @@ -69,6 +69,8 @@ if (WIN32) ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/mock_gmm_memory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_gmm_page_table_mngr.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_gmm_page_table_mngr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm.h ) endif() diff --git a/unit_tests/mocks/mock_wddm.cpp b/unit_tests/mocks/mock_wddm.cpp new file mode 100644 index 0000000000..2a993d18d0 --- /dev/null +++ b/unit_tests/mocks/mock_wddm.cpp @@ -0,0 +1,238 @@ +/* +* 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: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* 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. +*/ + +#include "runtime/helpers/aligned_memory.h" +#include "runtime/os_interface/windows/wddm_allocation.h" +#include "unit_tests/mocks/mock_wddm.h" +#include "unit_tests/mock_gdi/mock_gdi.h" + +#include "gtest/gtest.h" + +using namespace OCLRT; + +WddmMock::~WddmMock() { + EXPECT_EQ(0, reservedAddresses.size()); +} + +bool WddmMock::makeResident(D3DKMT_HANDLE *handles, uint32_t count, bool cantTrimFurther, uint64_t *numberOfBytesToTrim) { + makeResidentResult.called++; + makeResidentResult.handleCount = count; + for (auto i = 0u; i < count; i++) { + makeResidentResult.handlePack.push_back(handles[i]); + } + + return makeResidentResult.success = Wddm::makeResident(handles, count, cantTrimFurther, numberOfBytesToTrim); +} + +bool WddmMock::evict(D3DKMT_HANDLE *handles, uint32_t num, uint64_t &sizeToTrim) { + makeNonResidentResult.called++; + return makeNonResidentResult.success = Wddm::evict(handles, num, sizeToTrim); +} + +bool WddmMock::mapGpuVirtualAddressImpl(Gmm *gmm, D3DKMT_HANDLE handle, void *cpuPtr, uint64_t size, D3DGPU_VIRTUAL_ADDRESS &gpuPtr, bool allocation32Bit, bool use64kbPages, bool useHeap1) { + mapGpuVirtualAddressResult.called++; + mapGpuVirtualAddressResult.cpuPtrPassed = cpuPtr; + if (callBaseMapGpuVa) { + return mapGpuVirtualAddressResult.success = Wddm::mapGpuVirtualAddressImpl(gmm, handle, cpuPtr, size, gpuPtr, allocation32Bit, use64kbPages, useHeap1); + } else { + gpuPtr = reinterpret_cast(cpuPtr); + return mapGpuVaStatus; + } +} + +bool WddmMock::freeGpuVirtualAddres(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size) { + freeGpuVirtualAddresResult.called++; + return freeGpuVirtualAddresResult.success = Wddm::freeGpuVirtualAddres(gpuPtr, size); +} + +NTSTATUS WddmMock::createAllocation(WddmAllocation *alloc) { + createAllocationResult.called++; + if (callBaseDestroyAllocations) { + createAllocationStatus = Wddm::createAllocation(alloc); + createAllocationResult.success = createAllocationStatus == STATUS_SUCCESS; + } else { + createAllocationResult.success = true; + alloc->handle = ALLOCATION_HANDLE; + return createAllocationStatus; + } + return createAllocationStatus; +} + +bool WddmMock::createAllocation64k(WddmAllocation *alloc) { + createAllocationResult.called++; + return createAllocationResult.success = Wddm::createAllocation64k(alloc); +} + +bool WddmMock::destroyAllocations(D3DKMT_HANDLE *handles, uint32_t allocationCount, uint64_t lastFenceValue, D3DKMT_HANDLE resourceHandle) { + destroyAllocationResult.called++; + if (callBaseDestroyAllocations) { + return destroyAllocationResult.success = Wddm::destroyAllocations(handles, allocationCount, lastFenceValue, resourceHandle); + } else { + return true; + } +} + +bool WddmMock::destroyAllocation(WddmAllocation *alloc) { + D3DKMT_HANDLE *allocationHandles = nullptr; + uint32_t allocationCount = 0; + D3DKMT_HANDLE resourceHandle = 0; + void *cpuPtr = nullptr; + void *reserveAddress = alloc->getReservedAddress(); + if (alloc->peekSharedHandle()) { + resourceHandle = alloc->resourceHandle; + } else { + allocationHandles = &alloc->handle; + allocationCount = 1; + if (alloc->cpuPtrAllocated) { + cpuPtr = alloc->getAlignedCpuPtr(); + } + } + auto success = destroyAllocations(allocationHandles, allocationCount, alloc->getResidencyData().lastFence, resourceHandle); + ::alignedFree(cpuPtr); + releaseReservedAddress(reserveAddress); + return success; +} + +bool WddmMock::openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) { + if (failOpenSharedHandle) { + return false; + } else { + return Wddm::openSharedHandle(handle, alloc); + } +} + +bool WddmMock::createContext() { + createContextResult.called++; + return createContextResult.success = Wddm::createContext(); +} + +bool WddmMock::destroyContext(D3DKMT_HANDLE context) { + destroyContextResult.called++; + return destroyContextResult.success = Wddm::destroyContext(context); +} + +bool WddmMock::queryAdapterInfo() { + queryAdapterInfoResult.called++; + return queryAdapterInfoResult.success = Wddm::queryAdapterInfo(); +} + +bool WddmMock::submit(uint64_t commandBuffer, size_t size, void *commandHeader) { + submitResult.called++; + submitResult.commandBufferSubmitted = commandBuffer; + submitResult.commandHeaderSubmitted = commandHeader; + return submitResult.success = Wddm::submit(commandBuffer, size, commandHeader); +} + +bool WddmMock::waitOnGPU() { + waitOnGPUResult.called++; + return waitOnGPUResult.success = Wddm::waitOnGPU(); +} + +void *WddmMock::lockResource(WddmAllocation *allocation) { + lockResult.called++; + auto ptr = Wddm::lockResource(allocation); + lockResult.success = ptr != nullptr; + return ptr; +} + +void WddmMock::unlockResource(WddmAllocation *allocation) { + unlockResult.called++; + unlockResult.success = true; + Wddm::unlockResource(allocation); +} + +void WddmMock::kmDafLock(WddmAllocation *allocation) { + kmDafLockResult.called++; + kmDafLockResult.success = true; + kmDafLockResult.lockedAllocations.push_back(allocation); + Wddm::kmDafLock(allocation); +} + +bool WddmMock::isKmDafEnabled() { + return kmDafEnabled; +} + +void WddmMock::setKmDafEnabled(bool state) { + kmDafEnabled = state; +} + +void WddmMock::setHwContextId(unsigned long hwContextId) { + this->hwContextId = hwContextId; +} + +bool WddmMock::openAdapter() { + this->adapter = ADAPTER_HANDLE; + return true; +} + +void WddmMock::setHeap32(uint64_t base, uint64_t size) { + gfxPartition.Heap32[0].Base = base; + gfxPartition.Heap32[0].Limit = size; +} + +GMM_GFX_PARTITIONING *WddmMock::getGfxPartitionPtr() { + return &gfxPartition; +} + +bool WddmMock::waitFromCpu(uint64_t lastFenceValue) { + waitFromCpuResult.called++; + waitFromCpuResult.uint64ParamPassed = lastFenceValue; + return waitFromCpuResult.success = Wddm::waitFromCpu(lastFenceValue); +} + +void *WddmMock::virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned long type) { + void *address = Wddm::virtualAlloc(inPtr, size, flags, type); + virtualAllocAddress = reinterpret_cast(address); + return address; +} + +int WddmMock::virtualFree(void *ptr, size_t size, unsigned long flags) { + int success = Wddm::virtualFree(ptr, size, flags); + return success; +} + +void WddmMock::releaseReservedAddress(void *reservedAddress) { + releaseReservedAddressResult.called++; + if (reservedAddress != nullptr) { + std::set::iterator it; + it = reservedAddresses.find(reservedAddress); + EXPECT_NE(reservedAddresses.end(), it); + reservedAddresses.erase(it); + } + Wddm::releaseReservedAddress(reservedAddress); +} + +bool WddmMock::reserveValidAddressRange(size_t size, void *&reservedMem) { + reserveValidAddressRangeResult.called++; + bool ret = Wddm::reserveValidAddressRange(size, reservedMem); + if (reservedMem != nullptr) { + std::set::iterator it; + it = reservedAddresses.find(reservedMem); + EXPECT_EQ(reservedAddresses.end(), it); + reservedAddresses.insert(reservedMem); + } + return ret; +} + +GmmMemory *WddmMock::getGmmMemory() const { + return gmmMemory.get(); +} diff --git a/unit_tests/mocks/mock_wddm.h b/unit_tests/mocks/mock_wddm.h new file mode 100644 index 0000000000..0a8443985a --- /dev/null +++ b/unit_tests/mocks/mock_wddm.h @@ -0,0 +1,131 @@ +/* +* 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: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* 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. +*/ + +#pragma once + +#include "runtime/os_interface/windows/wddm.h" +#include +#include + +namespace OCLRT { +namespace WddmMockHelpers { +struct CallResult { + uint32_t called = 0; + uint64_t uint64ParamPassed = -1; + bool success = false; + uint64_t commandBufferSubmitted = 0u; + void *commandHeaderSubmitted = nullptr; + void *cpuPtrPassed = nullptr; +}; +struct MakeResidentCall : public CallResult { + std::vector handlePack; + uint32_t handleCount = 0; +}; +struct KmDafLockCall : public CallResult { + std::vector lockedAllocations; +}; +} // namespace WddmMockHelpers + +class WddmMock : public Wddm { + public: + using Wddm::adapter; + using Wddm::context; + using Wddm::createMonitoredFence; + using Wddm::device; + using Wddm::gdi; + using Wddm::getSystemInfo; + using Wddm::pagingQueue; + + WddmMock() : Wddm(){}; + WddmMock(Gdi *gdi) : Wddm(gdi) {} + ~WddmMock(); + + bool makeResident(D3DKMT_HANDLE *handles, uint32_t count, bool cantTrimFurther, uint64_t *numberOfBytesToTrim) override; + bool evict(D3DKMT_HANDLE *handles, uint32_t num, uint64_t &sizeToTrim) override; + bool mapGpuVirtualAddressImpl(Gmm *gmm, D3DKMT_HANDLE handle, void *cpuPtr, uint64_t size, D3DGPU_VIRTUAL_ADDRESS &gpuPtr, bool allocation32Bit, bool use64kbPages, bool useHeap1) override; + bool freeGpuVirtualAddres(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size) override; + NTSTATUS createAllocation(WddmAllocation *alloc) override; + bool createAllocation64k(WddmAllocation *alloc) override; + bool destroyAllocations(D3DKMT_HANDLE *handles, uint32_t allocationCount, uint64_t lastFenceValue, D3DKMT_HANDLE resourceHandle) override; + bool destroyAllocation(WddmAllocation *alloc); + bool openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) override; + bool createContext() override; + bool destroyContext(D3DKMT_HANDLE context) override; + bool queryAdapterInfo() override; + bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override; + bool waitOnGPU() override; + void *lockResource(WddmAllocation *allocation) override; + void unlockResource(WddmAllocation *allocation) override; + void kmDafLock(WddmAllocation *allocation) override; + bool isKmDafEnabled() override; + void setKmDafEnabled(bool state); + void setHwContextId(unsigned long hwContextId); + bool openAdapter() override; + void setHeap32(uint64_t base, uint64_t size); + GMM_GFX_PARTITIONING *getGfxPartitionPtr(); + bool waitFromCpu(uint64_t lastFenceValue) override; + void *virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned long type) override; + int virtualFree(void *ptr, size_t size, unsigned long flags) override; + void releaseReservedAddress(void *reservedAddress) override; + bool reserveValidAddressRange(size_t size, void *&reservedMem); + GmmMemory *getGmmMemory() const; + + template + bool configureDeviceAddressSpace() { + configureDeviceAddressSpaceResult.called++; + //create context cant be called before configureDeviceAddressSpace + if (createContextResult.called > 0) { + return configureDeviceAddressSpaceResult.success = false; + } else { + return configureDeviceAddressSpaceResult.success = Wddm::configureDeviceAddressSpace(); + } + } + + WddmMockHelpers::MakeResidentCall makeResidentResult; + WddmMockHelpers::CallResult makeNonResidentResult; + WddmMockHelpers::CallResult mapGpuVirtualAddressResult; + WddmMockHelpers::CallResult freeGpuVirtualAddresResult; + WddmMockHelpers::CallResult createAllocationResult; + WddmMockHelpers::CallResult destroyAllocationResult; + WddmMockHelpers::CallResult destroyContextResult; + WddmMockHelpers::CallResult queryAdapterInfoResult; + WddmMockHelpers::CallResult submitResult; + WddmMockHelpers::CallResult waitOnGPUResult; + WddmMockHelpers::CallResult configureDeviceAddressSpaceResult; + WddmMockHelpers::CallResult createContextResult; + WddmMockHelpers::CallResult lockResult; + WddmMockHelpers::CallResult unlockResult; + WddmMockHelpers::KmDafLockCall kmDafLockResult; + WddmMockHelpers::CallResult waitFromCpuResult; + WddmMockHelpers::CallResult releaseReservedAddressResult; + WddmMockHelpers::CallResult reserveValidAddressRangeResult; + + NTSTATUS createAllocationStatus; + bool mapGpuVaStatus; + bool callBaseDestroyAllocations = true; + bool failOpenSharedHandle = false; + bool callBaseMapGpuVa = true; + std::set reservedAddresses; + uintptr_t virtualAllocAddress = OCLRT::windowsMinAddress; + bool kmDafEnabled = false; +}; +} // namespace OCLRT diff --git a/unit_tests/os_interface/windows/CMakeLists.txt b/unit_tests/os_interface/windows/CMakeLists.txt index 0b92b4031b..a6f1841235 100644 --- a/unit_tests/os_interface/windows/CMakeLists.txt +++ b/unit_tests/os_interface/windows/CMakeLists.txt @@ -40,12 +40,13 @@ set(IGDRCL_SRCS_tests_os_interface_windows ${CMAKE_CURRENT_SOURCE_DIR}/os_time_win_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/performance_counters_win_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/self_lib_win.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/wddm_address_space_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_fixture.h ${CMAKE_CURRENT_SOURCE_DIR}/wddm_kmdaf_listener_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_manager_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_manager_tests.h + ${CMAKE_CURRENT_SOURCE_DIR}/wddm_preemption_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_tests.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/wddm_tests.h ) if(WIN32) target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_os_interface_windows}) diff --git a/unit_tests/os_interface/windows/deferrable_deletion_win_tests.cpp b/unit_tests/os_interface/windows/deferrable_deletion_win_tests.cpp index 89a7ad5cae..ac70009ed4 100644 --- a/unit_tests/os_interface/windows/deferrable_deletion_win_tests.cpp +++ b/unit_tests/os_interface/windows/deferrable_deletion_win_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2017 - 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"), @@ -20,8 +20,8 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "unit_tests/os_interface/windows/wddm_fixture.h" #include "runtime/os_interface/windows/deferrable_deletion_win.h" +#include "unit_tests/mocks/mock_wddm.h" #include "gtest/gtest.h" using namespace OCLRT; diff --git a/unit_tests/os_interface/windows/device_command_stream_tests.cpp b/unit_tests/os_interface/windows/device_command_stream_tests.cpp index 2704f775f9..c1074bae20 100644 --- a/unit_tests/os_interface/windows/device_command_stream_tests.cpp +++ b/unit_tests/os_interface/windows/device_command_stream_tests.cpp @@ -20,26 +20,20 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#pragma warning(push) -#pragma warning(disable : 4005) #include "runtime/command_stream/command_stream_receiver.h" #include "runtime/command_stream/command_stream_receiver_with_aub_dump.h" #include "runtime/command_stream/aub_command_stream_receiver.h" #include "runtime/command_stream/device_command_stream.h" #include "runtime/command_stream/linear_stream.h" #include "runtime/command_stream/preemption.h" -#include "runtime/helpers/options.h" #include "runtime/gen_common/hw_cmds.h" +#include "runtime/helpers/options.h" +#include "runtime/helpers/translationtable_callbacks.h" #include "runtime/memory_manager/memory_manager.h" #include "runtime/mem_obj/buffer.h" #include "runtime/os_interface/windows/wddm_device_command_stream.h" #include "runtime/os_interface/windows/wddm_memory_manager.h" -#include "runtime/helpers/translationtable_callbacks.h" -#pragma warning(pop) -#include "test.h" #include "unit_tests/fixtures/memory_management_fixture.h" #include "unit_tests/mocks/mock_buffer.h" #include "unit_tests/mocks/mock_device.h" @@ -51,6 +45,8 @@ #include "unit_tests/os_interface/windows/mock_gdi_interface.h" #include "unit_tests/helpers/debug_manager_state_restore.h" +#include "test.h" + using namespace OCLRT; using namespace ::testing; diff --git a/unit_tests/os_interface/windows/driver_info_tests.cpp b/unit_tests/os_interface/windows/driver_info_tests.cpp index b802a0b765..fff593422d 100644 --- a/unit_tests/os_interface/windows/driver_info_tests.cpp +++ b/unit_tests/os_interface/windows/driver_info_tests.cpp @@ -20,7 +20,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "unit_tests/os_interface/windows/wddm_fixture.h" #include "runtime/os_interface/windows/driver_info.h" #include "runtime/os_interface/windows/registry_reader.h" #include "runtime/os_interface/windows/os_interface.h" @@ -28,6 +27,7 @@ #include "runtime/helpers/options.h" #include "unit_tests/mocks/mock_device.h" #include "unit_tests/mocks/mock_csr.h" +#include "unit_tests/mocks/mock_wddm.h" #include "unit_tests/libult/create_command_stream.h" #include "gtest/gtest.h" diff --git a/unit_tests/os_interface/windows/mock_performance_counters_win.cpp b/unit_tests/os_interface/windows/mock_performance_counters_win.cpp index 6a5d89d220..3bf7fc680d 100644 --- a/unit_tests/os_interface/windows/mock_performance_counters_win.cpp +++ b/unit_tests/os_interface/windows/mock_performance_counters_win.cpp @@ -21,6 +21,7 @@ */ #include "runtime/os_interface/windows/windows_wrapper.h" +#include "unit_tests/mocks/mock_wddm.h" #include "mock_performance_counters_win.h" namespace OCLRT { diff --git a/unit_tests/os_interface/windows/mock_performance_counters_win.h b/unit_tests/os_interface/windows/mock_performance_counters_win.h index a71fef0be6..24f2abed00 100644 --- a/unit_tests/os_interface/windows/mock_performance_counters_win.h +++ b/unit_tests/os_interface/windows/mock_performance_counters_win.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, Intel Corporation +* Copyright (c) 2017 - 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"), @@ -24,7 +24,6 @@ #include "runtime/os_interface/windows/performance_counters_win.h" #include "unit_tests/os_interface/mock_performance_counters.h" #include "unit_tests/os_interface/windows/mock_os_time_win.h" -#include "unit_tests/os_interface/windows/wddm_fixture.h" namespace OCLRT { diff --git a/unit_tests/os_interface/windows/performance_counters_win_tests.cpp b/unit_tests/os_interface/windows/performance_counters_win_tests.cpp index a4f833ec01..7c62fc2455 100644 --- a/unit_tests/os_interface/windows/performance_counters_win_tests.cpp +++ b/unit_tests/os_interface/windows/performance_counters_win_tests.cpp @@ -20,7 +20,9 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include "runtime/helpers/options.h" #include "runtime/os_interface/windows/windows_wrapper.h" +#include "unit_tests/mocks/mock_wddm.h" #include "unit_tests/os_interface/windows/mock_performance_counters_win.h" #include "gtest/gtest.h" diff --git a/unit_tests/os_interface/windows/wddm_address_space_tests.cpp b/unit_tests/os_interface/windows/wddm_address_space_tests.cpp new file mode 100644 index 0000000000..bb529e55d7 --- /dev/null +++ b/unit_tests/os_interface/windows/wddm_address_space_tests.cpp @@ -0,0 +1,152 @@ +/* + * 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: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * 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. + */ + +#include "unit_tests/mocks/mock_wddm.h" +#include "test.h" + +using namespace OCLRT; + +class WddmMockReserveAddress : public WddmMock { + public: + WddmMockReserveAddress() : WddmMock() {} + WddmMockReserveAddress(Gdi *gdi) : WddmMock(gdi) {} + + void *virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned long type) override { + if (returnGood != 0) { + return WddmMock::virtualAlloc(inPtr, size, flags, type); + } + + if (returnInvalidCount != 0) { + returnInvalidIter++; + if (returnInvalidIter > returnInvalidCount) { + return WddmMock::virtualAlloc(inPtr, size, flags, type); + } + if (returnNullCount != 0) { + returnNullIter++; + if (returnNullIter > returnNullCount) { + return nullptr; + } + return reinterpret_cast(0x1000); + } + return reinterpret_cast(0x1000); + } + + return nullptr; + } + + int virtualFree(void *ptr, size_t size, unsigned long flags) override { + if ((ptr == reinterpret_cast(0x1000)) || (ptr == reinterpret_cast(0x0))) { + return 1; + } + + return WddmMock::virtualFree(ptr, size, flags); + } + + uint32_t returnGood = 0; + uint32_t returnInvalidCount = 0; + uint32_t returnInvalidIter = 0; + uint32_t returnNullCount = 0; + uint32_t returnNullIter = 0; +}; + +using WddmReserveAddressTest = ::testing::Test; + +HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsSuccessfulThenReturnReserveAddress) { + std::unique_ptr wddm(new WddmMockReserveAddress()); + size_t size = 0x1000; + void *reserve = nullptr; + + bool ret = wddm->init(); + EXPECT_TRUE(ret); + + wddm->returnGood = 1; + + ret = wddm->reserveValidAddressRange(size, reserve); + uintptr_t expectedReserve = wddm->virtualAllocAddress; + EXPECT_TRUE(ret); + EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); + wddm->releaseReservedAddress(reserve); +} + +HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsNullThenReturnNull) { + std::unique_ptr wddm(new WddmMockReserveAddress()); + size_t size = 0x1000; + void *reserve = nullptr; + + bool ret = wddm->init(); + EXPECT_TRUE(ret); + uintptr_t expectedReserve = 0; + ret = wddm->reserveValidAddressRange(size, reserve); + EXPECT_FALSE(ret); + EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); +} + +HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsInvalidSecondSuccessfulThenReturnSecond) { + std::unique_ptr wddm(new WddmMockReserveAddress()); + size_t size = 0x1000; + void *reserve = nullptr; + + bool ret = wddm->init(); + EXPECT_TRUE(ret); + + wddm->returnInvalidCount = 1; + + ret = wddm->reserveValidAddressRange(size, reserve); + uintptr_t expectedReserve = wddm->virtualAllocAddress; + EXPECT_TRUE(ret); + EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); + wddm->releaseReservedAddress(reserve); +} + +HWTEST_F(WddmReserveAddressTest, givenWddmWhenSecondIsInvalidThirdSuccessfulThenReturnThird) { + std::unique_ptr wddm(new WddmMockReserveAddress()); + size_t size = 0x1000; + void *reserve = nullptr; + + bool ret = wddm->init(); + EXPECT_TRUE(ret); + + wddm->returnInvalidCount = 2; + + ret = wddm->reserveValidAddressRange(size, reserve); + uintptr_t expectedReserve = wddm->virtualAllocAddress; + EXPECT_TRUE(ret); + EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); + wddm->releaseReservedAddress(reserve); +} + +HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsInvalidSecondNullThenReturnSecondNull) { + std::unique_ptr wddm(new WddmMockReserveAddress()); + size_t size = 0x1000; + void *reserve = nullptr; + + bool ret = wddm->init(); + EXPECT_TRUE(ret); + + wddm->returnInvalidCount = 2; + wddm->returnNullCount = 1; + uintptr_t expectedReserve = 0; + + ret = wddm->reserveValidAddressRange(size, reserve); + EXPECT_FALSE(ret); + EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); +} diff --git a/unit_tests/os_interface/windows/wddm_create.cpp b/unit_tests/os_interface/windows/wddm_create.cpp index fd09525c91..3f41fbca70 100644 --- a/unit_tests/os_interface/windows/wddm_create.cpp +++ b/unit_tests/os_interface/windows/wddm_create.cpp @@ -20,7 +20,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "unit_tests/os_interface/windows/wddm_fixture.h" +#include "unit_tests/mocks/mock_wddm.h" #include "unit_tests/os_interface/windows/ult_dxgi_factory.h" namespace OCLRT { diff --git a/unit_tests/os_interface/windows/wddm_fixture.h b/unit_tests/os_interface/windows/wddm_fixture.h index 5e2ea6dd0d..d36264fb3f 100644 --- a/unit_tests/os_interface/windows/wddm_fixture.h +++ b/unit_tests/os_interface/windows/wddm_fixture.h @@ -21,384 +21,15 @@ */ #pragma once -#include "runtime/helpers/aligned_memory.h" -#include "runtime/helpers/hw_info.h" -#include "runtime/helpers/options.h" -#include "runtime/memory_manager/memory_constants.h" + #include "runtime/os_interface/windows/gdi_interface.h" -#include "runtime/os_interface/windows/wddm.h" -#include "runtime/os_interface/windows/wddm_allocation.h" -#include "unit_tests/helpers/debug_manager_state_restore.h" -#include "unit_tests/mock_gdi/mock_gdi.h" -#include "mock_gmm_memory.h" +#include "unit_tests/mocks/mock_wddm.h" #include "unit_tests/os_interface/windows/mock_gdi_interface.h" #include "unit_tests/os_interface/windows/gdi_dll_fixture.h" -#pragma warning(push) -#pragma warning(disable : 4005) -#include -#pragma warning(pop) - -#include - -using namespace OCLRT; - -OsLibrary *setAdapterInfo(const PLATFORM *platform, const GT_SYSTEM_INFO *gtSystemInfo); - -class WddmMock : public Wddm { - struct CallResult { - uint32_t called = 0; - uint64_t uint64ParamPassed = -1; - bool success = false; - uint64_t commandBufferSubmitted = 0u; - void *commandHeaderSubmitted = nullptr; - void *cpuPtrPassed = nullptr; - }; - struct MakeResidentCall : public CallResult { - std::vector handlePack; - uint32_t handleCount = 0; - }; - struct KmDafLockCall : public CallResult { - std::vector lockedAllocations; - }; - - public: - using Wddm::adapter; - using Wddm::context; - using Wddm::createMonitoredFence; - using Wddm::device; - using Wddm::gdi; - using Wddm::getSystemInfo; - using Wddm::pagingQueue; - - WddmMock() : makeResidentResult(), - makeNonResidentResult(), - mapGpuVirtualAddressResult(), - freeGpuVirtualAddresResult(), - createAllocationResult(), - destroyAllocationResult(), - destroyContextResult(), - queryAdapterInfoResult(), - submitResult(), - waitOnGPUResult(), - configureDeviceAddressSpaceResult(), - createContextResult(), - lockResult(), - unlockResult(), - waitFromCpuResult(), - releaseReservedAddressResult(), - reserveValidAddressRangeResult() { - reservedAddresses.clear(); - virtualAllocAddress = OCLRT::windowsMinAddress; - } - - WddmMock(Gdi *gdi) : Wddm(gdi), - makeResidentResult(), - makeNonResidentResult(), - mapGpuVirtualAddressResult(), - freeGpuVirtualAddresResult(), - createAllocationResult(), - destroyAllocationResult(), - destroyContextResult(), - queryAdapterInfoResult(), - submitResult(), - waitOnGPUResult(), - configureDeviceAddressSpaceResult(), - createContextResult(), - lockResult(), - unlockResult(), - waitFromCpuResult(), - releaseReservedAddressResult(), - reserveValidAddressRangeResult() { - reservedAddresses.clear(); - virtualAllocAddress = OCLRT::windowsMinAddress; - } - - ~WddmMock() { - EXPECT_EQ(0, reservedAddresses.size()); - } - - bool makeResident(D3DKMT_HANDLE *handles, uint32_t count, bool cantTrimFurther, uint64_t *numberOfBytesToTrim) override { - makeResidentResult.called++; - makeResidentResult.handleCount = count; - for (auto i = 0u; i < count; i++) { - makeResidentResult.handlePack.push_back(handles[i]); - } - - return makeResidentResult.success = Wddm::makeResident(handles, count, cantTrimFurther, numberOfBytesToTrim); - } - bool evict(D3DKMT_HANDLE *handles, uint32_t num, uint64_t &sizeToTrim) override { - makeNonResidentResult.called++; - return makeNonResidentResult.success = Wddm::evict(handles, num, sizeToTrim); - } - bool mapGpuVirtualAddressImpl(Gmm *gmm, D3DKMT_HANDLE handle, void *cpuPtr, uint64_t size, D3DGPU_VIRTUAL_ADDRESS &gpuPtr, bool allocation32Bit, bool use64kbPages, bool useHeap1) override { - mapGpuVirtualAddressResult.called++; - mapGpuVirtualAddressResult.cpuPtrPassed = cpuPtr; - if (callBaseMapGpuVa) { - return mapGpuVirtualAddressResult.success = Wddm::mapGpuVirtualAddressImpl(gmm, handle, cpuPtr, size, gpuPtr, allocation32Bit, use64kbPages, useHeap1); - } else { - gpuPtr = reinterpret_cast(cpuPtr); - return mapGpuVaStatus; - } - } - bool freeGpuVirtualAddres(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size) override { - freeGpuVirtualAddresResult.called++; - return freeGpuVirtualAddresResult.success = Wddm::freeGpuVirtualAddres(gpuPtr, size); - } - NTSTATUS createAllocation(WddmAllocation *alloc) override { - createAllocationResult.called++; - if (callBaseDestroyAllocations) { - createAllocationStatus = Wddm::createAllocation(alloc); - createAllocationResult.success = createAllocationStatus == STATUS_SUCCESS; - } else { - createAllocationResult.success = true; - alloc->handle = ALLOCATION_HANDLE; - return createAllocationStatus; - } - return createAllocationStatus; - } - bool createAllocation64k(WddmAllocation *alloc) override { - createAllocationResult.called++; - return createAllocationResult.success = Wddm::createAllocation64k(alloc); - } - bool destroyAllocations(D3DKMT_HANDLE *handles, uint32_t allocationCount, uint64_t lastFenceValue, D3DKMT_HANDLE resourceHandle) override { - destroyAllocationResult.called++; - if (callBaseDestroyAllocations) { - return destroyAllocationResult.success = Wddm::destroyAllocations(handles, allocationCount, lastFenceValue, resourceHandle); - } else { - return true; - } - } - bool destroyAllocation(WddmAllocation *alloc) { - D3DKMT_HANDLE *allocationHandles = nullptr; - uint32_t allocationCount = 0; - D3DKMT_HANDLE resourceHandle = 0; - void *cpuPtr = nullptr; - void *reserveAddress = alloc->getReservedAddress(); - if (alloc->peekSharedHandle()) { - resourceHandle = alloc->resourceHandle; - } else { - allocationHandles = &alloc->handle; - allocationCount = 1; - if (alloc->cpuPtrAllocated) { - cpuPtr = alloc->getAlignedCpuPtr(); - } - } - auto success = destroyAllocations(allocationHandles, allocationCount, alloc->getResidencyData().lastFence, resourceHandle); - ::alignedFree(cpuPtr); - releaseReservedAddress(reserveAddress); - return success; - } - - bool openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) { - if (failOpenSharedHandle) { - return false; - } else { - return Wddm::openSharedHandle(handle, alloc); - } - } - - bool createContext() override { - createContextResult.called++; - return createContextResult.success = Wddm::createContext(); - } - bool destroyContext(D3DKMT_HANDLE context) override { - destroyContextResult.called++; - return destroyContextResult.success = Wddm::destroyContext(context); - } - bool queryAdapterInfo() override { - queryAdapterInfoResult.called++; - return queryAdapterInfoResult.success = Wddm::queryAdapterInfo(); - } - - bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override { - submitResult.called++; - submitResult.commandBufferSubmitted = commandBuffer; - submitResult.commandHeaderSubmitted = commandHeader; - return submitResult.success = Wddm::submit(commandBuffer, size, commandHeader); - } - bool waitOnGPU() override { - waitOnGPUResult.called++; - return waitOnGPUResult.success = Wddm::waitOnGPU(); - } - - template - bool configureDeviceAddressSpace() { - configureDeviceAddressSpaceResult.called++; - //create context cant be called before configureDeviceAddressSpace - if (createContextResult.called > 0) { - return configureDeviceAddressSpaceResult.success = false; - } else { - return configureDeviceAddressSpaceResult.success = Wddm::configureDeviceAddressSpace(); - } - } - void *lockResource(WddmAllocation *allocation) override { - lockResult.called++; - auto ptr = Wddm::lockResource(allocation); - lockResult.success = ptr != nullptr; - return ptr; - } - void unlockResource(WddmAllocation *allocation) override { - unlockResult.called++; - unlockResult.success = true; - Wddm::unlockResource(allocation); - } - void kmDafLock(WddmAllocation *allocation) override { - kmDafLockResult.called++; - kmDafLockResult.success = true; - kmDafLockResult.lockedAllocations.push_back(allocation); - Wddm::kmDafLock(allocation); - } - bool isKmDafEnabled() override { - return kmDafEnabled; - } - void setKmDafEnabled(bool state) { - kmDafEnabled = state; - } - void setHwContextId(unsigned long hwContextId) { - this->hwContextId = hwContextId; - } - - bool openAdapter() override { - this->adapter = ADAPTER_HANDLE; - return true; - } - - void setHeap32(uint64_t base, uint64_t size) { - gfxPartition.Heap32[0].Base = base; - gfxPartition.Heap32[0].Limit = size; - } - - GMM_GFX_PARTITIONING *getGfxPartitionPtr() { - return &gfxPartition; - } - - bool waitFromCpu(uint64_t lastFenceValue) override { - waitFromCpuResult.called++; - waitFromCpuResult.uint64ParamPassed = lastFenceValue; - return waitFromCpuResult.success = Wddm::waitFromCpu(lastFenceValue); - } - - void *virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned long type) override { - void *address = Wddm::virtualAlloc(inPtr, size, flags, type); - virtualAllocAddress = (uintptr_t)address; - return address; - } - int virtualFree(void *ptr, size_t size, unsigned long flags) override { - int success = Wddm::virtualFree(ptr, size, flags); - return success; - } - - void releaseReservedAddress(void *reservedAddress) override { - releaseReservedAddressResult.called++; - if (reservedAddress != nullptr) { - std::set::iterator it; - it = reservedAddresses.find(reservedAddress); - EXPECT_NE(reservedAddresses.end(), it); - reservedAddresses.erase(it); - } - Wddm::releaseReservedAddress(reservedAddress); - } - - bool reserveValidAddressRange(size_t size, void *&reservedMem) { - reserveValidAddressRangeResult.called++; - bool ret = Wddm::reserveValidAddressRange(size, reservedMem); - if (reservedMem != nullptr) { - std::set::iterator it; - it = reservedAddresses.find(reservedMem); - EXPECT_EQ(reservedAddresses.end(), it); - reservedAddresses.insert(reservedMem); - } - return ret; - } - - GmmMemory *getGmmMemory() { - return gmmMemory.get(); - } - - MakeResidentCall makeResidentResult; - CallResult makeNonResidentResult; - CallResult mapGpuVirtualAddressResult; - CallResult freeGpuVirtualAddresResult; - CallResult createAllocationResult; - CallResult destroyAllocationResult; - CallResult destroyContextResult; - CallResult queryAdapterInfoResult; - CallResult submitResult; - CallResult waitOnGPUResult; - CallResult configureDeviceAddressSpaceResult; - CallResult createContextResult; - CallResult lockResult; - CallResult unlockResult; - KmDafLockCall kmDafLockResult; - CallResult waitFromCpuResult; - CallResult releaseReservedAddressResult; - CallResult reserveValidAddressRangeResult; - NTSTATUS createAllocationStatus; - bool mapGpuVaStatus; - bool callBaseDestroyAllocations = true; - bool failOpenSharedHandle = false; - bool callBaseMapGpuVa = true; - std::set reservedAddresses; - uintptr_t virtualAllocAddress; - bool kmDafEnabled = false; -}; - -class WddmMockReserveAddress : public WddmMock { - public: - WddmMockReserveAddress() : WddmMock() { - returnGood = 0; - returnInvalidCount = 0; - returnInvalidIter = 0; - returnNullCount = 0; - returnNullIter = 0; - } - WddmMockReserveAddress(Gdi *gdi) : WddmMock(gdi) { - returnGood = 0; - returnInvalidCount = 0; - returnInvalidIter = 0; - returnNullCount = 0; - returnNullIter = 0; - } - - void *virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned long type) override { - if (returnGood != 0) { - return WddmMock::virtualAlloc(inPtr, size, flags, type); - } - - if (returnInvalidCount != 0) { - returnInvalidIter++; - if (returnInvalidIter > returnInvalidCount) { - return WddmMock::virtualAlloc(inPtr, size, flags, type); - } - if (returnNullCount != 0) { - returnNullIter++; - if (returnNullIter > returnNullCount) { - return nullptr; - } - return reinterpret_cast(0x1000); - } - return reinterpret_cast(0x1000); - } - - return nullptr; - } - - int virtualFree(void *ptr, size_t size, unsigned long flags) override { - - if ((ptr == reinterpret_cast(0x1000)) || (ptr == reinterpret_cast(0x0))) { - return 1; - } - - return WddmMock::virtualFree(ptr, size, flags); - } - - uint32_t returnGood; - uint32_t returnInvalidCount; - uint32_t returnInvalidIter; - uint32_t returnNullCount; - uint32_t returnNullIter; -}; +#include "mock_gmm_memory.h" +#include "test.h" +namespace OCLRT { struct WddmFixture { virtual void SetUp() { wddm.reset(static_cast(Wddm::createWddm(&gdi))); @@ -436,3 +67,9 @@ struct WddmInstrumentationGmmFixture { std::unique_ptr wddm; GmockGmmMemory *gmmMem = nullptr; }; + +typedef Test WddmTest; +typedef Test WddmTestWithMockGdiDll; +typedef Test WddmInstrumentationTest; +typedef ::testing::Test WddmTestSingle; +} // namespace OCLRT diff --git a/unit_tests/os_interface/windows/wddm_kmdaf_listener_tests.cpp b/unit_tests/os_interface/windows/wddm_kmdaf_listener_tests.cpp index 7b0960a469..fc2c060819 100644 --- a/unit_tests/os_interface/windows/wddm_kmdaf_listener_tests.cpp +++ b/unit_tests/os_interface/windows/wddm_kmdaf_listener_tests.cpp @@ -20,10 +20,12 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "unit_tests/os_interface/windows/mock_kmdaf_listener.h" -#include "unit_tests/os_interface/windows/wddm_tests.h" #include "runtime/os_interface/windows/wddm.h" -#include "gtest/gtest.h" +#include "runtime/os_interface/windows/wddm_allocation.h" +#include "unit_tests/os_interface/windows/mock_kmdaf_listener.h" +#include "unit_tests/os_interface/windows/mock_gdi_interface.h" +#include "unit_tests/mock_gdi/mock_gdi.h" +#include "test.h" using namespace OCLRT; diff --git a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp index f38893ccc5..7d2359f3a5 100644 --- a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp @@ -20,14 +20,15 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include "runtime/gmm_helper/gmm_helper.h" #include "runtime/helpers/aligned_memory.h" #include "runtime/mem_obj/buffer.h" #include "runtime/mem_obj/image.h" #include "runtime/os_interface/os_library.h" +#include "unit_tests/helpers/debug_manager_state_restore.h" #include "unit_tests/mocks/mock_deferred_deleter.h" #include "unit_tests/os_interface/windows/wddm_memory_manager_tests.h" -#include "runtime/gmm_helper/gmm_helper.h" using namespace OCLRT; using namespace ::testing; diff --git a/unit_tests/os_interface/windows/wddm_preemption_tests.cpp b/unit_tests/os_interface/windows/wddm_preemption_tests.cpp new file mode 100644 index 0000000000..c102e2f487 --- /dev/null +++ b/unit_tests/os_interface/windows/wddm_preemption_tests.cpp @@ -0,0 +1,111 @@ +/* + * 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: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * 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. + */ + +#include "runtime/command_stream/preemption.h" +#include "unit_tests/helpers/debug_manager_state_restore.h" +#include "unit_tests/os_interface/windows/wddm_fixture.h" +#include "test.h" + +using namespace OCLRT; + +class WddmPreemptionTests : public Test { + public: + void SetUp() override { + WddmFixtureWithMockGdiDll::SetUp(); + const HardwareInfo hwInfo = *platformDevices[0]; + memcpy(&hwInfoTest, &hwInfo, sizeof(hwInfoTest)); + dbgRestorer = new DebugManagerStateRestore(); + } + + void TearDown() override { + delete dbgRestorer; + WddmFixtureWithMockGdiDll::TearDown(); + } + + template + void createAndInitWddm(unsigned int forceReturnPreemptionRegKeyValue) { + wddm.reset(static_cast(Wddm::createWddm())); + auto regReader = new RegistryReaderMock(); + wddm->registryReader.reset(regReader); + regReader->forceRetValue = forceReturnPreemptionRegKeyValue; + PreemptionMode preemptionMode = PreemptionHelper::getDefaultPreemptionMode(hwInfoTest); + wddm->setPreemptionMode(preemptionMode); + wddm->init(); + } + + DebugManagerStateRestore *dbgRestorer = nullptr; + HardwareInfo hwInfoTest; +}; + +HWTEST_F(WddmPreemptionTests, givenDevicePreemptionEnabledDebugFlagDontForceWhenPreemptionRegKeySetThenSetGpuTimeoutFlagOn) { + DebugManager.flags.ForcePreemptionMode.set(-1); // dont force + hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread; + unsigned int expectedVal = 1u; + createAndInitWddm(1u); + EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); + EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); +} + +HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagDontForceWhenPreemptionRegKeySetThenSetGpuTimeoutFlagOff) { + DebugManager.flags.ForcePreemptionMode.set(-1); // dont force + hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; + unsigned int expectedVal = 0u; + createAndInitWddm(1u); + EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); + EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); +} + +HWTEST_F(WddmPreemptionTests, givenDevicePreemptionEnabledDebugFlagDontForceWhenPreemptionRegKeyNotSetThenSetGpuTimeoutFlagOff) { + DebugManager.flags.ForcePreemptionMode.set(-1); // dont force + hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread; + unsigned int expectedVal = 0u; + createAndInitWddm(0u); + EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); + EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); +} + +HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagDontForceWhenPreemptionRegKeyNotSetThenSetGpuTimeoutFlagOff) { + DebugManager.flags.ForcePreemptionMode.set(-1); // dont force + hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; + unsigned int expectedVal = 0u; + createAndInitWddm(0u); + EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); + EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); +} + +HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagForcePreemptionWhenPreemptionRegKeySetThenSetGpuTimeoutFlagOn) { + DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::MidThread)); // force preemption + hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; + unsigned int expectedVal = 1u; + createAndInitWddm(1u); + EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); + EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); +} + +HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagForcePreemptionWhenPreemptionRegKeyNotSetThenSetGpuTimeoutFlagOff) { + DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::MidThread)); // force preemption + hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; + unsigned int expectedVal = 0u; + createAndInitWddm(0u); + EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); + EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); +} diff --git a/unit_tests/os_interface/windows/wddm_tests.cpp b/unit_tests/os_interface/windows/wddm_tests.cpp index bbe5bd4f3e..21b70bda84 100644 --- a/unit_tests/os_interface/windows/wddm_tests.cpp +++ b/unit_tests/os_interface/windows/wddm_tests.cpp @@ -21,7 +21,6 @@ */ #include "unit_tests/os_interface/windows/wddm_fixture.h" -#include "unit_tests/os_interface/windows/wddm_tests.h" #include "runtime/helpers/hw_info.h" #include "runtime/helpers/options.h" @@ -668,60 +667,6 @@ HWTEST_F(WddmTest, givenDebugManagerWhenGetForUseNoRingFlushesKmdModeIsCalledThe EXPECT_TRUE(DebugManager.flags.UseNoRingFlushesKmdMode.get()); } -HWTEST_F(WddmPreemptionTests, givenDevicePreemptionEnabledDebugFlagDontForceWhenPreemptionRegKeySetThenSetGpuTimeoutFlagOn) { - DebugManager.flags.ForcePreemptionMode.set(-1); // dont force - hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread; - unsigned int expectedVal = 1u; - createAndInitWddm(1u); - EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); - EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); -} - -HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagDontForceWhenPreemptionRegKeySetThenSetGpuTimeoutFlagOff) { - DebugManager.flags.ForcePreemptionMode.set(-1); // dont force - hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; - unsigned int expectedVal = 0u; - createAndInitWddm(1u); - EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); - EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); -} - -HWTEST_F(WddmPreemptionTests, givenDevicePreemptionEnabledDebugFlagDontForceWhenPreemptionRegKeyNotSetThenSetGpuTimeoutFlagOff) { - DebugManager.flags.ForcePreemptionMode.set(-1); // dont force - hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread; - unsigned int expectedVal = 0u; - createAndInitWddm(0u); - EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); - EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); -} - -HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagDontForceWhenPreemptionRegKeyNotSetThenSetGpuTimeoutFlagOff) { - DebugManager.flags.ForcePreemptionMode.set(-1); // dont force - hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; - unsigned int expectedVal = 0u; - createAndInitWddm(0u); - EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); - EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); -} - -HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagForcePreemptionWhenPreemptionRegKeySetThenSetGpuTimeoutFlagOn) { - DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::MidThread)); // force preemption - hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; - unsigned int expectedVal = 1u; - createAndInitWddm(1u); - EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); - EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); -} - -HWTEST_F(WddmPreemptionTests, givenDevicePreemptionDisabledDebugFlagForcePreemptionWhenPreemptionRegKeyNotSetThenSetGpuTimeoutFlagOff) { - DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::MidThread)); // force preemption - hwInfoTest.capabilityTable.defaultPreemptionMode = PreemptionMode::Disabled; - unsigned int expectedVal = 0u; - createAndInitWddm(0u); - EXPECT_EQ(expectedVal, getMockCreateDeviceParamsFcn().Flags.DisableGpuTimeout); - EXPECT_EQ(expectedVal, getCreateContextDataFcn()->Flags.DisableGpuTimeout); -} - HWTEST_F(WddmTest, makeResidentMultipleHandles) { wddm->init(); ASSERT_TRUE(wddm->isInitialized()); @@ -943,89 +888,6 @@ HWTEST_F(WddmTest, givenOpenSharedHandleWhenZeroAllocationsThenReturnNull) { EXPECT_EQ(false, ret); } -using WddmReserveAddressTest = WddmTestSingle; - -HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsSuccessfulThenReturnReserveAddress) { - std::unique_ptr wddm(new WddmMockReserveAddress()); - size_t size = 0x1000; - void *reserve = nullptr; - - bool ret = wddm->init(); - EXPECT_TRUE(ret); - - wddm->returnGood = 1; - - ret = wddm->reserveValidAddressRange(size, reserve); - uintptr_t expectedReserve = wddm->virtualAllocAddress; - EXPECT_TRUE(ret); - EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); - wddm->releaseReservedAddress(reserve); -} - -HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsNullThenReturnNull) { - std::unique_ptr wddm(new WddmMockReserveAddress()); - size_t size = 0x1000; - void *reserve = nullptr; - - bool ret = wddm->init(); - EXPECT_TRUE(ret); - uintptr_t expectedReserve = 0; - ret = wddm->reserveValidAddressRange(size, reserve); - EXPECT_FALSE(ret); - EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); -} - -HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsInvalidSecondSuccessfulThenReturnSecond) { - std::unique_ptr wddm(new WddmMockReserveAddress()); - size_t size = 0x1000; - void *reserve = nullptr; - - bool ret = wddm->init(); - EXPECT_TRUE(ret); - - wddm->returnInvalidCount = 1; - - ret = wddm->reserveValidAddressRange(size, reserve); - uintptr_t expectedReserve = wddm->virtualAllocAddress; - EXPECT_TRUE(ret); - EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); - wddm->releaseReservedAddress(reserve); -} - -HWTEST_F(WddmReserveAddressTest, givenWddmWhenSecondIsInvalidThirdSuccessfulThenReturnThird) { - std::unique_ptr wddm(new WddmMockReserveAddress()); - size_t size = 0x1000; - void *reserve = nullptr; - - bool ret = wddm->init(); - EXPECT_TRUE(ret); - - wddm->returnInvalidCount = 2; - - ret = wddm->reserveValidAddressRange(size, reserve); - uintptr_t expectedReserve = wddm->virtualAllocAddress; - EXPECT_TRUE(ret); - EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); - wddm->releaseReservedAddress(reserve); -} - -HWTEST_F(WddmReserveAddressTest, givenWddmWhenFirstIsInvalidSecondNullThenReturnSecondNull) { - std::unique_ptr wddm(new WddmMockReserveAddress()); - size_t size = 0x1000; - void *reserve = nullptr; - - bool ret = wddm->init(); - EXPECT_TRUE(ret); - - wddm->returnInvalidCount = 2; - wddm->returnNullCount = 1; - uintptr_t expectedReserve = 0; - - ret = wddm->reserveValidAddressRange(size, reserve); - EXPECT_FALSE(ret); - EXPECT_EQ(expectedReserve, reinterpret_cast(reserve)); -} - HWTEST_F(WddmTest, givenReadOnlyMemoryWhenCreateAllocationFailsWithNoVideoMemoryThenCorrectStatusIsReturned) { class MockCreateAllocation { public: diff --git a/unit_tests/os_interface/windows/wddm_tests.h b/unit_tests/os_interface/windows/wddm_tests.h deleted file mode 100644 index 585c7e8744..0000000000 --- a/unit_tests/os_interface/windows/wddm_tests.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 - 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: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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. - */ - -#pragma once - -#include "unit_tests/os_interface/windows/wddm_fixture.h" -#include "runtime/command_stream/preemption.h" - -#include "test.h" - -using namespace OCLRT; - -OsLibrary *setAdapterInfo(const PLATFORM *platform, const GT_SYSTEM_INFO *gtSystemInfo); - -typedef Test WddmTest; -typedef Test WddmTestWithMockGdiDll; - -typedef Test WddmInstrumentationTest; - -typedef ::testing::Test WddmTestSingle; - -class WddmPreemptionTests : public WddmTestWithMockGdiDll { - public: - void SetUp() override { - WddmTestWithMockGdiDll::SetUp(); - const HardwareInfo hwInfo = *platformDevices[0]; - memcpy(&hwInfoTest, &hwInfo, sizeof(hwInfoTest)); - dbgRestorer = new DebugManagerStateRestore(); - } - - void TearDown() override { - delete dbgRestorer; - WddmTestWithMockGdiDll::TearDown(); - } - - template - void createAndInitWddm(unsigned int forceReturnPreemptionRegKeyValue) { - wddm.reset(static_cast(Wddm::createWddm())); - auto regReader = new RegistryReaderMock(); - wddm->registryReader.reset(regReader); - regReader->forceRetValue = forceReturnPreemptionRegKeyValue; - PreemptionMode preemptionMode = PreemptionHelper::getDefaultPreemptionMode(hwInfoTest); - wddm->setPreemptionMode(preemptionMode); - wddm->init(); - } - - DebugManagerStateRestore *dbgRestorer = nullptr; - HardwareInfo hwInfoTest; -};