2018-08-10 22:41:44 +08:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
#include "runtime/memory_manager/memory_constants.h"
|
2018-08-10 22:41:44 +08:00
|
|
|
#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"
|
2018-08-21 23:36:08 +08:00
|
|
|
#include "runtime/os_interface/windows/os_context_win.h"
|
2018-08-10 22:41:44 +08:00
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
using namespace OCLRT;
|
|
|
|
|
|
|
|
bool WddmInterface20::createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) {
|
2018-08-10 22:41:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
2018-09-12 18:43:15 +08:00
|
|
|
void WddmInterface20::destroyHwQueue(D3DKMT_HANDLE hwQueue) {}
|
2018-08-10 22:41:44 +08:00
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
bool WddmInterface::createMonitoredFence(OsContextWin &osContext) {
|
2018-08-10 22:41:44 +08:00
|
|
|
NTSTATUS Status;
|
|
|
|
D3DKMT_CREATESYNCHRONIZATIONOBJECT2 CreateSynchronizationObject = {0};
|
|
|
|
CreateSynchronizationObject.hDevice = wddm.getDevice();
|
|
|
|
CreateSynchronizationObject.Info.Type = D3DDDI_MONITORED_FENCE;
|
|
|
|
CreateSynchronizationObject.Info.MonitoredFence.InitialFenceValue = 0;
|
|
|
|
|
|
|
|
Status = wddm.getGdi()->createSynchronizationObject2(&CreateSynchronizationObject);
|
|
|
|
|
|
|
|
DEBUG_BREAK_IF(STATUS_SUCCESS != Status);
|
|
|
|
|
2018-08-21 23:36:08 +08:00
|
|
|
osContext.resetMonitoredFenceParams(CreateSynchronizationObject.hSyncObject,
|
|
|
|
reinterpret_cast<uint64_t *>(CreateSynchronizationObject.Info.MonitoredFence.FenceValueCPUVirtualAddress),
|
|
|
|
CreateSynchronizationObject.Info.MonitoredFence.FenceValueGPUVirtualAddress);
|
2018-08-10 22:41:44 +08:00
|
|
|
|
|
|
|
return Status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
const bool WddmInterface20::hwQueuesSupported() {
|
2018-08-10 22:41:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
bool WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) {
|
2018-08-10 22:41:44 +08:00
|
|
|
D3DKMT_SUBMITCOMMAND SubmitCommand = {0};
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
2018-08-27 21:48:29 +08:00
|
|
|
auto monitoredFence = osContext.getMonitoredFence();
|
2018-08-10 22:41:44 +08:00
|
|
|
SubmitCommand.Commands = commandBuffer;
|
|
|
|
SubmitCommand.CommandLength = static_cast<UINT>(size);
|
|
|
|
SubmitCommand.BroadcastContextCount = 1;
|
2018-08-21 23:36:08 +08:00
|
|
|
SubmitCommand.BroadcastContext[0] = osContext.getContext();
|
2018-08-10 22:41:44 +08:00
|
|
|
SubmitCommand.Flags.NullRendering = (UINT)DebugManager.flags.EnableNullHardware.get();
|
|
|
|
|
|
|
|
COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast<COMMAND_BUFFER_HEADER *>(commandHeader);
|
|
|
|
|
|
|
|
pHeader->MonitorFenceVA = monitoredFence.gpuAddress;
|
|
|
|
pHeader->MonitorFenceValue = monitoredFence.currentFenceValue;
|
|
|
|
|
|
|
|
// Note: Private data should be the CPU VA Address
|
|
|
|
SubmitCommand.pPrivateDriverData = commandHeader;
|
|
|
|
SubmitCommand.PrivateDriverDataSize = sizeof(COMMAND_BUFFER_HEADER);
|
|
|
|
|
|
|
|
status = wddm.getGdi()->submitCommand(&SubmitCommand);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS == status;
|
|
|
|
}
|
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
bool WddmInterface23::createHwQueue(PreemptionMode preemptionMode, OsContextWin &osContext) {
|
2018-08-10 22:41:44 +08:00
|
|
|
D3DKMT_CREATEHWQUEUE createHwQueue = {};
|
|
|
|
|
|
|
|
if (!wddm.getGdi()->setupHwQueueProcAddresses()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-21 23:36:08 +08:00
|
|
|
createHwQueue.hHwContext = osContext.getContext();
|
2018-08-10 22:41:44 +08:00
|
|
|
if (preemptionMode >= PreemptionMode::MidBatch) {
|
|
|
|
createHwQueue.Flags.DisableGpuTimeout = wddm.readEnablePreemptionRegKey();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto status = wddm.getGdi()->createHwQueue(&createHwQueue);
|
|
|
|
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
|
2018-08-21 23:36:08 +08:00
|
|
|
osContext.setHwQueue(createHwQueue.hHwQueue);
|
2018-08-10 22:41:44 +08:00
|
|
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
void WddmInterface23::destroyHwQueue(D3DKMT_HANDLE hwQueue) {
|
2018-08-21 23:36:08 +08:00
|
|
|
if (hwQueue) {
|
2018-08-10 22:41:44 +08:00
|
|
|
D3DKMT_DESTROYHWQUEUE destroyHwQueue = {};
|
2018-08-21 23:36:08 +08:00
|
|
|
destroyHwQueue.hHwQueue = hwQueue;
|
2018-08-10 22:41:44 +08:00
|
|
|
|
|
|
|
auto status = wddm.getGdi()->destroyHwQueue(&destroyHwQueue);
|
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
const bool WddmInterface23::hwQueuesSupported() {
|
2018-08-10 22:41:44 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-09-12 18:43:15 +08:00
|
|
|
bool WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) {
|
2018-08-27 21:48:29 +08:00
|
|
|
auto monitoredFence = osContext.getMonitoredFence();
|
2018-08-10 22:41:44 +08:00
|
|
|
|
|
|
|
D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommand = {};
|
2018-08-21 23:36:08 +08:00
|
|
|
submitCommand.hHwQueue = osContext.getHwQueue();
|
2018-08-10 22:41:44 +08:00
|
|
|
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;
|
2018-09-12 18:43:15 +08:00
|
|
|
submitCommand.PrivateDriverDataSize = MemoryConstants::pageSize;
|
2018-08-10 22:41:44 +08:00
|
|
|
|
|
|
|
auto status = wddm.getGdi()->submitCommandToHwQueue(&submitCommand);
|
|
|
|
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|