/* * Copyright (C) 2017-2020 Intel Corporation * * SPDX-License-Identifier: MIT * */ // 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 "command_stream/linear_stream.h" #include "command_stream/preemption.h" #include "direct_submission/dispatchers/blitter_dispatcher.h" #include "direct_submission/dispatchers/render_dispatcher.h" #include "direct_submission/windows/wddm_direct_submission.h" #include "gmm_helper/page_table_mngr.h" #include "helpers/flush_stamp.h" #include "helpers/hw_cmds.h" #include "helpers/ptr_math.h" #include "helpers/windows/gmm_callbacks.h" #include "os_interface/windows/wddm/wddm.h" #include "opencl/source/os_interface/windows/wddm_device_command_stream.h" #pragma warning(pop) #include "os_interface/windows/gdi_interface.h" #include "os_interface/windows/os_context_win.h" #include "os_interface/windows/os_interface.h" #include "os_interface/windows/wddm_memory_manager.h" namespace NEO { // Initialize COMMAND_BUFFER_HEADER Type PatchList Streamer Perf Tag DECLARE_COMMAND_BUFFER(CommandBufferHeader, UMD_OCL, FALSE, FALSE, PERFTAG_OCL); template WddmCommandStreamReceiver::WddmCommandStreamReceiver(ExecutionEnvironment &executionEnvironment, uint32_t rootDeviceIndex) : BaseClass(executionEnvironment, rootDeviceIndex) { notifyAubCaptureImpl = DeviceCallbacks::notifyAubCapture; this->wddm = executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->osInterface->get()->getWddm(); PreemptionMode preemptionMode = PreemptionHelper::getDefaultPreemptionMode(peekHwInfo()); commandBufferHeader = new COMMAND_BUFFER_HEADER; *commandBufferHeader = CommandBufferHeader; if (preemptionMode != PreemptionMode::Disabled) { commandBufferHeader->NeedsMidBatchPreEmptionSupport = true; } this->dispatchMode = DispatchMode::BatchedDispatch; if (DebugManager.flags.CsrDispatchMode.get()) { this->dispatchMode = (DispatchMode)DebugManager.flags.CsrDispatchMode.get(); } } template WddmCommandStreamReceiver::~WddmCommandStreamReceiver() { if (commandBufferHeader) delete commandBufferHeader; } template bool WddmCommandStreamReceiver::flush(BatchBuffer &batchBuffer, ResidencyContainer &allocationsForResidency) { auto commandStreamAddress = ptrOffset(batchBuffer.commandBufferAllocation->getGpuAddress(), batchBuffer.startOffset); allocationsForResidency.push_back(batchBuffer.commandBufferAllocation); batchBuffer.commandBufferAllocation->updateResidencyTaskCount(this->taskCount, this->osContext->getContextId()); this->processResidency(allocationsForResidency, 0u); if (directSubmission.get()) { return directSubmission->dispatchCommandBuffer(batchBuffer, *(flushStamp.get())); } COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast(commandBufferHeader); pHeader->RequiresCoherency = batchBuffer.requiresCoherency; pHeader->UmdRequestedSliceState = 0; pHeader->UmdRequestedEUCount = wddm->getGtSysInfo()->EUCount / wddm->getGtSysInfo()->SubSliceCount; const uint32_t maxRequestedSubsliceCount = 7; switch (batchBuffer.throttle) { case QueueThrottle::LOW: case QueueThrottle::MEDIUM: pHeader->UmdRequestedSubsliceCount = 0; break; case QueueThrottle::HIGH: pHeader->UmdRequestedSubsliceCount = (wddm->getGtSysInfo()->SubSliceCount <= maxRequestedSubsliceCount) ? wddm->getGtSysInfo()->SubSliceCount : 0; break; } if (wddm->isKmDafEnabled()) { this->kmDafLockAllocations(allocationsForResidency); } auto osContextWin = static_cast(osContext); WddmSubmitArguments submitArgs = {}; submitArgs.contextHandle = osContextWin->getWddmContextHandle(); submitArgs.hwQueueHandle = osContextWin->getHwQueue().handle; submitArgs.monitorFence = &osContextWin->getResidencyController().getMonitoredFence(); auto status = wddm->submit(commandStreamAddress, batchBuffer.usedSize - batchBuffer.startOffset, commandBufferHeader, submitArgs); flushStamp->setStamp(submitArgs.monitorFence->lastSubmittedFence); return status; } template void WddmCommandStreamReceiver::processResidency(const ResidencyContainer &allocationsForResidency, uint32_t handleId) { bool success = static_cast(osContext)->getResidencyController().makeResidentResidencyAllocations(allocationsForResidency); DEBUG_BREAK_IF(!success); } template void WddmCommandStreamReceiver::processEviction() { static_cast(osContext)->getResidencyController().makeNonResidentEvictionAllocations(this->getEvictionAllocations()); this->getEvictionAllocations().clear(); } template WddmMemoryManager *WddmCommandStreamReceiver::getMemoryManager() const { return static_cast(CommandStreamReceiver::getMemoryManager()); } template bool WddmCommandStreamReceiver::waitForFlushStamp(FlushStamp &flushStampToWait) { return wddm->waitFromCpu(flushStampToWait, static_cast(osContext)->getResidencyController().getMonitoredFence()); } template GmmPageTableMngr *WddmCommandStreamReceiver::createPageTableManager() { GMM_TRANSLATIONTABLE_CALLBACKS ttCallbacks = {}; ttCallbacks.pfWriteL3Adr = TTCallbacks::writeL3Address; auto rootDeviceEnvironment = executionEnvironment.rootDeviceEnvironments[this->rootDeviceIndex].get(); GmmPageTableMngr *gmmPageTableMngr = GmmPageTableMngr::create(executionEnvironment.getGmmClientContext(), TT_TYPE::AUXTT, &ttCallbacks); gmmPageTableMngr->setCsrHandle(this); rootDeviceEnvironment->pageTableManager.reset(gmmPageTableMngr); return gmmPageTableMngr; } template void WddmCommandStreamReceiver::kmDafLockAllocations(ResidencyContainer &allocationsForResidency) { for (auto &graphicsAllocation : allocationsForResidency) { if ((GraphicsAllocation::AllocationType::LINEAR_STREAM == graphicsAllocation->getAllocationType()) || (GraphicsAllocation::AllocationType::FILL_PATTERN == graphicsAllocation->getAllocationType()) || (GraphicsAllocation::AllocationType::COMMAND_BUFFER == graphicsAllocation->getAllocationType())) { wddm->kmDafLock(static_cast(graphicsAllocation)->getDefaultHandle()); } } } template bool WddmCommandStreamReceiver::initDirectSubmission(Device &device, OsContext &osContext) { bool ret = true; if (DebugManager.flags.EnableDirectSubmission.get() == 1) { auto contextEngineType = osContext.getEngineType(); const DirectSubmissionProperties &directSubmissionProperty = device.getHardwareInfo().capabilityTable.directSubmissionEngines.data[contextEngineType]; if (directSubmissionProperty.engineSupported) { if (contextEngineType == ENGINE_TYPE_BCS) { directSubmission = std::make_unique>(device, std::make_unique>(), osContext); } else { directSubmission = std::make_unique>(device, std::make_unique>(), osContext); } ret = directSubmission->initialize(directSubmissionProperty.submitOnInit); this->dispatchMode = DispatchMode::ImmediateDispatch; } } return ret; } } // namespace NEO