2018-08-10 16:41:44 +02:00
|
|
|
/*
|
2024-01-29 13:10:58 +00:00
|
|
|
* Copyright (C) 2018-2024 Intel Corporation
|
2018-09-18 09:11:08 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
|
*
|
|
|
|
|
*/
|
2018-08-10 16:41:44 +02:00
|
|
|
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
|
2019-02-27 11:39:32 +01:00
|
|
|
|
2022-12-01 19:42:57 +00:00
|
|
|
#include "shared/source/command_stream/preemption_mode.h"
|
2022-11-23 15:09:23 +00:00
|
|
|
#include "shared/source/debug_settings/debug_settings_manager.h"
|
2020-04-02 11:28:38 +02:00
|
|
|
#include "shared/source/helpers/constants.h"
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/os_interface/windows/gdi_interface.h"
|
|
|
|
|
#include "shared/source/os_interface/windows/os_context_win.h"
|
2023-01-23 14:55:52 +00:00
|
|
|
#include "shared/source/os_interface/windows/wddm/um_km_data_temp_storage.h"
|
2023-01-24 12:14:14 +00:00
|
|
|
#include "shared/source/os_interface/windows/wddm/um_km_data_translator.h"
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
2018-08-10 16:41:44 +02:00
|
|
|
|
2019-03-26 11:59:46 +01:00
|
|
|
using namespace NEO;
|
2018-09-12 12:43:15 +02:00
|
|
|
|
2019-12-17 15:26:00 +01:00
|
|
|
bool WddmInterface::createMonitoredFence(MonitoredFence &monitorFence) {
|
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2022-05-12 14:04:41 +00:00
|
|
|
D3DKMT_CREATESYNCHRONIZATIONOBJECT2 createSynchronizationObject = {0};
|
|
|
|
|
createSynchronizationObject.hDevice = wddm.getDeviceHandle();
|
|
|
|
|
createSynchronizationObject.Info.Type = D3DDDI_MONITORED_FENCE;
|
|
|
|
|
createSynchronizationObject.Info.MonitoredFence.InitialFenceValue = 0;
|
2018-08-10 16:41:44 +02:00
|
|
|
|
2022-05-12 14:04:41 +00:00
|
|
|
status = wddm.getGdi()->createSynchronizationObject2(&createSynchronizationObject);
|
2019-12-17 15:26:00 +01:00
|
|
|
DEBUG_BREAK_IF(STATUS_SUCCESS != status);
|
2018-08-10 16:41:44 +02:00
|
|
|
|
2022-05-12 14:04:41 +00:00
|
|
|
monitorFence.fenceHandle = createSynchronizationObject.hSyncObject;
|
|
|
|
|
monitorFence.cpuAddress = reinterpret_cast<uint64_t *>(createSynchronizationObject.Info.MonitoredFence.FenceValueCPUVirtualAddress);
|
|
|
|
|
monitorFence.gpuAddress = createSynchronizationObject.Info.MonitoredFence.FenceValueGPUVirtualAddress;
|
2018-08-10 16:41:44 +02:00
|
|
|
|
2019-12-17 15:26:00 +01:00
|
|
|
return status == STATUS_SUCCESS;
|
2018-08-10 16:41:44 +02:00
|
|
|
}
|
2019-12-17 15:26:00 +01:00
|
|
|
void WddmInterface::destroyMonitorFence(D3DKMT_HANDLE fenceHandle) {
|
2019-12-13 15:47:45 +01:00
|
|
|
D3DKMT_DESTROYSYNCHRONIZATIONOBJECT destroySyncObject = {0};
|
|
|
|
|
destroySyncObject.hSyncObject = fenceHandle;
|
2021-06-09 13:53:41 +00:00
|
|
|
[[maybe_unused]] NTSTATUS status = wddm.getGdi()->destroySynchronizationObject(&destroySyncObject);
|
2019-12-13 15:47:45 +01:00
|
|
|
DEBUG_BREAK_IF(STATUS_SUCCESS != status);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-17 15:26:00 +01:00
|
|
|
bool WddmInterface20::createHwQueue(OsContextWin &osContext) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
void WddmInterface20::destroyHwQueue(D3DKMT_HANDLE hwQueue) {}
|
|
|
|
|
|
|
|
|
|
bool WddmInterface20::createMonitoredFence(OsContextWin &osContext) {
|
|
|
|
|
auto &residencyController = osContext.getResidencyController();
|
|
|
|
|
MonitoredFence &monitorFence = residencyController.getMonitoredFence();
|
|
|
|
|
bool ret = WddmInterface::createMonitoredFence(monitorFence);
|
|
|
|
|
|
|
|
|
|
monitorFence.currentFenceValue = 1;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WddmInterface20::destroyMonitorFence(MonitoredFence &monitorFence) {
|
|
|
|
|
WddmInterface::destroyMonitorFence(monitorFence.fenceHandle);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-19 20:12:09 +00:00
|
|
|
bool WddmInterface20::hwQueuesSupported() {
|
2018-08-10 16:41:44 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:42:13 +01:00
|
|
|
bool WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) {
|
2022-05-12 14:04:41 +00:00
|
|
|
D3DKMT_SUBMITCOMMAND submitCommand = {0};
|
2018-08-10 16:41:44 +02:00
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
|
2022-05-12 14:04:41 +00:00
|
|
|
submitCommand.Commands = commandBuffer;
|
|
|
|
|
submitCommand.CommandLength = static_cast<UINT>(size);
|
|
|
|
|
submitCommand.BroadcastContextCount = 1;
|
|
|
|
|
submitCommand.BroadcastContext[0] = submitArguments.contextHandle;
|
2023-11-30 08:32:25 +00:00
|
|
|
submitCommand.Flags.NullRendering = (UINT)debugManager.flags.EnableNullHardware.get();
|
2018-08-10 16:41:44 +02:00
|
|
|
|
|
|
|
|
COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast<COMMAND_BUFFER_HEADER *>(commandHeader);
|
|
|
|
|
|
2019-12-16 15:42:13 +01:00
|
|
|
pHeader->MonitorFenceVA = submitArguments.monitorFence->gpuAddress;
|
|
|
|
|
pHeader->MonitorFenceValue = submitArguments.monitorFence->currentFenceValue;
|
2018-08-10 16:41:44 +02:00
|
|
|
|
|
|
|
|
// Note: Private data should be the CPU VA Address
|
2021-05-02 22:41:01 +02:00
|
|
|
UmKmDataTempStorage<COMMAND_BUFFER_HEADER> internalRepresentation;
|
|
|
|
|
if (wddm.getHwDeviceId()->getUmKmDataTranslator()->enabled()) {
|
|
|
|
|
internalRepresentation.resize(wddm.getHwDeviceId()->getUmKmDataTranslator()->getSizeForCommandBufferHeaderDataInternalRepresentation());
|
2021-09-27 15:17:26 +02:00
|
|
|
bool translated = wddm.getHwDeviceId()->getUmKmDataTranslator()->translateCommandBufferHeaderDataToInternalRepresentation(internalRepresentation.data(), internalRepresentation.size(), *pHeader);
|
2021-05-02 22:41:01 +02:00
|
|
|
UNRECOVERABLE_IF(false == translated);
|
2022-05-12 14:04:41 +00:00
|
|
|
submitCommand.pPrivateDriverData = internalRepresentation.data();
|
|
|
|
|
submitCommand.PrivateDriverDataSize = static_cast<uint32_t>(internalRepresentation.size());
|
2021-05-02 22:41:01 +02:00
|
|
|
} else {
|
2022-05-12 14:04:41 +00:00
|
|
|
submitCommand.pPrivateDriverData = pHeader;
|
|
|
|
|
submitCommand.PrivateDriverDataSize = sizeof(COMMAND_BUFFER_HEADER);
|
2021-05-02 22:41:01 +02:00
|
|
|
}
|
2018-08-10 16:41:44 +02:00
|
|
|
|
2022-05-12 14:04:41 +00:00
|
|
|
status = wddm.getGdi()->submitCommand(&submitCommand);
|
2018-08-10 16:41:44 +02:00
|
|
|
|
|
|
|
|
return STATUS_SUCCESS == status;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-27 11:17:17 +01:00
|
|
|
bool WddmInterface23::createHwQueue(OsContextWin &osContext) {
|
2018-08-10 16:41:44 +02:00
|
|
|
D3DKMT_CREATEHWQUEUE createHwQueue = {};
|
|
|
|
|
|
|
|
|
|
if (!wddm.getGdi()->setupHwQueueProcAddresses()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-01 12:21:30 +01:00
|
|
|
createHwQueue.hHwContext = osContext.getWddmContextHandle();
|
2019-02-27 11:17:17 +01:00
|
|
|
if (osContext.getPreemptionMode() >= PreemptionMode::MidBatch) {
|
2021-05-26 23:45:38 +02:00
|
|
|
createHwQueue.Flags.DisableGpuTimeout = wddm.getEnablePreemptionRegValue();
|
2018-08-10 16:41:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto status = wddm.getGdi()->createHwQueue(&createHwQueue);
|
|
|
|
|
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
|
2019-09-13 08:13:02 +02:00
|
|
|
osContext.setHwQueue({createHwQueue.hHwQueue, createHwQueue.hHwQueueProgressFence, createHwQueue.HwQueueProgressFenceCPUVirtualAddress,
|
|
|
|
|
createHwQueue.HwQueueProgressFenceGPUVirtualAddress});
|
2018-08-10 16:41:44 +02:00
|
|
|
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-13 08:13:02 +02:00
|
|
|
bool WddmInterface23::createMonitoredFence(OsContextWin &osContext) {
|
|
|
|
|
auto &residencyController = osContext.getResidencyController();
|
|
|
|
|
auto hwQueue = osContext.getHwQueue();
|
|
|
|
|
residencyController.resetMonitoredFenceParams(hwQueue.progressFenceHandle,
|
|
|
|
|
reinterpret_cast<uint64_t *>(hwQueue.progressFenceCpuVA),
|
|
|
|
|
hwQueue.progressFenceGpuVA);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-17 15:26:00 +01:00
|
|
|
void WddmInterface23::destroyMonitorFence(MonitoredFence &monitorFence) {
|
2019-12-13 15:47:45 +01:00
|
|
|
}
|
|
|
|
|
|
2018-09-12 12:43:15 +02:00
|
|
|
void WddmInterface23::destroyHwQueue(D3DKMT_HANDLE hwQueue) {
|
2018-08-21 17:36:08 +02:00
|
|
|
if (hwQueue) {
|
2018-08-10 16:41:44 +02:00
|
|
|
D3DKMT_DESTROYHWQUEUE destroyHwQueue = {};
|
2018-08-21 17:36:08 +02:00
|
|
|
destroyHwQueue.hHwQueue = hwQueue;
|
2018-08-10 16:41:44 +02:00
|
|
|
|
2021-05-20 13:48:33 +00:00
|
|
|
[[maybe_unused]] auto status = wddm.getGdi()->destroyHwQueue(&destroyHwQueue);
|
2018-08-10 16:41:44 +02:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-19 20:12:09 +00:00
|
|
|
bool WddmInterface23::hwQueuesSupported() {
|
2018-08-10 16:41:44 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:42:13 +01:00
|
|
|
bool WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) {
|
2018-08-10 16:41:44 +02:00
|
|
|
D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommand = {};
|
2019-12-16 15:42:13 +01:00
|
|
|
submitCommand.hHwQueue = submitArguments.hwQueueHandle;
|
|
|
|
|
submitCommand.HwQueueProgressFenceId = submitArguments.monitorFence->currentFenceValue;
|
2018-08-10 16:41:44 +02:00
|
|
|
submitCommand.CommandBuffer = commandBuffer;
|
|
|
|
|
submitCommand.CommandLength = static_cast<UINT>(size);
|
|
|
|
|
|
|
|
|
|
submitCommand.pPrivateDriverData = commandHeader;
|
2020-05-27 17:54:15 +02:00
|
|
|
submitCommand.PrivateDriverDataSize = sizeof(COMMAND_BUFFER_HEADER);
|
2020-05-08 12:06:30 +02:00
|
|
|
|
2023-11-30 08:32:25 +00:00
|
|
|
if (!debugManager.flags.UseCommandBufferHeaderSizeForWddmQueueSubmission.get()) {
|
2020-05-27 17:54:15 +02:00
|
|
|
submitCommand.PrivateDriverDataSize = MemoryConstants::pageSize;
|
2020-05-08 12:06:30 +02:00
|
|
|
}
|
2018-08-10 16:41:44 +02:00
|
|
|
|
|
|
|
|
auto status = wddm.getGdi()->submitCommandToHwQueue(&submitCommand);
|
|
|
|
|
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
|
}
|
2024-01-29 13:10:58 +00:00
|
|
|
|
|
|
|
|
bool NEO::WddmInterface23::createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) {
|
|
|
|
|
MonitoredFence monitorFenceForResidency{};
|
|
|
|
|
auto ret = WddmInterface::createMonitoredFence(monitorFenceForResidency);
|
|
|
|
|
auto &residencyController = osContext.getResidencyController();
|
|
|
|
|
residencyController.resetMonitoredFenceParams(monitorFenceForResidency.fenceHandle,
|
|
|
|
|
const_cast<uint64_t *>(monitorFenceForResidency.cpuAddress),
|
|
|
|
|
monitorFenceForResidency.gpuAddress);
|
|
|
|
|
|
|
|
|
|
auto hwQueue = osContext.getHwQueue();
|
|
|
|
|
monitorFence.cpuAddress = reinterpret_cast<uint64_t *>(hwQueue.progressFenceCpuVA);
|
|
|
|
|
monitorFence.currentFenceValue = 1u;
|
|
|
|
|
monitorFence.lastSubmittedFence = 0u;
|
|
|
|
|
monitorFence.gpuAddress = hwQueue.progressFenceGpuVA;
|
|
|
|
|
monitorFence.fenceHandle = hwQueue.progressFenceHandle;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|