2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2018-09-20 11:54:29 +08:00
|
|
|
* Copyright (C) 2017-2018 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-20 11:54:29 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Need to suppress warining 4005 caused by hw_cmds.h and wddm.h order.
|
|
|
|
// Current order must be preserved due to two versions of igfxfmid.h
|
|
|
|
#pragma warning(push)
|
|
|
|
#pragma warning(disable : 4005)
|
|
|
|
#include "hw_cmds.h"
|
|
|
|
#include "runtime/command_stream/linear_stream.h"
|
2018-02-06 18:58:05 +08:00
|
|
|
#include "runtime/command_stream/preemption.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/device/device.h"
|
2018-07-18 20:11:05 +08:00
|
|
|
#include "runtime/gmm_helper/page_table_mngr.h"
|
2018-08-17 19:38:09 +08:00
|
|
|
#include "runtime/helpers/gmm_callbacks.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/helpers/ptr_math.h"
|
2018-07-18 20:11:05 +08:00
|
|
|
#include "runtime/mem_obj/mem_obj.h"
|
|
|
|
#include "runtime/os_interface/windows/wddm/wddm.h"
|
|
|
|
#include "runtime/os_interface/windows/wddm_device_command_stream.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#pragma warning(pop)
|
|
|
|
|
|
|
|
#undef max
|
|
|
|
|
|
|
|
#include "runtime/os_interface/windows/gdi_interface.h"
|
2018-08-27 21:48:29 +08:00
|
|
|
#include "runtime/os_interface/windows/os_context_win.h"
|
2018-07-18 20:11:05 +08:00
|
|
|
#include "runtime/os_interface/windows/os_interface.h"
|
|
|
|
#include "runtime/os_interface/windows/wddm_engine_mapper.h"
|
|
|
|
#include "runtime/os_interface/windows/wddm_memory_manager.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
namespace OCLRT {
|
|
|
|
|
|
|
|
// Initialize COMMAND_BUFFER_HEADER Type PatchList Streamer Perf Tag
|
|
|
|
DECLARE_COMMAND_BUFFER(CommandBufferHeader, UMD_OCL, FALSE, FALSE, PERFTAG_OCL);
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-08-30 15:27:47 +08:00
|
|
|
WddmCommandStreamReceiver<GfxFamily>::WddmCommandStreamReceiver(const HardwareInfo &hwInfoIn,
|
|
|
|
ExecutionEnvironment &executionEnvironment)
|
2018-08-08 19:49:09 +08:00
|
|
|
: BaseClass(hwInfoIn, executionEnvironment) {
|
2018-08-30 15:27:47 +08:00
|
|
|
|
|
|
|
if (!executionEnvironment.osInterface) {
|
|
|
|
executionEnvironment.osInterface = std::make_unique<OSInterface>();
|
2018-08-14 17:05:17 +08:00
|
|
|
this->wddm = Wddm::createWddm();
|
2018-08-30 15:27:47 +08:00
|
|
|
this->osInterface = executionEnvironment.osInterface.get();
|
|
|
|
this->osInterface->get()->setWddm(this->wddm);
|
|
|
|
} else {
|
|
|
|
this->wddm = executionEnvironment.osInterface->get()->getWddm();
|
|
|
|
this->osInterface = executionEnvironment.osInterface.get();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-08-30 15:27:47 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
GPUNODE_ORDINAL nodeOrdinal = GPUNODE_3D;
|
2017-11-14 18:15:09 +08:00
|
|
|
UNRECOVERABLE_IF(!WddmEngineMapper<GfxFamily>::engineNodeMap(hwInfoIn.capabilityTable.defaultEngineType, nodeOrdinal));
|
2017-12-21 07:45:38 +08:00
|
|
|
this->wddm->setNode(nodeOrdinal);
|
2018-02-06 18:58:05 +08:00
|
|
|
PreemptionMode preemptionMode = PreemptionHelper::getDefaultPreemptionMode(hwInfoIn);
|
|
|
|
this->wddm->setPreemptionMode(preemptionMode);
|
2018-08-27 21:48:29 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
commandBufferHeader = new COMMAND_BUFFER_HEADER;
|
|
|
|
*commandBufferHeader = CommandBufferHeader;
|
2018-08-06 17:18:52 +08:00
|
|
|
|
|
|
|
if (preemptionMode != PreemptionMode::Disabled) {
|
|
|
|
commandBufferHeader->NeedsMidBatchPreEmptionSupport = true;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
this->dispatchMode = DispatchMode::BatchedDispatch;
|
|
|
|
|
|
|
|
if (DebugManager.flags.CsrDispatchMode.get()) {
|
|
|
|
this->dispatchMode = (DispatchMode)DebugManager.flags.CsrDispatchMode.get();
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
bool success = this->wddm->init();
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(!success);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
WddmCommandStreamReceiver<GfxFamily>::~WddmCommandStreamReceiver() {
|
|
|
|
this->cleanupResources();
|
|
|
|
|
|
|
|
if (commandBufferHeader)
|
|
|
|
delete commandBufferHeader;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
FlushStamp WddmCommandStreamReceiver<GfxFamily>::flush(BatchBuffer &batchBuffer,
|
2018-08-27 21:48:29 +08:00
|
|
|
EngineType engineType, ResidencyContainer *allocationsForResidency, OsContext &osContext) {
|
2018-03-01 23:21:18 +08:00
|
|
|
auto commandStreamAddress = ptrOffset(batchBuffer.commandBufferAllocation->getGpuAddress(), batchBuffer.startOffset);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (this->dispatchMode == DispatchMode::ImmediateDispatch) {
|
|
|
|
makeResident(*batchBuffer.commandBufferAllocation);
|
|
|
|
} else {
|
|
|
|
allocationsForResidency->push_back(batchBuffer.commandBufferAllocation);
|
2018-09-20 11:54:29 +08:00
|
|
|
batchBuffer.commandBufferAllocation->residencyTaskCount[this->deviceIndex] = this->taskCount;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-09-14 16:39:21 +08:00
|
|
|
UNRECOVERABLE_IF(allocationsForResidency == nullptr);
|
|
|
|
this->processResidency(*allocationsForResidency, osContext);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast<COMMAND_BUFFER_HEADER *>(commandBufferHeader);
|
|
|
|
pHeader->RequiresCoherency = batchBuffer.requiresCoherency;
|
2018-01-29 18:18:34 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
pHeader->UmdRequestedSliceState = 0;
|
|
|
|
pHeader->UmdRequestedEUCount = wddm->getGtSysInfo()->EUCount / wddm->getGtSysInfo()->SubSliceCount;
|
|
|
|
|
2018-01-29 18:18:34 +08:00
|
|
|
const uint32_t maxRequestedSubsliceCount = 7;
|
|
|
|
switch (batchBuffer.throttle) {
|
|
|
|
case QueueThrottle::LOW:
|
|
|
|
pHeader->UmdRequestedSubsliceCount = 1;
|
|
|
|
break;
|
|
|
|
case QueueThrottle::MEDIUM:
|
|
|
|
pHeader->UmdRequestedSubsliceCount = 0;
|
|
|
|
break;
|
|
|
|
case QueueThrottle::HIGH:
|
|
|
|
pHeader->UmdRequestedSubsliceCount = (wddm->getGtSysInfo()->SubSliceCount <= maxRequestedSubsliceCount) ? wddm->getGtSysInfo()->SubSliceCount : 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-03-23 04:13:45 +08:00
|
|
|
if (wddm->isKmDafEnabled()) {
|
|
|
|
this->kmDafLockAllocations(allocationsForResidency);
|
|
|
|
}
|
|
|
|
|
2018-08-27 21:48:29 +08:00
|
|
|
wddm->submit(commandStreamAddress, batchBuffer.usedSize - batchBuffer.startOffset, commandBufferHeader, *osContext.get());
|
2018-03-23 04:13:45 +08:00
|
|
|
|
2018-08-27 21:48:29 +08:00
|
|
|
return osContext.get()->getMonitoredFence().lastSubmittedFence;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
void WddmCommandStreamReceiver<GfxFamily>::makeResident(GraphicsAllocation &gfxAllocation) {
|
|
|
|
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "allocation =", reinterpret_cast<WddmAllocation *>(&gfxAllocation));
|
|
|
|
|
|
|
|
if (gfxAllocation.fragmentsStorage.fragmentCount == 0) {
|
|
|
|
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "allocation handle =", reinterpret_cast<WddmAllocation *>(&gfxAllocation)->handle);
|
|
|
|
} else {
|
|
|
|
for (uint32_t allocationId = 0; allocationId < reinterpret_cast<WddmAllocation *>(&gfxAllocation)->fragmentsStorage.fragmentCount; allocationId++) {
|
|
|
|
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "fragment handle =", reinterpret_cast<WddmAllocation *>(&gfxAllocation)->fragmentsStorage.fragmentStorageData[allocationId].osHandleStorage->handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CommandStreamReceiver::makeResident(gfxAllocation);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-09-14 16:39:21 +08:00
|
|
|
void WddmCommandStreamReceiver<GfxFamily>::processResidency(ResidencyContainer &allocationsForResidency, OsContext &osContext) {
|
2018-09-25 17:34:16 +08:00
|
|
|
bool success = getMemoryManager()->makeResidentResidencyAllocations(allocationsForResidency, osContext);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(!success);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
void WddmCommandStreamReceiver<GfxFamily>::processEviction() {
|
2018-09-12 16:44:35 +08:00
|
|
|
getMemoryManager()->makeNonResidentEvictionAllocations(this->getEvictionAllocations());
|
|
|
|
this->clearEvictionAllocations();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
WddmMemoryManager *WddmCommandStreamReceiver<GfxFamily>::getMemoryManager() {
|
|
|
|
return (WddmMemoryManager *)CommandStreamReceiver::getMemoryManager();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-09-06 16:53:35 +08:00
|
|
|
MemoryManager *WddmCommandStreamReceiver<GfxFamily>::createMemoryManager(bool enable64kbPages, bool enableLocalMemory) {
|
2018-09-10 22:11:28 +08:00
|
|
|
return memoryManager = new WddmMemoryManager(enable64kbPages, enableLocalMemory, this->wddm);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-08-27 21:48:29 +08:00
|
|
|
bool WddmCommandStreamReceiver<GfxFamily>::waitForFlushStamp(FlushStamp &flushStampToWait, OsContext &osContext) {
|
|
|
|
return wddm->waitFromCpu(flushStampToWait, *osContext.get());
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
GmmPageTableMngr *WddmCommandStreamReceiver<GfxFamily>::createPageTableManager() {
|
2018-05-17 17:47:35 +08:00
|
|
|
GMM_DEVICE_CALLBACKS_INT deviceCallbacks = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
GMM_TRANSLATIONTABLE_CALLBACKS ttCallbacks = {};
|
|
|
|
auto gdi = wddm->getGdi();
|
|
|
|
|
|
|
|
// clang-format off
|
2018-05-17 17:47:35 +08:00
|
|
|
deviceCallbacks.Adapter.KmtHandle = wddm->getAdapter();
|
|
|
|
deviceCallbacks.hDevice.KmtHandle = wddm->getDevice();
|
2018-08-17 19:38:09 +08:00
|
|
|
deviceCallbacks.hCsr = static_cast<CommandStreamReceiverHw<GfxFamily> *>(this);
|
2017-12-21 07:45:38 +08:00
|
|
|
deviceCallbacks.PagingQueue = wddm->getPagingQueue();
|
|
|
|
deviceCallbacks.PagingFence = wddm->getPagingQueueSyncObject();
|
|
|
|
|
2018-05-17 17:47:35 +08:00
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnAllocate = gdi->createAllocation;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnDeallocate = gdi->destroyAllocation;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnMapGPUVA = gdi->mapGpuVirtualAddress;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnMakeResident = gdi->makeResident;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnEvict = gdi->evict;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnReserveGPUVA = gdi->reserveGpuVirtualAddress;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnUpdateGPUVA = gdi->updateGpuVirtualAddress;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnWaitFromCpu = gdi->waitForSynchronizationObjectFromCpu;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnLock = gdi->lock2;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnUnLock = gdi->unlock2;
|
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnEscape = gdi->escape;
|
2018-08-17 19:38:09 +08:00
|
|
|
deviceCallbacks.DevCbPtrs.KmtCbPtrs.pfnNotifyAubCapture = DeviceCallbacks<GfxFamily>::notifyAubCapture;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
ttCallbacks.pfWriteL3Adr = TTCallbacks<GfxFamily>::writeL3Address;
|
|
|
|
// clang-format on
|
|
|
|
|
2018-08-17 19:38:09 +08:00
|
|
|
GmmPageTableMngr *gmmPageTableMngr = GmmPageTableMngr::create(&deviceCallbacks, TT_TYPE::TRTT | TT_TYPE::AUXTT, &ttCallbacks);
|
|
|
|
this->wddm->resetPageTableManager(gmmPageTableMngr);
|
|
|
|
return gmmPageTableMngr;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
void WddmCommandStreamReceiver<GfxFamily>::initPageTableManagerRegisters(LinearStream &csr) {
|
2018-02-15 03:14:20 +08:00
|
|
|
if (wddm->getPageTableManager() && !pageTableManagerInitialized) {
|
|
|
|
wddm->getPageTableManager()->initContextTRTableRegister(this, GMM_ENGINE_TYPE::ENGINE_TYPE_RCS);
|
|
|
|
wddm->getPageTableManager()->initContextAuxTableRegister(this, GMM_ENGINE_TYPE::ENGINE_TYPE_RCS);
|
|
|
|
|
|
|
|
pageTableManagerInitialized = true;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-03-23 04:13:45 +08:00
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
void WddmCommandStreamReceiver<GfxFamily>::kmDafLockAllocations(ResidencyContainer *allocationsForResidency) {
|
2018-09-12 15:47:01 +08:00
|
|
|
auto &residencyAllocations = allocationsForResidency ? *allocationsForResidency : this->getResidencyAllocations();
|
2018-03-23 04:13:45 +08:00
|
|
|
|
|
|
|
for (uint32_t i = 0; i < residencyAllocations.size(); i++) {
|
2018-03-27 22:19:11 +08:00
|
|
|
auto graphicsAllocation = residencyAllocations[i];
|
2018-07-05 22:31:57 +08:00
|
|
|
if ((GraphicsAllocation::AllocationType::LINEAR_STREAM == graphicsAllocation->getAllocationType()) ||
|
|
|
|
(GraphicsAllocation::AllocationType::FILL_PATTERN == graphicsAllocation->getAllocationType())) {
|
2018-03-27 22:19:11 +08:00
|
|
|
wddm->kmDafLock(static_cast<WddmAllocation *>(graphicsAllocation));
|
2018-03-23 04:13:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
} // namespace OCLRT
|