Extract Os Context from Wddm and WddmInterface

Change-Id: I13a52fc466a14f4bd28876d3c47884dc596f2b58
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2018-08-21 17:36:08 +02:00
committed by sys_ocldev
parent f6f9c0f456
commit deaaa908a4
13 changed files with 228 additions and 147 deletions

View File

@@ -41,6 +41,8 @@ set(RUNTIME_SRCS_OS_INTERFACE_WINDOWS
${CMAKE_CURRENT_SOURCE_DIR}/gdi_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/kmdaf_listener${KMDAF_FILE_SUFFIX}.cpp
${CMAKE_CURRENT_SOURCE_DIR}/kmdaf_listener.h
${CMAKE_CURRENT_SOURCE_DIR}/os_context_win.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_context_win.h
${CMAKE_CURRENT_SOURCE_DIR}/os_inc.h
${CMAKE_CURRENT_SOURCE_DIR}/os_interface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_interface.h

View File

@@ -0,0 +1,50 @@
/*
* 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/os_context_win.h"
#include "runtime/os_interface/windows/wddm/wddm.h"
#include "runtime/os_interface/windows/wddm/wddm_interface.h"
namespace OCLRT {
OsContextWin::OsContextWin(Wddm &wddm) : wddm(wddm) {
auto wddmInterface = wddm.getWddmInterface();
if (!wddm.createContext(context))
return;
if (wddmInterface->hwQueuesSupported()) {
if (!wddmInterface->createHwQueue(wddm.getPreemptionMode(), *this))
return;
}
initialized = wddmInterface->createMonitoredFence(*this);
};
OsContextWin::~OsContextWin() {
wddm.getWddmInterface()->destroyHwQueue(hwQueueHandle);
wddm.destroyContext(context);
}
void OsContextWin::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

View File

@@ -0,0 +1,58 @@
/*
* 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/windows_wrapper.h"
#include "runtime/os_interface/windows/windows_defs.h"
#include <d3dkmthk.h>
namespace OCLRT {
class Wddm;
class OsContextWin {
public:
OsContextWin() = delete;
OsContextWin(Wddm &wddm);
~OsContextWin();
D3DKMT_HANDLE getContext() const {
return context;
}
D3DKMT_HANDLE getHwQueue() const {
return hwQueueHandle;
}
void setHwQueue(D3DKMT_HANDLE hwQueue) {
hwQueueHandle = hwQueue;
}
bool isInitialized() const {
return initialized;
}
MonitoredFence &getMonitoredFence() { return monitoredFence; }
void resetMonitoredFenceParams(D3DKMT_HANDLE &handle, uint64_t *cpuAddress, D3DGPU_VIRTUAL_ADDRESS &gpuAddress);
protected:
bool initialized = false;
D3DKMT_HANDLE context = 0;
D3DKMT_HANDLE hwQueueHandle = 0;
Wddm &wddm;
MonitoredFence monitoredFence = {};
};
} // namespace OCLRT

View File

@@ -30,6 +30,7 @@
#include "runtime/gmm_helper/page_table_mngr.h"
#include "runtime/os_interface/windows/wddm/wddm.h"
#include "runtime/os_interface/hw_info_config.h"
#include "runtime/os_interface/windows/os_context_win.h"
#include "runtime/os_interface/windows/wddm_allocation.h"
#include "runtime/os_interface/windows/registry_reader.h"
#include "runtime/helpers/debug_helpers.h"
@@ -54,16 +55,7 @@ Wddm::GetSystemInfoFcn Wddm::getSystemInfo = getGetSystemInfo();
Wddm::VirtualAllocFcn Wddm::virtualAllocFnc = getVirtualAlloc();
Wddm::VirtualFreeFcn Wddm::virtualFreeFnc = getVirtualFree();
Wddm::Wddm() : initialized(false),
adapter(0),
context(0),
device(0),
pagingQueue(0),
pagingQueueSyncObject(0),
pagingFenceAddress(nullptr),
currentPagingFenceValue(0),
hwContextId(0),
trimCallbackHandle(nullptr) {
Wddm::Wddm() {
featureTable.reset(new FeatureTable());
waTable.reset(new WorkaroundTable());
gtSystemInfo.reset(new GT_SYSTEM_INFO);
@@ -74,17 +66,12 @@ Wddm::Wddm() : initialized(false),
registryReader.reset(new RegistryReader("System\\CurrentControlSet\\Control\\GraphicsDrivers\\Scheduler"));
adapterLuid.HighPart = 0;
adapterLuid.LowPart = 0;
maximumApplicationAddress = 0;
node = GPUNODE_3D;
preemptionMode = PreemptionMode::Disabled;
minAddress = 0;
kmDafListener = std::unique_ptr<KmDafListener>(new KmDafListener);
gdi = std::unique_ptr<Gdi>(new Gdi());
}
Wddm::~Wddm() {
resetPageTableManager(nullptr);
destroyContext(context);
destroyPagingQueue();
destroyDevice();
closeAdapter();
@@ -684,7 +671,7 @@ void Wddm::kmDafLock(WddmAllocation *wddmAllocation) {
kmDafListener->notifyLock(featureTable->ftrKmdDaf, adapter, device, wddmAllocation->handle, 0, gdi->escape);
}
bool Wddm::createContext() {
bool Wddm::createContext(D3DKMT_HANDLE &context) {
NTSTATUS status = STATUS_UNSUCCESSFUL;
D3DKMT_CREATECONTEXTVIRTUAL CreateContext = {0};
CREATECONTEXT_PVTDATA PrivateData = {{0}};
@@ -730,15 +717,15 @@ bool Wddm::destroyContext(D3DKMT_HANDLE context) {
bool Wddm::submit(uint64_t commandBuffer, size_t size, void *commandHeader) {
bool status = false;
if (currentPagingFenceValue > *pagingFenceAddress && !waitOnGPU()) {
if (currentPagingFenceValue > *pagingFenceAddress && !waitOnGPU(osContext->getContext())) {
return false;
}
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "currentFenceValue =", monitoredFence.currentFenceValue);
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "currentFenceValue =", osContext->getMonitoredFence().currentFenceValue);
status = wddmInterface->submit(commandBuffer, size, commandHeader);
status = wddmInterface->submit(commandBuffer, size, commandHeader, *osContext);
if (status) {
monitoredFence.lastSubmittedFence = monitoredFence.currentFenceValue;
monitoredFence.currentFenceValue++;
osContext->getMonitoredFence().lastSubmittedFence = osContext->getMonitoredFence().currentFenceValue;
osContext->getMonitoredFence().currentFenceValue++;
}
getDeviceState();
UNRECOVERABLE_IF(!status);
@@ -764,9 +751,9 @@ void Wddm::getDeviceState() {
}
void Wddm::handleCompletion() {
if (monitoredFence.cpuAddress) {
auto *currentTag = monitoredFence.cpuAddress;
while (*currentTag < monitoredFence.currentFenceValue - 1)
if (osContext->getMonitoredFence().cpuAddress) {
auto *currentTag = osContext->getMonitoredFence().cpuAddress;
while (*currentTag < osContext->getMonitoredFence().currentFenceValue - 1)
;
}
}
@@ -775,7 +762,7 @@ unsigned int Wddm::readEnablePreemptionRegKey() {
return static_cast<unsigned int>(registryReader->getSetting("EnablePreemption", 1));
}
bool Wddm::waitOnGPU() {
bool Wddm::waitOnGPU(D3DKMT_HANDLE context) {
D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMGPU WaitOnGPU = {0};
WaitOnGPU.hContext = context;
@@ -792,10 +779,10 @@ bool Wddm::waitOnGPU() {
bool Wddm::waitFromCpu(uint64_t lastFenceValue) {
NTSTATUS status = STATUS_SUCCESS;
if (lastFenceValue > *monitoredFence.cpuAddress) {
if (lastFenceValue > *osContext->getMonitoredFence().cpuAddress) {
D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU waitFromCpu = {0};
waitFromCpu.ObjectCount = 1;
waitFromCpu.ObjectHandleArray = &monitoredFence.fenceHandle;
waitFromCpu.ObjectHandleArray = &osContext->getMonitoredFence().fenceHandle;
waitFromCpu.FenceValueArray = &lastFenceValue;
waitFromCpu.hDevice = device;
waitFromCpu.hAsyncEvent = NULL;
@@ -901,12 +888,9 @@ void *Wddm::virtualAlloc(void *inPtr, size_t size, unsigned long flags, unsigned
int Wddm::virtualFree(void *ptr, size_t size, unsigned long flags) {
return virtualFreeFnc(ptr, size, flags);
}
MonitoredFence &Wddm::getMonitoredFence() { return osContext->getMonitoredFence(); }
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;
D3DKMT_HANDLE Wddm::getOsDeviceContext() const {
return osContext->getContext();
}
} // namespace OCLRT

View File

@@ -45,6 +45,7 @@ class Gdi;
class Gmm;
class LinearStream;
class GmmPageTableMngr;
class OsContextWin;
struct FeatureTable;
struct WorkaroundTable;
struct KmDafListener;
@@ -70,7 +71,7 @@ class Wddm {
MOCKABLE_VIRTUAL bool makeResident(D3DKMT_HANDLE *handles, uint32_t count, bool cantTrimFurther, uint64_t *numberOfBytesToTrim);
bool mapGpuVirtualAddress(WddmAllocation *allocation, void *cpuPtr, bool allocation32bit, bool use64kbPages, bool useHeap1);
bool mapGpuVirtualAddress(AllocationStorageData *allocationStorageData, bool allocation32bit, bool use64kbPages);
MOCKABLE_VIRTUAL bool createContext();
MOCKABLE_VIRTUAL bool createContext(D3DKMT_HANDLE &context);
MOCKABLE_VIRTUAL bool freeGpuVirtualAddres(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size);
MOCKABLE_VIRTUAL NTSTATUS createAllocation(WddmAllocation *alloc);
MOCKABLE_VIRTUAL bool createAllocation64k(WddmAllocation *alloc);
@@ -86,8 +87,7 @@ class Wddm {
MOCKABLE_VIRTUAL bool destroyContext(D3DKMT_HANDLE context);
MOCKABLE_VIRTUAL bool queryAdapterInfo();
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader);
MOCKABLE_VIRTUAL bool waitOnGPU();
MOCKABLE_VIRTUAL bool submit(uint64_t commandBuffer, size_t size, void *commandHeader);
MOCKABLE_VIRTUAL bool waitFromCpu(uint64_t lastFenceValue);
NTSTATUS escape(D3DKMT_ESCAPE &escapeCommand);
@@ -121,7 +121,7 @@ class Wddm {
return deviceRegistryPath;
}
MonitoredFence &getMonitoredFence() { return monitoredFence; }
MonitoredFence &getMonitoredFence();
uint64_t getSystemSharedMemory() const;
@@ -159,27 +159,26 @@ class Wddm {
uintptr_t getWddmMinAddress() const {
return this->minAddress;
}
D3DKMT_HANDLE getOsDeviceContext() {
return context;
WddmInterface *getWddmInterface() const {
return wddmInterface.get();
}
PreemptionMode getPreemptionMode() const {
return preemptionMode;
}
D3DKMT_HANDLE getOsDeviceContext() const;
unsigned int readEnablePreemptionRegKey();
void resetMonitoredFenceParams(D3DKMT_HANDLE &handle, uint64_t *cpuAddress, D3DGPU_VIRTUAL_ADDRESS &gpuAddress);
protected:
bool initialized;
bool initialized = false;
std::unique_ptr<Gdi> gdi;
D3DKMT_HANDLE adapter;
D3DKMT_HANDLE context;
D3DKMT_HANDLE device;
D3DKMT_HANDLE pagingQueue;
D3DKMT_HANDLE pagingQueueSyncObject;
D3DKMT_HANDLE adapter = 0;
D3DKMT_HANDLE device = 0;
D3DKMT_HANDLE pagingQueue = 0;
D3DKMT_HANDLE pagingQueueSyncObject = 0;
uint64_t *pagingFenceAddress;
std::atomic<std::uint64_t> currentPagingFenceValue;
MonitoredFence monitoredFence;
uint64_t *pagingFenceAddress = nullptr;
std::atomic<std::uint64_t> currentPagingFenceValue{0};
// Adapter information
std::unique_ptr<PLATFORM> gfxPlatform;
@@ -192,18 +191,19 @@ class Wddm {
bool instrumentationEnabled = false;
std::string deviceRegistryPath;
unsigned long hwContextId;
unsigned long hwContextId = 0;
LUID adapterLuid;
void *trimCallbackHandle;
uintptr_t maximumApplicationAddress;
GPUNODE_ORDINAL node;
PreemptionMode preemptionMode;
void *trimCallbackHandle = nullptr;
uintptr_t maximumApplicationAddress = 0;
GPUNODE_ORDINAL node = GPUNODE_3D;
PreemptionMode preemptionMode = PreemptionMode::Disabled;
std::unique_ptr<GmmMemory> gmmMemory;
uintptr_t minAddress;
uintptr_t minAddress = 0;
Wddm();
MOCKABLE_VIRTUAL bool mapGpuVirtualAddressImpl(Gmm *gmm, D3DKMT_HANDLE handle, void *cpuPtr, D3DGPU_VIRTUAL_ADDRESS &gpuPtr, bool allocation32bit, bool use64kbPages, bool useHeap1);
MOCKABLE_VIRTUAL bool openAdapter();
MOCKABLE_VIRTUAL bool waitOnGPU(D3DKMT_HANDLE context);
bool createDevice();
bool createPagingQueue();
bool destroyPagingQueue();
@@ -221,5 +221,6 @@ class Wddm {
std::unique_ptr<KmDafListener> kmDafListener;
std::unique_ptr<WddmInterface> wddmInterface;
std::unique_ptr<OsContextWin> osContext;
};
} // namespace OCLRT

View File

@@ -22,6 +22,7 @@
#include "runtime/os_interface/windows/gdi_interface.h"
#include "runtime/os_interface/windows/wddm/wddm.h"
#include "runtime/os_interface/windows/os_context_win.h"
namespace OCLRT {
@@ -67,16 +68,8 @@ bool Wddm::init() {
if (!configureDeviceAddressSpace<GfxFamily>()) {
return false;
}
if (!createContext()) {
return false;
}
if (wddmInterface->hwQueuesSupported() && !wddmInterface->createHwQueue(preemptionMode)) {
return false;
}
if (!wddmInterface->createMonitoredFence()) {
return false;
}
initialized = true;
osContext = std::make_unique<OsContextWin>(*this);
initialized = osContext->isInitialized();
}
return initialized;
}

View File

@@ -23,12 +23,14 @@
#include "runtime/os_interface/windows/gdi_interface.h"
#include "runtime/os_interface/windows/wddm/wddm_interface.h"
#include "runtime/os_interface/windows/wddm/wddm.h"
#include "runtime/os_interface/windows/os_context_win.h"
bool OCLRT::WddmInterface20::createHwQueue(PreemptionMode preemptionMode) {
bool OCLRT::WddmInterface20::createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) {
return false;
}
void OCLRT::WddmInterface20::destroyHwQueue(D3DKMT_HANDLE hwQueue) {}
bool OCLRT::WddmInterface20::createMonitoredFence() {
bool OCLRT::WddmInterface20::createMonitoredFence(OsContextWin &osContext) {
NTSTATUS Status;
D3DKMT_CREATESYNCHRONIZATIONOBJECT2 CreateSynchronizationObject = {0};
CreateSynchronizationObject.hDevice = wddm.getDevice();
@@ -39,9 +41,9 @@ bool OCLRT::WddmInterface20::createMonitoredFence() {
DEBUG_BREAK_IF(STATUS_SUCCESS != Status);
wddm.resetMonitoredFenceParams(CreateSynchronizationObject.hSyncObject,
reinterpret_cast<uint64_t *>(CreateSynchronizationObject.Info.MonitoredFence.FenceValueCPUVirtualAddress),
CreateSynchronizationObject.Info.MonitoredFence.FenceValueGPUVirtualAddress);
osContext.resetMonitoredFenceParams(CreateSynchronizationObject.hSyncObject,
reinterpret_cast<uint64_t *>(CreateSynchronizationObject.Info.MonitoredFence.FenceValueCPUVirtualAddress),
CreateSynchronizationObject.Info.MonitoredFence.FenceValueGPUVirtualAddress);
return Status == STATUS_SUCCESS;
}
@@ -50,7 +52,7 @@ const bool OCLRT::WddmInterface20::hwQueuesSupported() {
return false;
}
bool OCLRT::WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *commandHeader) {
bool OCLRT::WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) {
D3DKMT_SUBMITCOMMAND SubmitCommand = {0};
NTSTATUS status = STATUS_SUCCESS;
@@ -58,7 +60,7 @@ bool OCLRT::WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *c
SubmitCommand.Commands = commandBuffer;
SubmitCommand.CommandLength = static_cast<UINT>(size);
SubmitCommand.BroadcastContextCount = 1;
SubmitCommand.BroadcastContext[0] = wddm.getOsDeviceContext();
SubmitCommand.BroadcastContext[0] = osContext.getContext();
SubmitCommand.Flags.NullRendering = (UINT)DebugManager.flags.EnableNullHardware.get();
COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast<COMMAND_BUFFER_HEADER *>(commandHeader);
@@ -75,40 +77,40 @@ bool OCLRT::WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *c
return STATUS_SUCCESS == status;
}
bool OCLRT::WddmInterface23::createHwQueue(PreemptionMode preemptionMode) {
bool OCLRT::WddmInterface23::createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) {
D3DKMT_CREATEHWQUEUE createHwQueue = {};
if (!wddm.getGdi()->setupHwQueueProcAddresses()) {
return false;
}
createHwQueue.hHwContext = wddm.getOsDeviceContext();
createHwQueue.hHwContext = osContext.getContext();
if (preemptionMode >= PreemptionMode::MidBatch) {
createHwQueue.Flags.DisableGpuTimeout = wddm.readEnablePreemptionRegKey();
}
auto status = wddm.getGdi()->createHwQueue(&createHwQueue);
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
hwQueueHandle = createHwQueue.hHwQueue;
osContext.setHwQueue(createHwQueue.hHwQueue);
wddm.resetMonitoredFenceParams(createHwQueue.hHwQueueProgressFence,
reinterpret_cast<uint64_t *>(createHwQueue.HwQueueProgressFenceCPUVirtualAddress),
createHwQueue.HwQueueProgressFenceGPUVirtualAddress);
osContext.resetMonitoredFenceParams(createHwQueue.hHwQueueProgressFence,
reinterpret_cast<uint64_t *>(createHwQueue.HwQueueProgressFenceCPUVirtualAddress),
createHwQueue.HwQueueProgressFenceGPUVirtualAddress);
return status == STATUS_SUCCESS;
}
void OCLRT::WddmInterface23::destroyHwQueue() {
if (hwQueueHandle) {
void OCLRT::WddmInterface23::destroyHwQueue(D3DKMT_HANDLE hwQueue) {
if (hwQueue) {
D3DKMT_DESTROYHWQUEUE destroyHwQueue = {};
destroyHwQueue.hHwQueue = hwQueueHandle;
destroyHwQueue.hHwQueue = hwQueue;
auto status = wddm.getGdi()->destroyHwQueue(&destroyHwQueue);
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
}
}
bool OCLRT::WddmInterface23::createMonitoredFence() {
bool OCLRT::WddmInterface23::createMonitoredFence(OsContextWin &osContext) {
return true;
}
@@ -116,11 +118,11 @@ const bool OCLRT::WddmInterface23::hwQueuesSupported() {
return true;
}
bool OCLRT::WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandHeader) {
bool OCLRT::WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) {
auto monitoredFence = wddm.getMonitoredFence();
D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommand = {};
submitCommand.hHwQueue = hwQueueHandle;
submitCommand.hHwQueue = osContext.getHwQueue();
submitCommand.HwQueueProgressFenceId = monitoredFence.fenceHandle;
submitCommand.CommandBuffer = commandBuffer;
submitCommand.CommandLength = static_cast<UINT>(size);

View File

@@ -20,42 +20,45 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "runtime/os_interface/windows/windows_wrapper.h"
#include <d3dkmthk.h>
#include <cstdint>
#include "runtime/helpers/hw_info.h"
namespace OCLRT {
class Gdi;
class OsContextWin;
class Wddm;
class WddmInterface {
public:
WddmInterface(Wddm &wddm) : wddm(wddm){};
virtual ~WddmInterface() = default;
WddmInterface() = delete;
virtual bool createHwQueue(PreemptionMode preemptionMode) = 0;
virtual bool createMonitoredFence() = 0;
virtual bool createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) = 0;
virtual void destroyHwQueue(D3DKMT_HANDLE hwQueue) = 0;
virtual bool createMonitoredFence(OsContextWin &osContext) = 0;
virtual const bool hwQueuesSupported() = 0;
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) = 0;
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) = 0;
Wddm &wddm;
};
class WddmInterface20 : public WddmInterface {
public:
using WddmInterface::WddmInterface;
bool createHwQueue(PreemptionMode preemptionMode) override;
bool createMonitoredFence() override;
bool createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) override;
void destroyHwQueue(D3DKMT_HANDLE hwQueue) override;
bool createMonitoredFence(OsContextWin &osContext) override;
const bool hwQueuesSupported() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override;
};
class WddmInterface23 : public WddmInterface {
public:
~WddmInterface23() override { destroyHwQueue(); }
using WddmInterface::WddmInterface;
bool createHwQueue(PreemptionMode preemptionMode) override;
void destroyHwQueue();
bool createMonitoredFence() override;
bool createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) override;
void destroyHwQueue(D3DKMT_HANDLE hwQueue) override;
bool createMonitoredFence(OsContextWin &osContext) override;
const bool hwQueuesSupported() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override;
D3DKMT_HANDLE hwQueueHandle = 0;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override;
};
} // namespace OCLRT

View File

@@ -121,9 +121,9 @@ bool WddmMock::openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) {
}
}
bool WddmMock::createContext() {
bool WddmMock::createContext(D3DKMT_HANDLE &context) {
createContextResult.called++;
return createContextResult.success = Wddm::createContext();
return createContextResult.success = Wddm::createContext(context);
}
bool WddmMock::destroyContext(D3DKMT_HANDLE context) {
@@ -143,9 +143,9 @@ bool WddmMock::submit(uint64_t commandBuffer, size_t size, void *commandHeader)
return submitResult.success = Wddm::submit(commandBuffer, size, commandHeader);
}
bool WddmMock::waitOnGPU() {
bool WddmMock::waitOnGPU(D3DKMT_HANDLE context) {
waitOnGPUResult.called++;
return waitOnGPUResult.success = Wddm::waitOnGPU();
return waitOnGPUResult.success = Wddm::waitOnGPU(context);
}
void *WddmMock::lockResource(WddmAllocation *allocation) {

View File

@@ -50,13 +50,13 @@ struct KmDafLockCall : public CallResult {
class WddmMock : public Wddm {
public:
using Wddm::adapter;
using Wddm::context;
using Wddm::currentPagingFenceValue;
using Wddm::device;
using Wddm::featureTable;
using Wddm::gdi;
using Wddm::getSystemInfo;
using Wddm::gmmMemory;
using Wddm::osContext;
using Wddm::pagingFenceAddress;
using Wddm::pagingQueue;
using Wddm::preemptionMode;
@@ -74,11 +74,11 @@ class WddmMock : public Wddm {
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 createContext(D3DKMT_HANDLE &context) override;
bool destroyContext(D3DKMT_HANDLE context) override;
bool queryAdapterInfo() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader) override;
bool waitOnGPU() override;
bool waitOnGPU(D3DKMT_HANDLE context) override;
void *lockResource(WddmAllocation *allocation) override;
void unlockResource(WddmAllocation *allocation) override;
void kmDafLock(WddmAllocation *allocation) override;

View File

@@ -29,9 +29,9 @@ class WddmMockInterface23 : public WddmInterface23 {
public:
using WddmInterface23::WddmInterface23;
bool createHwQueue(PreemptionMode preemptionMode) override {
bool createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) override {
createHwQueueCalled++;
createHwQueueResult = forceCreateHwQueueFail ? false : WddmInterface23::createHwQueue(preemptionMode);
createHwQueueResult = forceCreateHwQueueFail ? false : WddmInterface23::createHwQueue(preemptionMode, osContext);
return createHwQueueResult;
}

View File

@@ -30,6 +30,7 @@
#include "runtime/memory_manager/os_agnostic_memory_manager.h"
#include "runtime/os_interface/windows/os_interface.h"
#include "runtime/os_interface/os_library.h"
#include "runtime/os_interface/windows/os_context_win.h"
#include "runtime/os_interface/windows/wddm_allocation.h"
#include "runtime/os_interface/windows/wddm_memory_manager.h"
@@ -176,14 +177,12 @@ TEST(Wddm20EnumAdaptersTest, givenUnknownPlatformWhenEnumAdapterIsCalledThenFals
EXPECT_EQ(nullptr, outHwInfo.pWaTable);
}
HWTEST_F(Wddm20Tests, context) {
EXPECT_TRUE(wddm->getOsDeviceContext() == static_cast<D3DKMT_HANDLE>(0));
HWTEST_F(Wddm20Tests, whenInitializeWddmThenContextIsCreated) {
EXPECT_TRUE(wddm->osContext == nullptr);
wddm->init<FamilyType>();
ASSERT_TRUE(wddm->isInitialized());
EXPECT_TRUE(wddm->createContext());
auto context = wddm->getOsDeviceContext();
auto context = wddm->osContext->getContext();
EXPECT_TRUE(context != static_cast<D3DKMT_HANDLE>(0));
EXPECT_TRUE(wddm->destroyContext(context));
@@ -648,7 +647,8 @@ HWTEST_F(Wddm20Tests, getMaxApplicationAddress) {
HWTEST_F(Wddm20Tests, dontCallCreateContextBeforeConfigureDeviceAddressSpace) {
wddm->wddmInterface = std::make_unique<WddmInterface20>(*wddm);
wddm->createContext();
D3DKMT_HANDLE context;
wddm->createContext(context);
EXPECT_EQ(1u, wddm->createContextResult.called); // dont care about the result
wddm->configureDeviceAddressSpace<FamilyType>();
@@ -683,7 +683,7 @@ HWTEST_F(Wddm20WithMockGdiDllTests, whenCreateContextIsCalledThenDisableHwQueues
HWTEST_F(Wddm20Tests, whenCreateHwQueueIsCalledThenAlwaysReturnFalse) {
wddm->init<FamilyType>();
EXPECT_FALSE(wddm->wddmInterface->createHwQueue(wddm->preemptionMode));
EXPECT_FALSE(wddm->wddmInterface->createHwQueue(wddm->preemptionMode, *wddm->osContext));
}
HWTEST_F(Wddm20Tests, whenWddmIsInitializedThenGdiDoesntHaveHwQueueDDIs) {
@@ -895,7 +895,7 @@ HWTEST_F(Wddm20Tests, createMonitoredFenceIsInitializedWithFenceValueZeroAndCurr
gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue = 300;
wddm->wddmInterface->createMonitoredFence();
wddm->wddmInterface->createMonitoredFence(*wddm->osContext);
EXPECT_EQ(0u, gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue);
EXPECT_EQ(1u, wddm->getMonitoredFence().currentFenceValue);
@@ -946,9 +946,3 @@ HWTEST_F(Wddm20Tests, givenReadOnlyMemoryWhenCreateAllocationFailsWithNoVideoMem
delete handleStorage.fragmentStorageData[0].osHandleStorage->gmm;
}
HWTEST_F(Wddm20Tests, whenGetOsDeviceContextIsCalledThenWddmOsDeviceContextIsReturned) {
D3DKMT_HANDLE ctx = 0xc1;
wddm->context = ctx;
EXPECT_EQ(ctx, wddm->getOsDeviceContext());
}

View File

@@ -26,6 +26,7 @@
#include "unit_tests/mocks/mock_wddm.h"
#include "unit_tests/mocks/mock_wddm_interface23.h"
#include "unit_tests/os_interface/windows/gdi_dll_fixture.h"
#include "runtime/os_interface/windows/os_context_win.h"
#include "test.h"
using namespace OCLRT;
@@ -51,28 +52,17 @@ struct Wddm23Tests : public ::testing::Test, GdiDllFixture, public GmmEnvironmen
WddmMockInterface23 *wddmMockInterface = nullptr;
};
TEST_F(Wddm23Tests, whenCreateMonitoredFenceCalledThenDoNothing) {
EXPECT_TRUE(wddm->wddmInterface->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->wddmInterface->hwQueuesSupported());
EXPECT_EQ(1u, getCreateContextDataFcn()->Flags.HwQueueSupported);
}
TEST_F(Wddm23Tests, whenCreateHwQueueIsCalledThenSetAllRequiredFieldsAndMonitoredFence) {
EXPECT_EQ(0u, wddmMockInterface->hwQueueHandle);
wddm->context = 1;
HWTEST_F(Wddm23Tests, whenCreateHwQueueIsCalledThenSetAllRequiredFieldsAndMonitoredFence) {
EXPECT_EQ(nullptr, wddm->osContext);
wddm->init<FamilyType>();
wddm->wddmInterface->createHwQueue(wddm->preemptionMode);
EXPECT_EQ(wddm->context, getCreateHwQueueDataFcn()->hHwContext);
EXPECT_EQ(wddm->osContext->getContext(), getCreateHwQueueDataFcn()->hHwContext);
EXPECT_EQ(0u, getCreateHwQueueDataFcn()->PrivateDriverDataSize);
EXPECT_EQ(nullptr, getCreateHwQueueDataFcn()->pPrivateDriverData);
@@ -83,31 +73,34 @@ TEST_F(Wddm23Tests, whenCreateHwQueueIsCalledThenSetAllRequiredFieldsAndMonitore
EXPECT_EQ(0u, wddm->getMonitoredFence().lastSubmittedFence);
}
TEST_F(Wddm23Tests, givenPreemptionModeWhenCreateHwQueueCalledThenSetGpuTimeoutIfEnabled) {
HWTEST_F(Wddm23Tests, givenPreemptionModeWhenCreateHwQueueCalledThenSetGpuTimeoutIfEnabled) {
wddm->init<FamilyType>();
wddm->setPreemptionMode(PreemptionMode::Disabled);
wddm->wddmInterface->createHwQueue(wddm->preemptionMode);
wddm->wddmInterface->createHwQueue(wddm->preemptionMode, *wddm->osContext);
EXPECT_EQ(0u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
wddm->setPreemptionMode(PreemptionMode::MidBatch);
wddm->wddmInterface->createHwQueue(wddm->preemptionMode);
wddm->wddmInterface->createHwQueue(wddm->preemptionMode, *wddm->osContext);
EXPECT_EQ(1u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
}
HWTEST_F(Wddm23Tests, whenDestroyHwQueueCalledThenPassExistingHandle) {
wddm->init<FamilyType>();
wddmMockInterface->hwQueueHandle = 123;
wddmMockInterface->destroyHwQueue();
EXPECT_EQ(wddmMockInterface->hwQueueHandle, getDestroyHwQueueDataFcn()->hHwQueue);
D3DKMT_HANDLE hwQueue = 123;
wddm->osContext->setHwQueue(hwQueue);
wddmMockInterface->destroyHwQueue(wddm->osContext->getHwQueue());
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
wddmMockInterface->hwQueueHandle = 0;
wddmMockInterface->destroyHwQueue();
EXPECT_NE(wddmMockInterface->hwQueueHandle, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0
hwQueue = 0;
wddm->osContext->setHwQueue(hwQueue);
wddmMockInterface->destroyHwQueue(wddm->osContext->getHwQueue());
EXPECT_NE(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0
}
HWTEST_F(Wddm23Tests, whenObjectIsDestructedThenDestroyHwQueue) {
wddm->init<FamilyType>();
D3DKMT_HANDLE hwQueue = 123;
wddmMockInterface->hwQueueHandle = hwQueue;
wddm->osContext->setHwQueue(hwQueue);
wddm.reset(nullptr);
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
}
@@ -116,6 +109,7 @@ HWTEST_F(Wddm23Tests, givenCmdBufferWhenSubmitCalledThenSetAllRequiredFiledsAndU
wddm->init<FamilyType>();
uint64_t cmdBufferAddress = 123;
size_t cmdSize = 456;
auto hwQueue = wddm->osContext->getHwQueue();
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
EXPECT_EQ(1u, wddm->getMonitoredFence().currentFenceValue);
@@ -125,7 +119,7 @@ HWTEST_F(Wddm23Tests, givenCmdBufferWhenSubmitCalledThenSetAllRequiredFiledsAndU
EXPECT_EQ(cmdBufferAddress, getSubmitCommandToHwQueueDataFcn()->CommandBuffer);
EXPECT_EQ(static_cast<UINT>(cmdSize), getSubmitCommandToHwQueueDataFcn()->CommandLength);
EXPECT_EQ(wddmMockInterface->hwQueueHandle, getSubmitCommandToHwQueueDataFcn()->hHwQueue);
EXPECT_EQ(hwQueue, 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);