Wddm interface [7/n]: Add 2.3 interface with HW queue support

Change-Id: Ia0e829b8616b7060e39170aea0f1d2f123d73399
This commit is contained in:
Dunajski, Bartosz 2018-05-18 10:18:16 +02:00 committed by sys_ocldev
parent 39d55e5257
commit 71b844f522
27 changed files with 560 additions and 44 deletions

View File

@ -56,7 +56,7 @@ set(RUNTIME_SRCS_DLL_WINDOWS
${IGDRCL_SOURCE_DIR}/runtime/gmm_helper/page_table_mngr.cpp ${IGDRCL_SOURCE_DIR}/runtime/gmm_helper/page_table_mngr.cpp
${IGDRCL_SOURCE_DIR}/runtime/os_interface/windows/sys_calls.cpp ${IGDRCL_SOURCE_DIR}/runtime/os_interface/windows/sys_calls.cpp
${IGDRCL_SOURCE_DIR}/runtime/os_interface/windows/wddm/wddm_calls.cpp ${IGDRCL_SOURCE_DIR}/runtime/os_interface/windows/wddm/wddm_calls.cpp
${IGDRCL_SOURCE_DIR}/runtime/os_interface/windows/wddm${BRANCH_DIR_SUFFIX}/wddm_create.cpp ${IGDRCL_SOURCE_DIR}/runtime/os_interface/windows/wddm/wddm_create.cpp
) )
target_sources(${NEO_DYNAMIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_DLL_BASE}) target_sources(${NEO_DYNAMIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_DLL_BASE})

View File

@ -87,7 +87,6 @@ DECLARE_DEBUG_VARIABLE(int32_t, CsrDispatchMode, 0, "Chooses DispatchMode for Cs
/*DRIVER TOGGLES*/ /*DRIVER TOGGLES*/
DECLARE_DEBUG_VARIABLE(int32_t, ForceOCLVersion, 0, "Force specific OpenCL API version") DECLARE_DEBUG_VARIABLE(int32_t, ForceOCLVersion, 0, "Force specific OpenCL API version")
DECLARE_DEBUG_VARIABLE(int32_t, ForcePreemptionMode, -1, "Keep this variable in sync with PreemptionMode enum. -1 - devices default mode, 1 - disable, 2 - midBatch, 3 - threadGroup, 4 - midThread") DECLARE_DEBUG_VARIABLE(int32_t, ForcePreemptionMode, -1, "Keep this variable in sync with PreemptionMode enum. -1 - devices default mode, 1 - disable, 2 - midBatch, 3 - threadGroup, 4 - midThread")
DECLARE_DEBUG_VARIABLE(int32_t, ForceWddmInterfaceVersion, 0, "Windows only. Force internal interface version. 0 is default value. Example: set 20 to force 2.0")
DECLARE_DEBUG_VARIABLE(int32_t, NodeOrdinal, -1, "-1: default do not override, 0: ENGINE_RCS") DECLARE_DEBUG_VARIABLE(int32_t, NodeOrdinal, -1, "-1: default do not override, 0: ENGINE_RCS")
DECLARE_DEBUG_VARIABLE(int32_t, OverrideThreadArbitrationPolicy, -1, "-1 (dont override) or any valid config (0: Age Based, 1: Round Robin)") DECLARE_DEBUG_VARIABLE(int32_t, OverrideThreadArbitrationPolicy, -1, "-1 (dont override) or any valid config (0: Age Based, 1: Round Robin)")
DECLARE_DEBUG_VARIABLE(bool, HwQueueSupported, false, "Windows only. Pass flag to KMD during Wddm Context creation") DECLARE_DEBUG_VARIABLE(bool, HwQueueSupported, false, "Windows only. Pass flag to KMD during Wddm Context creation")

View File

@ -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 * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -31,6 +31,17 @@ Gdi::Gdi() : gdiDll(Os::gdiDllName),
} }
} }
bool Gdi::setupHwQueueProcAddresses() {
createHwQueue = reinterpret_cast<PFND3DKMT_CREATEHWQUEUE>(gdiDll.getProcAddress("D3DKMTCreateHwQueue"));
destroyHwQueue = reinterpret_cast<PFND3DKMT_DESTROYHWQUEUE>(gdiDll.getProcAddress("D3DKMTDestroyHwQueue"));
submitCommandToHwQueue = reinterpret_cast<PFND3DKMT_SUBMITCOMMANDTOHWQUEUE>(gdiDll.getProcAddress("D3DKMTSubmitCommandToHwQueue"));
if (!createHwQueue || !destroyHwQueue || !submitCommandToHwQueue) {
return false;
}
return true;
}
bool Gdi::getAllProcAddresses() { bool Gdi::getAllProcAddresses() {
openAdapterFromHdc = reinterpret_cast<PFND3DKMT_OPENADAPTERFROMHDC>(gdiDll.getProcAddress("D3DKMTOpenAdapterFromHdc")); openAdapterFromHdc = reinterpret_cast<PFND3DKMT_OPENADAPTERFROMHDC>(gdiDll.getProcAddress("D3DKMTOpenAdapterFromHdc"));
openAdapterFromLuid = reinterpret_cast<PFND3DKMT_OPENADAPTERFROMLUID>(gdiDll.getProcAddress("D3DKMTOpenAdapterFromLuid")); openAdapterFromLuid = reinterpret_cast<PFND3DKMT_OPENADAPTERFROMLUID>(gdiDll.getProcAddress("D3DKMTOpenAdapterFromLuid"));

View File

@ -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 * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -79,6 +79,11 @@ class Gdi {
ThkWrapper<OCL_RUNTIME_PROFILING, IN D3DKMT_REGISTERTRIMNOTIFICATION *> registerTrimNotification; ThkWrapper<OCL_RUNTIME_PROFILING, IN D3DKMT_REGISTERTRIMNOTIFICATION *> registerTrimNotification;
ThkWrapper<OCL_RUNTIME_PROFILING, IN D3DKMT_UNREGISTERTRIMNOTIFICATION *> unregisterTrimNotification; ThkWrapper<OCL_RUNTIME_PROFILING, IN D3DKMT_UNREGISTERTRIMNOTIFICATION *> unregisterTrimNotification;
// HW queue
ThkWrapper<OCL_RUNTIME_PROFILING, IN OUT D3DKMT_CREATEHWQUEUE *> createHwQueue;
ThkWrapper<OCL_RUNTIME_PROFILING, IN CONST D3DKMT_DESTROYHWQUEUE *> destroyHwQueue;
ThkWrapper<OCL_RUNTIME_PROFILING, IN CONST D3DKMT_SUBMITCOMMANDTOHWQUEUE *> submitCommandToHwQueue;
// For debug purposes // For debug purposes
ThkWrapper<OCL_RUNTIME_PROFILING, IN OUT D3DKMT_GETDEVICESTATE *> getDeviceState; ThkWrapper<OCL_RUNTIME_PROFILING, IN OUT D3DKMT_GETDEVICESTATE *> getDeviceState;
@ -86,8 +91,10 @@ class Gdi {
return initialized; return initialized;
} }
MOCKABLE_VIRTUAL bool setupHwQueueProcAddresses();
protected: protected:
virtual bool getAllProcAddresses(); MOCKABLE_VIRTUAL bool getAllProcAddresses();
bool initialized; bool initialized;
private: private:

View File

@ -72,6 +72,9 @@ enum SystemCallsIds {
SYSTIMER_ID_UNREGISTERTRIMNOTIFICATION = 44, SYSTIMER_ID_UNREGISTERTRIMNOTIFICATION = 44,
SYSTIMER_ID_QUERYRESOURCEINFOFROMNTHANDLE = 45, SYSTIMER_ID_QUERYRESOURCEINFOFROMNTHANDLE = 45,
SYSTIMER_ID_OPENRESOURCEFROMNTHANDLE = 46, SYSTIMER_ID_OPENRESOURCEFROMNTHANDLE = 46,
SYSTIMER_ID_CREATEHWQUEUE = 47,
SYSTIMER_ID_DESTROYHWQUEUE = 48,
SYSTIMER_ID_SUBMITCOMMANDTOHWQUEUE = 49,
SYSTIMER_ID_SLEEP_0 = 100, SYSTIMER_ID_SLEEP_0 = 100,
SYSTIMER_ID_WAIT_FOR_KMD = 200, SYSTIMER_ID_WAIT_FOR_KMD = 200,
@ -172,5 +175,8 @@ class ThkWrapper {
GET_ID(D3DKMT_UNREGISTERTRIMNOTIFICATION *, SYSTIMER_ID_UNREGISTERTRIMNOTIFICATION) GET_ID(D3DKMT_UNREGISTERTRIMNOTIFICATION *, SYSTIMER_ID_UNREGISTERTRIMNOTIFICATION)
GET_ID(D3DKMT_OPENRESOURCEFROMNTHANDLE *, SYSTIMER_ID_OPENRESOURCEFROMNTHANDLE) GET_ID(D3DKMT_OPENRESOURCEFROMNTHANDLE *, SYSTIMER_ID_OPENRESOURCEFROMNTHANDLE)
GET_ID(D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE *, SYSTIMER_ID_QUERYRESOURCEINFOFROMNTHANDLE) GET_ID(D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE *, SYSTIMER_ID_QUERYRESOURCEINFOFROMNTHANDLE)
GET_ID(D3DKMT_CREATEHWQUEUE *, SYSTIMER_ID_CREATEHWQUEUE)
GET_ID(CONST D3DKMT_DESTROYHWQUEUE *, SYSTIMER_ID_DESTROYHWQUEUE)
GET_ID(CONST D3DKMT_SUBMITCOMMANDTOHWQUEUE *, SYSTIMER_ID_SUBMITCOMMANDTOHWQUEUE)
}; };
} // namespace OCLRT } // namespace OCLRT

View File

@ -62,8 +62,7 @@ Wddm::Wddm() : initialized(false),
pagingFenceAddress(nullptr), pagingFenceAddress(nullptr),
currentPagingFenceValue(0), currentPagingFenceValue(0),
hwContextId(0), hwContextId(0),
trimCallbackHandle(nullptr), trimCallbackHandle(nullptr) {
wddmInterfaceVersion(WddmInterfaceVersion::Wddm20) {
featureTable.reset(new FeatureTable()); featureTable.reset(new FeatureTable());
waTable.reset(new WorkaroundTable()); waTable.reset(new WorkaroundTable());
gtSystemInfo.reset(new GT_SYSTEM_INFO); gtSystemInfo.reset(new GT_SYSTEM_INFO);
@ -235,12 +234,9 @@ bool Wddm::createMonitoredFence() {
DEBUG_BREAK_IF(STATUS_SUCCESS != Status); DEBUG_BREAK_IF(STATUS_SUCCESS != Status);
monitoredFence.currentFenceValue = 1; resetMonitoredFenceParams(CreateSynchronizationObject.hSyncObject,
monitoredFence.fenceHandle = CreateSynchronizationObject.hSyncObject; reinterpret_cast<uint64_t *>(CreateSynchronizationObject.Info.MonitoredFence.FenceValueCPUVirtualAddress),
monitoredFence.cpuAddress = reinterpret_cast<UINT64 *>(CreateSynchronizationObject.Info.MonitoredFence.FenceValueCPUVirtualAddress); CreateSynchronizationObject.Info.MonitoredFence.FenceValueGPUVirtualAddress);
monitoredFence.lastSubmittedFence = 0;
monitoredFence.gpuAddress = CreateSynchronizationObject.Info.MonitoredFence.FenceValueGPUVirtualAddress;
return Status == STATUS_SUCCESS; return Status == STATUS_SUCCESS;
} }
@ -728,7 +724,7 @@ bool Wddm::createContext() {
CreateContext.EngineAffinity = 0; CreateContext.EngineAffinity = 0;
CreateContext.Flags.NullRendering = static_cast<UINT>(DebugManager.flags.EnableNullHardware.get()); CreateContext.Flags.NullRendering = static_cast<UINT>(DebugManager.flags.EnableNullHardware.get());
CreateContext.Flags.HwQueueSupported = static_cast<UINT>(DebugManager.flags.HwQueueSupported.get()); CreateContext.Flags.HwQueueSupported = hwQueuesSupported();
if (preemptionMode >= PreemptionMode::MidBatch) { if (preemptionMode >= PreemptionMode::MidBatch) {
CreateContext.Flags.DisableGpuTimeout = readEnablePreemptionRegKey(); CreateContext.Flags.DisableGpuTimeout = readEnablePreemptionRegKey();
@ -951,8 +947,17 @@ bool Wddm::reserveValidAddressRange(size_t size, void *&reservedMem) {
void *Wddm::virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned long type) { void *Wddm::virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned long type) {
return virtualAllocFnc(inPtr, size, flags, type); return virtualAllocFnc(inPtr, size, flags, type);
} }
int Wddm::virtualFree(void *ptr, size_t size, unsigned long flags) { int Wddm::virtualFree(void *ptr, size_t size, unsigned long flags) {
return virtualFreeFnc(ptr, size, flags); return virtualFreeFnc(ptr, size, flags);
} }
void Wddm::resetMonitoredFenceParams(D3DKMT_HANDLE &handle, uint64_t *cpuAddress, D3DGPU_VIRTUAL_ADDRESS &gpuAddress) {
monitoredFence.lastSubmittedFence = 0;
monitoredFence.currentFenceValue = 1;
monitoredFence.fenceHandle = handle;
monitoredFence.cpuAddress = cpuAddress;
monitoredFence.gpuAddress = gpuAddress;
}
} // namespace OCLRT } // namespace OCLRT

View File

@ -51,6 +51,7 @@ struct KmDafListener;
namespace WddmInterfaceVersion { namespace WddmInterfaceVersion {
constexpr uint32_t Wddm20 = 20; constexpr uint32_t Wddm20 = 20;
constexpr uint32_t Wddm23 = 23;
} // namespace WddmInterfaceVersion } // namespace WddmInterfaceVersion
class Wddm { class Wddm {
@ -59,7 +60,6 @@ class Wddm {
typedef void(WINAPI *GetSystemInfoFcn)(SYSTEM_INFO *pSystemInfo); typedef void(WINAPI *GetSystemInfoFcn)(SYSTEM_INFO *pSystemInfo);
typedef BOOL(WINAPI *VirtualFreeFcn)(LPVOID ptr, SIZE_T size, DWORD flags); typedef BOOL(WINAPI *VirtualFreeFcn)(LPVOID ptr, SIZE_T size, DWORD flags);
typedef LPVOID(WINAPI *VirtualAllocFcn)(LPVOID inPtr, SIZE_T size, DWORD flags, DWORD type); typedef LPVOID(WINAPI *VirtualAllocFcn)(LPVOID inPtr, SIZE_T size, DWORD flags, DWORD type);
const uint32_t wddmInterfaceVersion;
virtual ~Wddm(); virtual ~Wddm();
@ -72,6 +72,7 @@ class Wddm {
bool mapGpuVirtualAddress(WddmAllocation *allocation, void *cpuPtr, uint64_t size, bool allocation32bit, bool use64kbPages, bool useHeap1); bool mapGpuVirtualAddress(WddmAllocation *allocation, void *cpuPtr, uint64_t size, bool allocation32bit, bool use64kbPages, bool useHeap1);
bool mapGpuVirtualAddress(AllocationStorageData *allocationStorageData, bool allocation32bit, bool use64kbPages); bool mapGpuVirtualAddress(AllocationStorageData *allocationStorageData, bool allocation32bit, bool use64kbPages);
MOCKABLE_VIRTUAL bool createContext(); MOCKABLE_VIRTUAL bool createContext();
virtual bool createHwQueue() { return false; }
MOCKABLE_VIRTUAL bool freeGpuVirtualAddres(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size); MOCKABLE_VIRTUAL bool freeGpuVirtualAddres(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size);
MOCKABLE_VIRTUAL NTSTATUS createAllocation(WddmAllocation *alloc); MOCKABLE_VIRTUAL NTSTATUS createAllocation(WddmAllocation *alloc);
MOCKABLE_VIRTUAL bool createAllocation64k(WddmAllocation *alloc); MOCKABLE_VIRTUAL bool createAllocation64k(WddmAllocation *alloc);
@ -87,7 +88,7 @@ class Wddm {
MOCKABLE_VIRTUAL bool destroyContext(D3DKMT_HANDLE context); MOCKABLE_VIRTUAL bool destroyContext(D3DKMT_HANDLE context);
MOCKABLE_VIRTUAL bool queryAdapterInfo(); MOCKABLE_VIRTUAL bool queryAdapterInfo();
MOCKABLE_VIRTUAL bool submit(uint64_t commandBuffer, size_t size, void *commandHeader); virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader);
MOCKABLE_VIRTUAL bool waitOnGPU(); MOCKABLE_VIRTUAL bool waitOnGPU();
MOCKABLE_VIRTUAL bool waitFromCpu(uint64_t lastFenceValue); MOCKABLE_VIRTUAL bool waitFromCpu(uint64_t lastFenceValue);
@ -207,12 +208,14 @@ class Wddm {
bool destroyPagingQueue(); bool destroyPagingQueue();
bool destroyDevice(); bool destroyDevice();
bool closeAdapter(); bool closeAdapter();
bool createMonitoredFence(); virtual bool createMonitoredFence();
void getDeviceState(); void getDeviceState();
void handleCompletion(); void handleCompletion();
unsigned int readEnablePreemptionRegKey(); unsigned int readEnablePreemptionRegKey();
bool initGmmContext(); bool initGmmContext();
void destroyGmmContext(); void destroyGmmContext();
void resetMonitoredFenceParams(D3DKMT_HANDLE &handle, uint64_t *cpuAddress, D3DGPU_VIRTUAL_ADDRESS &gpuAddress);
virtual const bool hwQueuesSupported() const { return false; }
static CreateDXGIFactoryFcn createDxgiFactory; static CreateDXGIFactoryFcn createDxgiFactory;
static GetSystemInfoFcn getSystemInfo; static GetSystemInfoFcn getSystemInfo;

View File

@ -61,6 +61,9 @@ bool Wddm::init() {
if (!createContext()) { if (!createContext()) {
return false; return false;
} }
if (hwQueuesSupported() && !createHwQueue()) {
return false;
}
if (!createMonitoredFence()) { if (!createMonitoredFence()) {
return false; return false;
} }

View File

@ -0,0 +1,98 @@
/*
* 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/os_interface/windows/gdi_interface.h"
#include "runtime/os_interface/windows/wddm/wddm23.h"
namespace OCLRT {
Wddm23::Wddm23() : Wddm20() {}
Wddm23::~Wddm23() {
destroyHwQueue();
}
bool Wddm23::createHwQueue() {
D3DKMT_CREATEHWQUEUE createHwQueue = {};
if (!gdi->setupHwQueueProcAddresses()) {
return false;
}
createHwQueue.hHwContext = context;
if (preemptionMode >= PreemptionMode::MidBatch) {
createHwQueue.Flags.DisableGpuTimeout = readEnablePreemptionRegKey();
}
auto status = gdi->createHwQueue(&createHwQueue);
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
hwQueueHandle = createHwQueue.hHwQueue;
resetMonitoredFenceParams(createHwQueue.hHwQueueProgressFence,
reinterpret_cast<uint64_t *>(createHwQueue.HwQueueProgressFenceCPUVirtualAddress),
createHwQueue.HwQueueProgressFenceGPUVirtualAddress);
return status == STATUS_SUCCESS;
}
void Wddm23::destroyHwQueue() {
if (hwQueueHandle) {
D3DKMT_DESTROYHWQUEUE destroyHwQueue = {};
destroyHwQueue.hHwQueue = hwQueueHandle;
auto status = gdi->destroyHwQueue(&destroyHwQueue);
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
}
}
bool Wddm23::submit(uint64_t commandBuffer, size_t size, void *commandHeader) {
D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommand = {};
submitCommand.hHwQueue = hwQueueHandle;
submitCommand.HwQueueProgressFenceId = monitoredFence.fenceHandle;
submitCommand.CommandBuffer = commandBuffer;
submitCommand.CommandLength = static_cast<UINT>(size);
COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast<COMMAND_BUFFER_HEADER *>(commandHeader);
pHeader->MonitorFenceVA = monitoredFence.gpuAddress;
pHeader->MonitorFenceValue = monitoredFence.currentFenceValue;
submitCommand.pPrivateDriverData = commandHeader;
submitCommand.PrivateDriverDataSize = sizeof(COMMAND_BUFFER_HEADER);
if (currentPagingFenceValue > *pagingFenceAddress && !waitOnGPU()) {
return false;
}
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "currentFenceValue =", monitoredFence.currentFenceValue);
auto status = gdi->submitCommandToHwQueue(&submitCommand);
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
if (STATUS_SUCCESS == status) {
monitoredFence.lastSubmittedFence = monitoredFence.currentFenceValue;
monitoredFence.currentFenceValue++;
}
getDeviceState();
return status == STATUS_SUCCESS;
}
} // namespace OCLRT

View File

@ -0,0 +1,41 @@
/*
* 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/wddm.h"
namespace OCLRT {
class Wddm23 : public Wddm20 {
protected:
friend Wddm20;
Wddm23();
~Wddm23();
bool createHwQueue() override;
void destroyHwQueue();
bool createMonitoredFence() override { return true; }
const bool hwQueuesSupported() const override { return true; }
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override;
D3DKMT_HANDLE hwQueueHandle = 0;
};
} // namespace OCLRT

View File

@ -20,10 +20,24 @@
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "runtime/os_interface/debug_settings_manager.h"
#include "runtime/os_interface/windows/wddm/wddm.h" #include "runtime/os_interface/windows/wddm/wddm.h"
#include "runtime/os_interface/windows/wddm/wddm23.h"
namespace OCLRT { namespace OCLRT {
Wddm *Wddm::createWddm(uint32_t interfaceVersion) { Wddm *Wddm::createWddm(uint32_t interfaceVersion) {
return new Wddm20(); if (DebugManager.flags.HwQueueSupported.get()) {
interfaceVersion = WddmInterfaceVersion::Wddm23;
}
switch (interfaceVersion) {
case WddmInterfaceVersion::Wddm20:
return new Wddm20();
case WddmInterfaceVersion::Wddm23:
return new Wddm23();
default:
UNRECOVERABLE_IF(true);
return nullptr;
}
} }
} // namespace OCLRT } // namespace OCLRT

View File

@ -30,11 +30,11 @@ namespace OCLRT {
constexpr uintptr_t windowsMinAddress = 0x200000; constexpr uintptr_t windowsMinAddress = 0x200000;
struct MonitoredFence { struct MonitoredFence {
D3DKMT_HANDLE fenceHandle; D3DKMT_HANDLE fenceHandle = 0;
D3DGPU_VIRTUAL_ADDRESS gpuAddress; D3DGPU_VIRTUAL_ADDRESS gpuAddress = 0;
volatile uint64_t *cpuAddress; volatile uint64_t *cpuAddress = nullptr;
volatile uint64_t currentFenceValue; volatile uint64_t currentFenceValue = 0;
uint64_t lastSubmittedFence; uint64_t lastSubmittedFence = 0;
}; };
} // namespace OCLRT } // namespace OCLRT

View File

@ -32,7 +32,7 @@ set(IGDRCL_SRCS_tests_local
) )
if(WIN32) if(WIN32)
list(APPEND IGDRCL_SRCS_tests_local ${IGDRCL_SOURCE_DIR}/unit_tests/os_interface/windows${BRANCH_DIR_SUFFIX}/wddm_create.cpp) list(APPEND IGDRCL_SRCS_tests_local ${IGDRCL_SOURCE_DIR}/unit_tests/os_interface/windows/wddm_create.cpp)
endif() endif()
add_subdirectory(libult) add_subdirectory(libult)

View File

@ -49,7 +49,7 @@ target_sources(igdrcl_aub_tests PRIVATE
if(WIN32) if(WIN32)
target_sources(igdrcl_aub_tests PRIVATE target_sources(igdrcl_aub_tests PRIVATE
${IGDRCL_SOURCE_DIR}/runtime/gmm_helper/gmm_memory.cpp ${IGDRCL_SOURCE_DIR}/runtime/gmm_helper/gmm_memory.cpp
${IGDRCL_SOURCE_DIR}/unit_tests/os_interface/windows${BRANCH_DIR_SUFFIX}/wddm_create.cpp ${IGDRCL_SOURCE_DIR}/unit_tests/os_interface/windows/wddm_create.cpp
) )
endif() endif()

View File

@ -62,6 +62,9 @@ D3DKMTEvict
D3DKMTGetDeviceState D3DKMTGetDeviceState
D3DKMTRegisterTrimNotification D3DKMTRegisterTrimNotification
D3DKMTUnregisterTrimNotification D3DKMTUnregisterTrimNotification
D3DKMTCreateHwQueue
D3DKMTDestroyHwQueue
D3DKMTSubmitCommandToHwQueue
MockSetAdapterInfo MockSetAdapterInfo
MockSetSizes MockSetSizes
GetMockSizes GetMockSizes
@ -74,3 +77,6 @@ getAdapterInfoAddress
getLastCallMapGpuVaArg getLastCallMapGpuVaArg
setMapGpuVaFailConfig setMapGpuVaFailConfig
getCreateContextData getCreateContextData
getCreateHwQueueData
getDestroyHwQueueData
getSubmitCommandToHwQueueData

View File

@ -387,6 +387,31 @@ NTSTATUS __stdcall D3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESYNCHR
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static D3DKMT_CREATEHWQUEUE createHwQueueData = {};
NTSTATUS __stdcall D3DKMTCreateHwQueue(IN OUT D3DKMT_CREATEHWQUEUE *createHwQueue) {
createHwQueue->hHwQueueProgressFence = 1;
createHwQueue->HwQueueProgressFenceCPUVirtualAddress = reinterpret_cast<void *>(2);
createHwQueue->HwQueueProgressFenceGPUVirtualAddress = 3;
createHwQueue->hHwQueue = 4;
createHwQueueData = *createHwQueue;
return STATUS_SUCCESS;
}
static D3DKMT_DESTROYHWQUEUE destroyHwQueueData = {};
NTSTATUS __stdcall D3DKMTDestroyHwQueue(IN CONST D3DKMT_DESTROYHWQUEUE *destroyHwQueue) {
destroyHwQueueData = *destroyHwQueue;
return STATUS_SUCCESS;
}
static D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommandToHwQueueData = {};
NTSTATUS __stdcall D3DKMTSubmitCommandToHwQueue(IN CONST D3DKMT_SUBMITCOMMANDTOHWQUEUE *submitCommandToHwQueue) {
submitCommandToHwQueueData = *submitCommandToHwQueue;
return STATUS_SUCCESS;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@ -441,3 +466,15 @@ void setMapGpuVaFailConfig(uint32_t count, uint32_t max) {
D3DKMT_CREATECONTEXTVIRTUAL *getCreateContextData() { D3DKMT_CREATECONTEXTVIRTUAL *getCreateContextData() {
return &createContextData; return &createContextData;
} }
D3DKMT_CREATEHWQUEUE *getCreateHwQueueData() {
return &createHwQueueData;
}
D3DKMT_DESTROYHWQUEUE *getDestroyHwQueueData() {
return &destroyHwQueueData;
}
D3DKMT_SUBMITCOMMANDTOHWQUEUE *getSubmitCommandToHwQueueData() {
return &submitCommandToHwQueueData;
}

View File

@ -83,3 +83,6 @@ ADAPTER_INFO *getAdapterInfoAddress();
D3DDDI_MAPGPUVIRTUALADDRESS *getLastCallMapGpuVaArg(); D3DDDI_MAPGPUVIRTUALADDRESS *getLastCallMapGpuVaArg();
void setMapGpuVaFailConfig(uint32_t count, uint32_t max); void setMapGpuVaFailConfig(uint32_t count, uint32_t max);
D3DKMT_CREATECONTEXTVIRTUAL *getCreateContextData(); D3DKMT_CREATECONTEXTVIRTUAL *getCreateContextData();
D3DKMT_CREATEHWQUEUE *getCreateHwQueueData();
D3DKMT_DESTROYHWQUEUE *getDestroyHwQueueData();
D3DKMT_SUBMITCOMMANDTOHWQUEUE *getSubmitCommandToHwQueueData();

View File

@ -125,6 +125,11 @@ bool WddmMock::createContext() {
return createContextResult.success = Wddm::createContext(); return createContextResult.success = Wddm::createContext();
} }
bool WddmMock::createHwQueue() {
createHwQueueResult.called++;
return createHwQueueResult.success = Wddm::createHwQueue();
}
bool WddmMock::destroyContext(D3DKMT_HANDLE context) { bool WddmMock::destroyContext(D3DKMT_HANDLE context) {
destroyContextResult.called++; destroyContextResult.called++;
return destroyContextResult.success = Wddm::destroyContext(context); return destroyContextResult.success = Wddm::destroyContext(context);

View File

@ -49,11 +49,13 @@ class WddmMock : public Wddm20 {
public: public:
using Wddm::adapter; using Wddm::adapter;
using Wddm::context; using Wddm::context;
using Wddm::createHwQueue;
using Wddm::createMonitoredFence; using Wddm::createMonitoredFence;
using Wddm::device; using Wddm::device;
using Wddm::gdi; using Wddm::gdi;
using Wddm::getSystemInfo; using Wddm::getSystemInfo;
using Wddm::gmmMemory; using Wddm::gmmMemory;
using Wddm::hwQueuesSupported;
using Wddm::pagingQueue; using Wddm::pagingQueue;
WddmMock() : Wddm20(){}; WddmMock() : Wddm20(){};
@ -69,6 +71,7 @@ class WddmMock : public Wddm20 {
bool destroyAllocation(WddmAllocation *alloc); bool destroyAllocation(WddmAllocation *alloc);
bool openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) override; bool openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) override;
bool createContext() override; bool createContext() override;
bool createHwQueue() override;
bool destroyContext(D3DKMT_HANDLE context) override; bool destroyContext(D3DKMT_HANDLE context) override;
bool queryAdapterInfo() override; bool queryAdapterInfo() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override; bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override;
@ -118,6 +121,7 @@ class WddmMock : public Wddm20 {
WddmMockHelpers::CallResult waitFromCpuResult; WddmMockHelpers::CallResult waitFromCpuResult;
WddmMockHelpers::CallResult releaseReservedAddressResult; WddmMockHelpers::CallResult releaseReservedAddressResult;
WddmMockHelpers::CallResult reserveValidAddressRangeResult; WddmMockHelpers::CallResult reserveValidAddressRangeResult;
WddmMockHelpers::CallResult createHwQueueResult;
NTSTATUS createAllocationStatus; NTSTATUS createAllocationStatus;
bool mapGpuVaStatus; bool mapGpuVaStatus;

View File

@ -0,0 +1,59 @@
/*
* 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/wddm23.h"
namespace OCLRT {
class WddmMock23 : public Wddm23 {
public:
using Wddm23::context;
using Wddm23::createHwQueue;
using Wddm23::createMonitoredFence;
using Wddm23::currentPagingFenceValue;
using Wddm23::destroyHwQueue;
using Wddm23::gdi;
using Wddm23::hwQueueHandle;
using Wddm23::hwQueuesSupported;
using Wddm23::pagingFenceAddress;
using Wddm23::submit;
WddmMock23() : Wddm23(){};
bool waitOnGPU() override {
waitOnGPUCalled++;
return true;
}
bool createHwQueue() override {
createHwQueueCalled++;
createHwQueueResult = forceCreateHwQueueFail ? false : Wddm23::createHwQueue();
return createHwQueueResult;
}
uint32_t waitOnGPUCalled = 0;
uint32_t createHwQueueCalled = 0;
bool forceCreateHwQueueFail = false;
bool createHwQueueResult = false;
};
} // namespace OCLRT

View File

@ -44,7 +44,7 @@ target_link_libraries(igdrcl_mt_tests igdrcl_mocks ${IGDRCL_EXTRA_LIBS})
if(WIN32) if(WIN32)
target_sources(igdrcl_mt_tests PRIVATE target_sources(igdrcl_mt_tests PRIVATE
${IGDRCL_SOURCE_DIR}/unit_tests/os_interface/windows${BRANCH_DIR_SUFFIX}/wddm_create.cpp ${IGDRCL_SOURCE_DIR}/unit_tests/os_interface/windows/wddm_create.cpp
) )
endif() endif()

View File

@ -51,10 +51,17 @@ struct GdiDllFixture {
setMapGpuVaFailConfigFcn = reinterpret_cast<decltype(&setMapGpuVaFailConfig)>(mockGdiDll->getProcAddress("setMapGpuVaFailConfig")); setMapGpuVaFailConfigFcn = reinterpret_cast<decltype(&setMapGpuVaFailConfig)>(mockGdiDll->getProcAddress("setMapGpuVaFailConfig"));
setMapGpuVaFailConfigFcn(0, 0); setMapGpuVaFailConfigFcn(0, 0);
getCreateContextDataFcn = reinterpret_cast<decltype(&getCreateContextData)>(mockGdiDll->getProcAddress("getCreateContextData")); getCreateContextDataFcn = reinterpret_cast<decltype(&getCreateContextData)>(mockGdiDll->getProcAddress("getCreateContextData"));
getCreateHwQueueDataFcn = reinterpret_cast<decltype(&getCreateHwQueueData)>(mockGdiDll->getProcAddress("getCreateHwQueueData"));
getDestroyHwQueueDataFcn = reinterpret_cast<decltype(&getDestroyHwQueueData)>(mockGdiDll->getProcAddress("getDestroyHwQueueData"));
getSubmitCommandToHwQueueDataFcn =
reinterpret_cast<decltype(&getSubmitCommandToHwQueueData)>(mockGdiDll->getProcAddress("getSubmitCommandToHwQueueData"));
setMockLastDestroyedResHandleFcn((D3DKMT_HANDLE)0); setMockLastDestroyedResHandleFcn((D3DKMT_HANDLE)0);
} }
virtual void TearDown() { virtual void TearDown() {
*getCreateHwQueueDataFcn() = {};
*getDestroyHwQueueDataFcn() = {};
*getSubmitCommandToHwQueueDataFcn() = {};
setMapGpuVaFailConfigFcn(0, 0); setMapGpuVaFailConfigFcn(0, 0);
} }
@ -71,4 +78,7 @@ struct GdiDllFixture {
decltype(&getLastCallMapGpuVaArg) getLastCallMapGpuVaArgFcn = nullptr; decltype(&getLastCallMapGpuVaArg) getLastCallMapGpuVaArgFcn = nullptr;
decltype(&setMapGpuVaFailConfig) setMapGpuVaFailConfigFcn = nullptr; decltype(&setMapGpuVaFailConfig) setMapGpuVaFailConfigFcn = nullptr;
decltype(&getCreateContextData) getCreateContextDataFcn = nullptr; decltype(&getCreateContextData) getCreateContextDataFcn = nullptr;
decltype(&getCreateHwQueueData) getCreateHwQueueDataFcn = nullptr;
decltype(&getDestroyHwQueueData) getDestroyHwQueueDataFcn = nullptr;
decltype(&getSubmitCommandToHwQueueData) getSubmitCommandToHwQueueDataFcn = nullptr;
}; };

View File

@ -667,20 +667,26 @@ HWTEST_F(Wddm20WithMockGdiDllTests, givenUseNoRingFlushesKmdModeDebugFlagToTrueW
EXPECT_TRUE(!!privateData->NoRingFlushes); EXPECT_TRUE(!!privateData->NoRingFlushes);
} }
HWTEST_F(Wddm20WithMockGdiDllTests, givenHwQueueSupportEnabledWhenCreateContextIsCalledThenSetAppropriateFlag) { HWTEST_F(Wddm20WithMockGdiDllTests, whenCreateContextIsCalledThenDisableHwQueues) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.HwQueueSupported.set(true);
wddm->init<FamilyType>(); wddm->init<FamilyType>();
EXPECT_EQ(1u, getCreateContextDataFcn()->Flags.HwQueueSupported); EXPECT_FALSE(wddm->hwQueuesSupported());
EXPECT_EQ(0u, getCreateContextDataFcn()->Flags.HwQueueSupported);
} }
HWTEST_F(Wddm20WithMockGdiDllTests, givenHwQueueSupportDisabledWhenCreateContextIsCalledThenSetAppropriateFlag) { TEST_F(Wddm20Tests, whenCreateHwQueueIsCalledThenAlwaysReturnFalse) {
DebugManagerStateRestore dbgRestore; EXPECT_FALSE(wddm->createHwQueue());
DebugManager.flags.HwQueueSupported.set(false); }
HWTEST_F(Wddm20Tests, whenInitCalledThenDontCallToCreateHwQueue) {
wddm->init<FamilyType>(); wddm->init<FamilyType>();
EXPECT_EQ(0u, getCreateContextDataFcn()->Flags.HwQueueSupported); EXPECT_EQ(0u, wddm->createHwQueueResult.called);
}
HWTEST_F(Wddm20Tests, whenWddmIsInitializedThenGdiDoesntHaveHwQueueDDIs) {
wddm->init<FamilyType>();
EXPECT_EQ(nullptr, wddm->gdi->createHwQueue.mFunc);
EXPECT_EQ(nullptr, wddm->gdi->destroyHwQueue.mFunc);
EXPECT_EQ(nullptr, wddm->gdi->submitCommandToHwQueue.mFunc);
} }
HWTEST_F(Wddm20Tests, givenDebugManagerWhenGetForUseNoRingFlushesKmdModeIsCalledThenTrueIsReturned) { HWTEST_F(Wddm20Tests, givenDebugManagerWhenGetForUseNoRingFlushesKmdModeIsCalledThenTrueIsReturned) {

View File

@ -0,0 +1,174 @@
/*
* 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/os_interface/windows/gdi_interface.h"
#include "runtime/os_interface/windows/wddm/wddm23.h"
#include "unit_tests/mocks/mock_wddm23.h"
#include "unit_tests/os_interface/windows/gdi_dll_fixture.h"
#include "test.h"
using namespace OCLRT;
struct Wddm23Tests : public ::testing::Test, GdiDllFixture {
void SetUp() override {
GdiDllFixture::SetUp();
wddm.reset(static_cast<WddmMock23 *>(Wddm::createWddm(WddmInterfaceVersion::Wddm23)));
}
void TearDown() override {
GdiDllFixture::TearDown();
}
std::unique_ptr<WddmMock23> wddm;
};
TEST_F(Wddm23Tests, whenCreateMonitoredFenceCalledThenDoNothing) {
EXPECT_TRUE(wddm->createMonitoredFence());
EXPECT_TRUE(nullptr == wddm->getMonitoredFence().cpuAddress);
EXPECT_EQ(0u, wddm->getMonitoredFence().currentFenceValue);
EXPECT_EQ(static_cast<D3DKMT_HANDLE>(0), wddm->getMonitoredFence().fenceHandle);
EXPECT_EQ(static_cast<D3DGPU_VIRTUAL_ADDRESS>(0), wddm->getMonitoredFence().gpuAddress);
EXPECT_EQ(0u, wddm->getMonitoredFence().lastSubmittedFence);
}
HWTEST_F(Wddm23Tests, whenCreateContextIsCalledThenEnableHwQueues) {
wddm->init<FamilyType>();
EXPECT_TRUE(wddm->hwQueuesSupported());
EXPECT_EQ(1u, getCreateContextDataFcn()->Flags.HwQueueSupported);
}
TEST_F(Wddm23Tests, whenCreateHwQueueIsCalledThenSetAllRequiredFieldsAndMonitoredFence) {
EXPECT_EQ(0u, wddm->hwQueueHandle);
wddm->context = 1;
wddm->createHwQueue();
EXPECT_EQ(wddm->context, getCreateHwQueueDataFcn()->hHwContext);
EXPECT_EQ(0u, getCreateHwQueueDataFcn()->PrivateDriverDataSize);
EXPECT_EQ(nullptr, getCreateHwQueueDataFcn()->pPrivateDriverData);
EXPECT_TRUE(nullptr != wddm->getMonitoredFence().cpuAddress);
EXPECT_EQ(1u, wddm->getMonitoredFence().currentFenceValue);
EXPECT_NE(static_cast<D3DKMT_HANDLE>(0), wddm->getMonitoredFence().fenceHandle);
EXPECT_NE(static_cast<D3DGPU_VIRTUAL_ADDRESS>(0), wddm->getMonitoredFence().gpuAddress);
EXPECT_EQ(0u, wddm->getMonitoredFence().lastSubmittedFence);
}
TEST_F(Wddm23Tests, givenPreemptionModeWhenCreateHwQueueCalledThenSetGpuTimeoutIfEnabled) {
wddm->setPreemptionMode(PreemptionMode::Disabled);
wddm->createHwQueue();
EXPECT_EQ(0u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
wddm->setPreemptionMode(PreemptionMode::MidBatch);
wddm->createHwQueue();
EXPECT_EQ(1u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
}
HWTEST_F(Wddm23Tests, whenDestroyHwQueueCalledThenPassExistingHandle) {
wddm->init<FamilyType>();
wddm->hwQueueHandle = 123;
wddm->destroyHwQueue();
EXPECT_EQ(wddm->hwQueueHandle, getDestroyHwQueueDataFcn()->hHwQueue);
wddm->hwQueueHandle = 0;
wddm->destroyHwQueue();
EXPECT_NE(wddm->hwQueueHandle, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0
}
HWTEST_F(Wddm23Tests, whenObjectIsDestructedThenDestroyHwQueue) {
wddm->init<FamilyType>();
D3DKMT_HANDLE hwQueue = 123;
wddm->hwQueueHandle = hwQueue;
wddm.reset(nullptr);
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
}
HWTEST_F(Wddm23Tests, givenCmdBufferWhenSubmitCalledThenSetAllRequiredFiledsAndUpdateMonitoredFence) {
wddm->init<FamilyType>();
uint64_t cmdBufferAddress = 123;
size_t cmdSize = 456;
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
EXPECT_EQ(1u, wddm->getMonitoredFence().currentFenceValue);
EXPECT_EQ(0u, wddm->getMonitoredFence().lastSubmittedFence);
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader);
EXPECT_EQ(cmdBufferAddress, getSubmitCommandToHwQueueDataFcn()->CommandBuffer);
EXPECT_EQ(static_cast<UINT>(cmdSize), getSubmitCommandToHwQueueDataFcn()->CommandLength);
EXPECT_EQ(wddm->hwQueueHandle, getSubmitCommandToHwQueueDataFcn()->hHwQueue);
EXPECT_EQ(wddm->getMonitoredFence().fenceHandle, getSubmitCommandToHwQueueDataFcn()->HwQueueProgressFenceId);
EXPECT_EQ(&cmdBufferHeader, getSubmitCommandToHwQueueDataFcn()->pPrivateDriverData);
EXPECT_EQ(static_cast<UINT>(sizeof(COMMAND_BUFFER_HEADER)), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
EXPECT_EQ(wddm->getMonitoredFence().gpuAddress, cmdBufferHeader.MonitorFenceVA);
EXPECT_EQ(wddm->getMonitoredFence().lastSubmittedFence, cmdBufferHeader.MonitorFenceValue);
EXPECT_EQ(2u, wddm->getMonitoredFence().currentFenceValue);
EXPECT_EQ(1u, wddm->getMonitoredFence().lastSubmittedFence);
}
HWTEST_F(Wddm23Tests, givenCurrentPendingFenceValueGreaterThanPendingFenceValueWhenSubmitCalledThenCallWaitOnGpu) {
wddm->init<FamilyType>();
uint64_t cmdBufferAddress = 123;
size_t cmdSize = 456;
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
*wddm->pagingFenceAddress = 1;
wddm->currentPagingFenceValue = 1;
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader);
EXPECT_EQ(0u, wddm->waitOnGPUCalled);
wddm->currentPagingFenceValue = 2;
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader);
EXPECT_EQ(1u, wddm->waitOnGPUCalled);
}
HWTEST_F(Wddm23Tests, whenInitCalledThenInitializeNewGdiDDIsAndCallToCreateHwQueue) {
EXPECT_EQ(nullptr, wddm->gdi->createHwQueue.mFunc);
EXPECT_EQ(nullptr, wddm->gdi->destroyHwQueue.mFunc);
EXPECT_EQ(nullptr, wddm->gdi->submitCommandToHwQueue.mFunc);
EXPECT_TRUE(wddm->init<FamilyType>());
EXPECT_EQ(1u, wddm->createHwQueueCalled);
EXPECT_NE(nullptr, wddm->gdi->createHwQueue.mFunc);
EXPECT_NE(nullptr, wddm->gdi->destroyHwQueue.mFunc);
EXPECT_NE(nullptr, wddm->gdi->submitCommandToHwQueue.mFunc);
}
HWTEST_F(Wddm23Tests, whenCreateHwQueueFailedThenReturnFalseFromInit) {
wddm->forceCreateHwQueueFail = true;
EXPECT_FALSE(wddm->init<FamilyType>());
}
HWTEST_F(Wddm23Tests, givenFailureOnGdiInitializationWhenCreatingHwQueueThenReturnFailure) {
struct MyMockGdi : public Gdi {
bool setupHwQueueProcAddresses() override {
return false;
}
};
wddm->gdi.reset(new MyMockGdi());
EXPECT_FALSE(wddm->init<FamilyType>());
EXPECT_EQ(1u, wddm->createHwQueueCalled);
EXPECT_FALSE(wddm->createHwQueueResult);
}

View File

@ -21,9 +21,17 @@
*/ */
#include "unit_tests/mocks/mock_wddm20.h" #include "unit_tests/mocks/mock_wddm20.h"
#include "unit_tests/mocks/mock_wddm23.h"
namespace OCLRT { namespace OCLRT {
Wddm *Wddm::createWddm(uint32_t interfaceVersion) { Wddm *Wddm::createWddm(uint32_t interfaceVersion) {
return new WddmMock20(); switch (interfaceVersion) {
case WddmInterfaceVersion::Wddm20:
return new WddmMock20();
case WddmInterfaceVersion::Wddm23:
return new WddmMock23();
default:
return nullptr;
}
} }
} // namespace OCLRT } // namespace OCLRT

View File

@ -62,5 +62,4 @@ FlattenBatchBufferForAUBDump = false
PrintDispatchParameters = false PrintDispatchParameters = false
AddPatchInfoCommentsForAUBDump = false AddPatchInfoCommentsForAUBDump = false
HwQueueSupported = false HwQueueSupported = false
ForceWddmInterfaceVersion = 0
DisableZeroCopyForUseHostPtr = false DisableZeroCopyForUseHostPtr = false

View File

@ -21,16 +21,34 @@
*/ */
#include "runtime/os_interface/windows/wddm/wddm.h" #include "runtime/os_interface/windows/wddm/wddm.h"
#include "runtime/os_interface/windows/wddm/wddm23.h"
#include "unit_tests/helpers/debug_manager_state_restore.h"
#include "test.h" #include "test.h"
#include <typeinfo>
using namespace OCLRT; using namespace OCLRT;
TEST(wddmCreateTests, givenInputVersionWhenCreatingThenAlwaysUse20) { TEST(wddmCreateTests, givenInputVersionWhenCreatingThenCreateRequestedObject) {
std::unique_ptr<Wddm> wddm1(Wddm::createWddm(WddmInterfaceVersion::Wddm20)); std::unique_ptr<Wddm> wddm20(Wddm::createWddm(WddmInterfaceVersion::Wddm20));
std::unique_ptr<Wddm> wddm2(Wddm::createWddm(21)); std::unique_ptr<Wddm> wddm23(Wddm::createWddm(WddmInterfaceVersion::Wddm23));
std::unique_ptr<Wddm> wddm3(Wddm::createWddm(0));
EXPECT_EQ(WddmInterfaceVersion::Wddm20, wddm1->wddmInterfaceVersion); EXPECT_EQ(typeid(*wddm20.get()), typeid(Wddm20));
EXPECT_EQ(WddmInterfaceVersion::Wddm20, wddm2->wddmInterfaceVersion); EXPECT_EQ(typeid(*wddm23.get()), typeid(Wddm23));
EXPECT_EQ(WddmInterfaceVersion::Wddm20, wddm3->wddmInterfaceVersion); }
TEST(wddmCreateTests, givenInvalidInputVersionWhenCreatingThenThrowException) {
EXPECT_THROW(Wddm::createWddm(0), std::exception);
EXPECT_THROW(Wddm::createWddm(21), std::exception);
EXPECT_THROW(Wddm::createWddm(22), std::exception);
EXPECT_THROW(Wddm::createWddm(24), std::exception);
}
TEST(wddmCreateTests, givenHwQueuesSupportedDebugVariableWhenCreatingThenForceWddm23) {
DebugManagerStateRestore restore;
DebugManager.flags.HwQueueSupported.set(true);
std::unique_ptr<Wddm> wddm(Wddm::createWddm(WddmInterfaceVersion::Wddm20));
EXPECT_EQ(typeid(*wddm.get()), typeid(Wddm23));
} }