2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2023-01-02 16:41:11 +08:00
|
|
|
* Copyright (C) 2018-2023 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
|
|
|
|
2021-09-29 23:59:41 +08:00
|
|
|
#include "shared/source/command_stream/command_stream_receiver.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/command_stream/preemption.h"
|
2020-08-18 20:59:44 +08:00
|
|
|
#include "shared/source/execution_environment/execution_environment.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/execution_environment/root_device_environment.h"
|
2021-06-29 01:36:16 +08:00
|
|
|
#include "shared/source/gmm_helper/client_context/gmm_client_context.h"
|
2023-01-23 22:55:52 +08:00
|
|
|
#include "shared/source/gmm_helper/client_context/gmm_handle_allocator.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/gmm_helper/gmm.h"
|
|
|
|
#include "shared/source/gmm_helper/gmm_helper.h"
|
|
|
|
#include "shared/source/gmm_helper/page_table_mngr.h"
|
|
|
|
#include "shared/source/gmm_helper/resource_info.h"
|
2021-05-14 01:46:01 +08:00
|
|
|
#include "shared/source/helpers/api_specific_config.h"
|
2023-02-02 00:23:01 +08:00
|
|
|
#include "shared/source/helpers/gfx_core_helper.h"
|
2020-09-14 21:14:11 +08:00
|
|
|
#include "shared/source/helpers/heap_assigner.h"
|
2023-02-06 17:05:43 +08:00
|
|
|
#include "shared/source/helpers/hw_info.h"
|
2022-08-09 21:34:45 +08:00
|
|
|
#include "shared/source/helpers/mt_helpers.h"
|
2021-05-20 04:12:09 +08:00
|
|
|
#include "shared/source/helpers/string.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/windows/gmm_callbacks.h"
|
2022-12-16 00:01:37 +08:00
|
|
|
#include "shared/source/memory_manager/gfx_partition.h"
|
2023-03-10 20:28:11 +08:00
|
|
|
#include "shared/source/os_interface/product_helper.h"
|
2022-02-12 00:28:08 +08:00
|
|
|
#include "shared/source/os_interface/sys_calls_common.h"
|
2020-03-17 18:55:53 +08:00
|
|
|
#include "shared/source/os_interface/windows/driver_info_windows.h"
|
2021-05-27 05:45:38 +08:00
|
|
|
#include "shared/source/os_interface/windows/dxcore_wrapper.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/windows/gdi_interface.h"
|
|
|
|
#include "shared/source/os_interface/windows/kmdaf_listener.h"
|
|
|
|
#include "shared/source/os_interface/windows/os_context_win.h"
|
2020-03-17 14:26:46 +08:00
|
|
|
#include "shared/source/os_interface/windows/os_environment_win.h"
|
2021-06-05 18:09:29 +08:00
|
|
|
#include "shared/source/os_interface/windows/sharedata_wrapper.h"
|
2021-05-26 00:42:36 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm/adapter_factory.h"
|
2023-01-23 22:55:52 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm/um_km_data_temp_storage.h"
|
2021-05-03 04:41:01 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm/um_km_data_translator.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
|
2020-03-17 19:19:38 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm/wddm_residency_logger.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm_allocation.h"
|
|
|
|
#include "shared/source/os_interface/windows/wddm_engine_mapper.h"
|
2021-05-20 04:12:09 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm_memory_manager.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/windows/wddm_residency_allocations_container.h"
|
|
|
|
#include "shared/source/sku_info/operations/windows/sku_info_receiver.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-02-27 18:39:32 +08:00
|
|
|
#include "gmm_memory.h"
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
namespace NEO {
|
2021-05-11 17:18:31 +08:00
|
|
|
extern Wddm::CreateDXGIFactoryFcn getCreateDxgiFactory();
|
2021-05-11 23:07:20 +08:00
|
|
|
extern Wddm::DXCoreCreateAdapterFactoryFcn getDXCoreCreateAdapterFactory();
|
2017-12-21 07:45:38 +08:00
|
|
|
extern Wddm::GetSystemInfoFcn getGetSystemInfo();
|
|
|
|
|
2021-05-11 23:07:20 +08:00
|
|
|
Wddm::DXCoreCreateAdapterFactoryFcn Wddm::dXCoreCreateAdapterFactory = getDXCoreCreateAdapterFactory();
|
2021-05-11 17:18:31 +08:00
|
|
|
Wddm::CreateDXGIFactoryFcn Wddm::createDxgiFactory = getCreateDxgiFactory();
|
2017-12-21 07:45:38 +08:00
|
|
|
Wddm::GetSystemInfoFcn Wddm::getSystemInfo = getGetSystemInfo();
|
|
|
|
|
2021-10-21 20:37:31 +08:00
|
|
|
Wddm::Wddm(std::unique_ptr<HwDeviceIdWddm> &&hwDeviceIdIn, RootDeviceEnvironment &rootDeviceEnvironment)
|
2021-05-21 07:17:57 +08:00
|
|
|
: DriverModel(DriverModelType::WDDM), hwDeviceId(std::move(hwDeviceIdIn)), rootDeviceEnvironment(rootDeviceEnvironment) {
|
2020-02-07 17:29:56 +08:00
|
|
|
UNRECOVERABLE_IF(!hwDeviceId);
|
2018-03-03 04:43:37 +08:00
|
|
|
featureTable.reset(new FeatureTable());
|
2019-05-08 22:00:24 +08:00
|
|
|
workaroundTable.reset(new WorkaroundTable());
|
2018-03-03 04:43:37 +08:00
|
|
|
gtSystemInfo.reset(new GT_SYSTEM_INFO);
|
|
|
|
gfxPlatform.reset(new PLATFORM);
|
|
|
|
memset(gtSystemInfo.get(), 0, sizeof(*gtSystemInfo));
|
|
|
|
memset(gfxPlatform.get(), 0, sizeof(*gfxPlatform));
|
2021-05-27 05:45:38 +08:00
|
|
|
this->enablePreemptionRegValue = NEO::readEnablePreemptionRegKey();
|
2018-01-31 18:22:13 +08:00
|
|
|
kmDafListener = std::unique_ptr<KmDafListener>(new KmDafListener);
|
2019-07-12 22:50:14 +08:00
|
|
|
temporaryResources = std::make_unique<WddmResidentAllocationsContainer>(this);
|
2021-09-27 21:17:26 +08:00
|
|
|
osMemory = OSMemory::create();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Wddm::~Wddm() {
|
2019-10-30 21:25:58 +08:00
|
|
|
temporaryResources.reset();
|
2017-12-21 07:45:38 +08:00
|
|
|
destroyPagingQueue();
|
|
|
|
destroyDevice();
|
2019-11-12 21:29:39 +08:00
|
|
|
UNRECOVERABLE_IF(temporaryResources.get())
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-02-10 18:15:34 +08:00
|
|
|
bool Wddm::init() {
|
2020-04-08 17:45:54 +08:00
|
|
|
if (!rootDeviceEnvironment.osInterface) {
|
|
|
|
rootDeviceEnvironment.osInterface = std::make_unique<OSInterface>();
|
2021-05-21 07:17:57 +08:00
|
|
|
rootDeviceEnvironment.osInterface->setDriverModel(std::unique_ptr<DriverModel>(this));
|
2020-04-08 17:45:54 +08:00
|
|
|
}
|
2018-08-10 17:07:17 +08:00
|
|
|
if (!queryAdapterInfo()) {
|
2018-06-12 15:42:47 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-10 17:07:17 +08:00
|
|
|
auto productFamily = gfxPlatform->eProductFamily;
|
2018-06-12 15:42:47 +08:00
|
|
|
if (!hardwareInfoTable[productFamily]) {
|
|
|
|
return false;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2022-11-10 08:05:51 +08:00
|
|
|
|
|
|
|
auto hardwareInfo = rootDeviceEnvironment.getMutableHardwareInfo();
|
2020-02-10 18:15:34 +08:00
|
|
|
hardwareInfo->platform = *gfxPlatform;
|
|
|
|
hardwareInfo->featureTable = *featureTable;
|
|
|
|
hardwareInfo->workaroundTable = *workaroundTable;
|
|
|
|
hardwareInfo->gtSystemInfo = *gtSystemInfo;
|
|
|
|
hardwareInfo->capabilityTable = hardwareInfoTable[productFamily]->capabilityTable;
|
|
|
|
hardwareInfo->capabilityTable.maxRenderFrequency = maxRenderFrequency;
|
|
|
|
hardwareInfo->capabilityTable.instrumentationEnabled =
|
|
|
|
(hardwareInfo->capabilityTable.instrumentationEnabled && instrumentationEnabled);
|
2018-04-05 00:38:36 +08:00
|
|
|
|
2023-02-01 11:12:09 +08:00
|
|
|
rootDeviceEnvironment.initProductHelper();
|
2023-01-31 20:34:59 +08:00
|
|
|
rootDeviceEnvironment.initCompilerProductHelper();
|
2022-11-10 08:05:51 +08:00
|
|
|
auto &productHelper = rootDeviceEnvironment.getHelper<ProductHelper>();
|
|
|
|
productHelper.adjustPlatformForProductFamily(hardwareInfo);
|
2023-02-01 11:12:09 +08:00
|
|
|
rootDeviceEnvironment.initApiGfxCoreHelper();
|
|
|
|
rootDeviceEnvironment.initGfxCoreHelper();
|
2023-04-13 22:16:49 +08:00
|
|
|
rootDeviceEnvironment.initReleaseHelper();
|
2023-01-03 18:27:35 +08:00
|
|
|
|
2022-11-14 22:52:40 +08:00
|
|
|
if (productHelper.configureHwInfoWddm(hardwareInfo, hardwareInfo, rootDeviceEnvironment)) {
|
2019-07-08 19:30:31 +08:00
|
|
|
return false;
|
|
|
|
}
|
2022-11-10 08:05:51 +08:00
|
|
|
setPlatformSupportEvictIfNecessaryFlag(productHelper);
|
2018-06-12 15:42:47 +08:00
|
|
|
|
2020-02-10 18:15:34 +08:00
|
|
|
auto preemptionMode = PreemptionHelper::getDefaultPreemptionMode(*hardwareInfo);
|
2022-10-31 21:57:24 +08:00
|
|
|
populateIpVersion(*hardwareInfo);
|
2022-11-10 08:05:51 +08:00
|
|
|
|
2020-02-25 23:38:47 +08:00
|
|
|
rootDeviceEnvironment.initGmm();
|
2021-05-11 23:07:20 +08:00
|
|
|
this->rootDeviceEnvironment.getGmmClientContext()->setHandleAllocator(this->hwDeviceId->getUmKmDataTranslator()->createGmmHandleAllocator());
|
2019-07-11 00:35:06 +08:00
|
|
|
|
2021-07-21 16:47:43 +08:00
|
|
|
[[maybe_unused]] bool result = rootDeviceEnvironment.initAilConfiguration();
|
|
|
|
DEBUG_BREAK_IF(!result);
|
|
|
|
|
2019-12-17 21:29:28 +08:00
|
|
|
if (WddmVersion::WDDM_2_3 == getWddmVersion()) {
|
2019-07-08 19:30:31 +08:00
|
|
|
wddmInterface = std::make_unique<WddmInterface23>(*this);
|
|
|
|
} else {
|
|
|
|
wddmInterface = std::make_unique<WddmInterface20>(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!createDevice(preemptionMode)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!createPagingQueue()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!gmmMemory) {
|
2020-02-25 01:04:30 +08:00
|
|
|
gmmMemory.reset(GmmMemory::create(rootDeviceEnvironment.getGmmClientContext()));
|
2019-07-08 19:30:31 +08:00
|
|
|
}
|
|
|
|
|
2023-03-23 05:43:29 +08:00
|
|
|
buildTopologyMapping();
|
2022-07-28 21:09:14 +08:00
|
|
|
|
2019-07-08 19:30:31 +08:00
|
|
|
return configureDeviceAddressSpace();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-12-13 00:43:41 +08:00
|
|
|
void Wddm::setPlatformSupportEvictIfNecessaryFlag(const ProductHelper &productHelper) {
|
|
|
|
platformSupportsEvictIfNecessary = productHelper.isEvictionIfNecessaryFlagSupported();
|
2022-08-22 20:11:44 +08:00
|
|
|
int32_t overridePlatformSupportsEvictIfNecessary =
|
|
|
|
DebugManager.flags.PlaformSupportEvictIfNecessaryFlag.get();
|
|
|
|
if (overridePlatformSupportsEvictIfNecessary != -1) {
|
|
|
|
platformSupportsEvictIfNecessary = !!overridePlatformSupportsEvictIfNecessary;
|
2022-07-26 05:33:42 +08:00
|
|
|
}
|
2022-08-11 07:03:13 +08:00
|
|
|
forceEvictOnlyIfNecessary = DebugManager.flags.ForceEvictOnlyIfNecessaryFlag.get();
|
2022-07-26 05:33:42 +08:00
|
|
|
}
|
|
|
|
|
2022-07-28 21:09:14 +08:00
|
|
|
bool Wddm::buildTopologyMapping() {
|
|
|
|
|
|
|
|
TopologyMapping mapping;
|
|
|
|
if (!translateTopologyInfo(mapping)) {
|
2022-09-20 04:49:57 +08:00
|
|
|
PRINT_DEBUGGER_ERROR_LOG("translateTopologyInfo Failed\n", "");
|
|
|
|
return false;
|
2022-07-28 21:09:14 +08:00
|
|
|
}
|
|
|
|
this->topologyMap[0] = mapping;
|
|
|
|
|
2022-09-20 04:49:57 +08:00
|
|
|
return true;
|
2022-07-28 21:09:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Wddm::translateTopologyInfo(TopologyMapping &mapping) {
|
|
|
|
int sliceCount = 0;
|
|
|
|
int subSliceCount = 0;
|
|
|
|
int euCount = 0;
|
|
|
|
std::vector<int> sliceIndices;
|
|
|
|
auto gtSystemInfo = rootDeviceEnvironment.getHardwareInfo()->gtSystemInfo;
|
|
|
|
sliceIndices.reserve(gtSystemInfo.SliceCount);
|
2022-09-23 08:29:32 +08:00
|
|
|
auto hwInfo = rootDeviceEnvironment.getHardwareInfo();
|
2022-12-08 20:22:35 +08:00
|
|
|
const uint32_t highestEnabledSlice = NEO::GfxCoreHelper::getHighestEnabledSlice(*hwInfo);
|
2022-07-28 21:09:14 +08:00
|
|
|
|
2022-09-23 08:29:32 +08:00
|
|
|
for (uint32_t x = 0; x < std::max(highestEnabledSlice, hwInfo->gtSystemInfo.MaxSlicesSupported); x++) {
|
2022-07-28 21:09:14 +08:00
|
|
|
if (!gtSystemInfo.SliceInfo[x].Enabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
sliceIndices.push_back(x);
|
|
|
|
sliceCount++;
|
|
|
|
|
|
|
|
std::vector<int> subSliceIndices;
|
|
|
|
subSliceIndices.reserve((gtSystemInfo.SliceInfo[x].DualSubSliceEnabledCount) * GT_MAX_SUBSLICE_PER_DSS);
|
|
|
|
|
|
|
|
// subSliceIndex is used to track the index number of subslices from all DSS in this slice
|
|
|
|
int subSliceIndex = -1;
|
|
|
|
for (uint32_t dss = 0; dss < GT_MAX_DUALSUBSLICE_PER_SLICE; dss++) {
|
|
|
|
if (!gtSystemInfo.SliceInfo[x].DSSInfo[dss].Enabled) {
|
|
|
|
subSliceIndex += 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t y = 0; y < GT_MAX_SUBSLICE_PER_DSS; y++) {
|
|
|
|
subSliceIndex++;
|
|
|
|
if (!gtSystemInfo.SliceInfo[x].DSSInfo[dss].SubSlice[y].Enabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
subSliceCount++;
|
|
|
|
subSliceIndices.push_back(subSliceIndex);
|
|
|
|
|
|
|
|
euCount += gtSystemInfo.SliceInfo[x].DSSInfo[dss].SubSlice[y].EuEnabledCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// single slice available
|
|
|
|
if (sliceCount == 1) {
|
|
|
|
mapping.subsliceIndices = std::move(subSliceIndices);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sliceIndices.size()) {
|
|
|
|
mapping.sliceIndices = std::move(sliceIndices);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sliceCount != 1) {
|
|
|
|
mapping.subsliceIndices.clear();
|
|
|
|
}
|
2022-09-20 04:49:57 +08:00
|
|
|
PRINT_DEBUGGER_INFO_LOG("Topology Mapping: sliceCount=%d subSliceCount=%d euCount=%d\n", sliceCount, subSliceCount, euCount);
|
2022-07-28 21:09:14 +08:00
|
|
|
return (sliceCount && subSliceCount && euCount);
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
bool Wddm::queryAdapterInfo() {
|
|
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
2021-06-08 03:47:12 +08:00
|
|
|
ADAPTER_INFO_KMD adapterInfo = {};
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_QUERYADAPTERINFO queryAdapterInfo = {};
|
|
|
|
queryAdapterInfo.hAdapter = getAdapter();
|
|
|
|
queryAdapterInfo.Type = KMTQAITYPE_UMDRIVERPRIVATE;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2021-05-03 04:41:01 +08:00
|
|
|
if (hwDeviceId->getUmKmDataTranslator()->enabled()) {
|
2021-06-05 18:09:29 +08:00
|
|
|
UmKmDataTempStorage<ADAPTER_INFO_KMD, 1> internalRepresentation(hwDeviceId->getUmKmDataTranslator()->getSizeForAdapterInfoInternalRepresentation());
|
2022-05-12 22:04:41 +08:00
|
|
|
queryAdapterInfo.pPrivateDriverData = internalRepresentation.data();
|
|
|
|
queryAdapterInfo.PrivateDriverDataSize = static_cast<uint32_t>(internalRepresentation.size());
|
2021-05-03 04:41:01 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
status = getGdi()->queryAdapterInfo(&queryAdapterInfo);
|
2021-05-03 04:41:01 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
|
|
|
|
if (status == STATUS_SUCCESS) {
|
|
|
|
bool translated = hwDeviceId->getUmKmDataTranslator()->translateAdapterInfoFromInternalRepresentation(adapterInfo, internalRepresentation.data(), internalRepresentation.size());
|
|
|
|
status = translated ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
} else {
|
2022-05-12 22:04:41 +08:00
|
|
|
queryAdapterInfo.pPrivateDriverData = &adapterInfo;
|
|
|
|
queryAdapterInfo.PrivateDriverDataSize = sizeof(ADAPTER_INFO_KMD);
|
2021-05-03 04:41:01 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
status = getGdi()->queryAdapterInfo(&queryAdapterInfo);
|
2021-05-03 04:41:01 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
// translate
|
|
|
|
if (status == STATUS_SUCCESS) {
|
2018-03-03 04:43:37 +08:00
|
|
|
memcpy_s(gtSystemInfo.get(), sizeof(GT_SYSTEM_INFO), &adapterInfo.SystemInfo, sizeof(GT_SYSTEM_INFO));
|
|
|
|
memcpy_s(gfxPlatform.get(), sizeof(PLATFORM), &adapterInfo.GfxPlatform, sizeof(PLATFORM));
|
|
|
|
|
|
|
|
SkuInfoReceiver::receiveFtrTableFromAdapterInfo(featureTable.get(), &adapterInfo);
|
2019-05-08 22:00:24 +08:00
|
|
|
SkuInfoReceiver::receiveWaTableFromAdapterInfo(workaroundTable.get(), &adapterInfo);
|
2018-03-03 04:43:37 +08:00
|
|
|
|
|
|
|
memcpy_s(&gfxPartition, sizeof(gfxPartition), &adapterInfo.GfxPartition, sizeof(GMM_GFX_PARTITIONING));
|
2019-10-15 21:05:47 +08:00
|
|
|
memcpy_s(&adapterBDF, sizeof(adapterBDF), &adapterInfo.stAdapterBDF, sizeof(ADAPTER_BDF));
|
2018-03-03 04:43:37 +08:00
|
|
|
|
2020-08-24 07:55:47 +08:00
|
|
|
deviceRegistryPath = std::string(adapterInfo.DeviceRegistryPath, sizeof(adapterInfo.DeviceRegistryPath)).c_str();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-03-03 04:43:37 +08:00
|
|
|
systemSharedMemory = adapterInfo.SystemSharedMemory;
|
2019-07-29 20:32:37 +08:00
|
|
|
dedicatedVideoMemory = adapterInfo.DedicatedVideoMemory;
|
2018-03-03 04:43:37 +08:00
|
|
|
maxRenderFrequency = adapterInfo.MaxRenderFreq;
|
2021-02-02 02:37:13 +08:00
|
|
|
timestampFrequency = adapterInfo.GfxTimeStampFreq;
|
2018-03-03 04:43:37 +08:00
|
|
|
instrumentationEnabled = adapterInfo.Caps.InstrumentationIsEnabled != 0;
|
2022-08-04 19:29:25 +08:00
|
|
|
|
|
|
|
populateAdditionalAdapterInfoOptions(adapterInfo);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Wddm::createPagingQueue() {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_CREATEPAGINGQUEUE createPagingQueue = {};
|
|
|
|
createPagingQueue.hDevice = device;
|
|
|
|
createPagingQueue.Priority = D3DDDI_PAGINGQUEUE_PRIORITY_NORMAL;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
NTSTATUS status = getGdi()->createPagingQueue(&createPagingQueue);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (status == STATUS_SUCCESS) {
|
2022-05-12 22:04:41 +08:00
|
|
|
pagingQueue = createPagingQueue.hPagingQueue;
|
|
|
|
pagingQueueSyncObject = createPagingQueue.hSyncObject;
|
|
|
|
pagingFenceAddress = reinterpret_cast<UINT64 *>(createPagingQueue.FenceValueCPUVirtualAddress);
|
2020-03-17 19:19:38 +08:00
|
|
|
createPagingFenceLogger();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Wddm::destroyPagingQueue() {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DDDI_DESTROYPAGINGQUEUE destroyPagingQueue = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
if (pagingQueue) {
|
2022-05-12 22:04:41 +08:00
|
|
|
destroyPagingQueue.hPagingQueue = pagingQueue;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
[[maybe_unused]] NTSTATUS status = getGdi()->destroyPagingQueue(&destroyPagingQueue);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
pagingQueue = 0;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-12-10 17:30:39 +08:00
|
|
|
bool Wddm::createDevice(PreemptionMode preemptionMode) {
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_CREATEDEVICE createDevice = {};
|
2020-02-05 17:49:54 +08:00
|
|
|
if (hwDeviceId) {
|
2022-05-12 22:04:41 +08:00
|
|
|
createDevice.hAdapter = getAdapter();
|
|
|
|
createDevice.Flags.LegacyMode = FALSE;
|
2018-02-06 18:58:05 +08:00
|
|
|
if (preemptionMode >= PreemptionMode::MidBatch) {
|
2022-05-12 22:04:41 +08:00
|
|
|
createDevice.Flags.DisableGpuTimeout = getEnablePreemptionRegValue();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
status = getGdi()->createDevice(&createDevice);
|
2017-12-21 07:45:38 +08:00
|
|
|
if (status == STATUS_SUCCESS) {
|
2022-05-12 22:04:41 +08:00
|
|
|
device = createDevice.hDevice;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Wddm::destroyDevice() {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_DESTROYDEVICE destroyDevice = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
if (device) {
|
2022-05-12 22:04:41 +08:00
|
|
|
destroyDevice.hDevice = device;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
[[maybe_unused]] NTSTATUS status = getGdi()->destroyDevice(&destroyDevice);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
device = 0;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-05-03 04:41:01 +08:00
|
|
|
bool validDriverStorePath(OsEnvironmentWin &osEnvironment, D3DKMT_HANDLE adapter) {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_QUERYADAPTERINFO queryAdapterInfo = {};
|
2021-06-08 03:47:12 +08:00
|
|
|
ADAPTER_INFO_KMD adapterInfo = {};
|
2022-05-12 22:04:41 +08:00
|
|
|
queryAdapterInfo.hAdapter = adapter;
|
|
|
|
queryAdapterInfo.Type = KMTQAITYPE_UMDRIVERPRIVATE;
|
|
|
|
queryAdapterInfo.pPrivateDriverData = &adapterInfo;
|
|
|
|
queryAdapterInfo.PrivateDriverDataSize = sizeof(ADAPTER_INFO_KMD);
|
2020-03-17 18:55:53 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
auto status = osEnvironment.gdi->queryAdapterInfo(&queryAdapterInfo);
|
2020-03-17 18:55:53 +08:00
|
|
|
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
DEBUG_BREAK_IF("queryAdapterInfo failed");
|
2021-05-21 07:17:57 +08:00
|
|
|
return false;
|
2020-03-17 18:55:53 +08:00
|
|
|
}
|
|
|
|
|
2021-05-21 07:17:57 +08:00
|
|
|
std::string deviceRegistryPath = adapterInfo.DeviceRegistryPath;
|
|
|
|
return isCompatibleDriverStore(std::move(deviceRegistryPath));
|
2021-05-03 04:41:01 +08:00
|
|
|
}
|
|
|
|
|
2022-12-08 08:05:54 +08:00
|
|
|
std::unique_ptr<HwDeviceIdWddm> createHwDeviceIdFromAdapterLuid(OsEnvironmentWin &osEnvironment, LUID adapterLuid, uint32_t adapterNodeOrdinal) {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_OPENADAPTERFROMLUID openAdapterData = {};
|
|
|
|
openAdapterData.AdapterLuid = adapterLuid;
|
|
|
|
auto status = osEnvironment.gdi->openAdapterFromLuid(&openAdapterData);
|
2021-05-03 04:41:01 +08:00
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
DEBUG_BREAK_IF("openAdapterFromLuid failed");
|
2020-03-17 18:55:53 +08:00
|
|
|
return nullptr;
|
2020-02-17 23:14:22 +08:00
|
|
|
}
|
2020-03-17 18:55:53 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
std::unique_ptr<UmKmDataTranslator> umKmDataTranslator = createUmKmDataTranslator(*osEnvironment.gdi, openAdapterData.hAdapter);
|
2021-05-03 04:41:01 +08:00
|
|
|
if (false == umKmDataTranslator->enabled()) {
|
2022-05-12 22:04:41 +08:00
|
|
|
if (false == validDriverStorePath(osEnvironment, openAdapterData.hAdapter)) {
|
2021-05-03 04:41:01 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_QUERYADAPTERINFO queryAdapterInfo = {};
|
2020-09-04 02:49:39 +08:00
|
|
|
D3DKMT_ADAPTERTYPE queryAdapterType = {};
|
2022-05-12 22:04:41 +08:00
|
|
|
queryAdapterInfo.hAdapter = openAdapterData.hAdapter;
|
|
|
|
queryAdapterInfo.Type = KMTQAITYPE_ADAPTERTYPE;
|
|
|
|
queryAdapterInfo.pPrivateDriverData = &queryAdapterType;
|
|
|
|
queryAdapterInfo.PrivateDriverDataSize = sizeof(queryAdapterType);
|
|
|
|
status = osEnvironment.gdi->queryAdapterInfo(&queryAdapterInfo);
|
2020-09-04 02:49:39 +08:00
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
DEBUG_BREAK_IF("queryAdapterInfo failed");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
if (0 == queryAdapterType.RenderSupported) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2022-12-08 08:05:54 +08:00
|
|
|
uint32_t adapterNodeMask = 1 << adapterNodeOrdinal;
|
|
|
|
return std::make_unique<HwDeviceIdWddm>(openAdapterData.hAdapter, adapterLuid, adapterNodeMask, &osEnvironment, std::move(umKmDataTranslator));
|
2020-02-17 23:14:22 +08:00
|
|
|
}
|
|
|
|
|
2021-05-28 01:44:47 +08:00
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> Wddm::discoverDevices(ExecutionEnvironment &executionEnvironment) {
|
2020-03-17 14:26:46 +08:00
|
|
|
|
|
|
|
auto osEnvironment = new OsEnvironmentWin();
|
|
|
|
auto gdi = osEnvironment->gdi.get();
|
|
|
|
executionEnvironment.osEnvironment.reset(osEnvironment);
|
2020-02-05 17:49:54 +08:00
|
|
|
|
|
|
|
if (!gdi->isInitialized()) {
|
2021-05-11 23:07:20 +08:00
|
|
|
return {};
|
2020-02-05 17:49:54 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2021-05-26 00:42:36 +08:00
|
|
|
auto adapterFactory = AdapterFactory::create(Wddm::dXCoreCreateAdapterFactory, Wddm::createDxgiFactory);
|
2021-05-11 17:18:31 +08:00
|
|
|
|
2021-05-26 00:42:36 +08:00
|
|
|
if (false == adapterFactory->isSupported()) {
|
2021-05-11 23:07:20 +08:00
|
|
|
return {};
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-05-20 23:06:32 +08:00
|
|
|
size_t numRootDevices = 0u;
|
|
|
|
if (DebugManager.flags.CreateMultipleRootDevices.get()) {
|
|
|
|
numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get();
|
|
|
|
}
|
|
|
|
|
2021-05-11 23:07:20 +08:00
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> hwDeviceIds;
|
2020-05-20 23:06:32 +08:00
|
|
|
do {
|
2021-05-26 00:42:36 +08:00
|
|
|
if (false == adapterFactory->createSnapshotOfAvailableAdapters()) {
|
2021-05-11 23:07:20 +08:00
|
|
|
return hwDeviceIds;
|
|
|
|
}
|
|
|
|
|
2021-05-26 00:42:36 +08:00
|
|
|
auto adapterCount = adapterFactory->getNumAdaptersInSnapshot();
|
2021-05-11 23:07:20 +08:00
|
|
|
for (uint32_t i = 0; i < adapterCount; ++i) {
|
|
|
|
AdapterFactory::AdapterDesc adapterDesc;
|
2021-05-26 00:42:36 +08:00
|
|
|
if (false == adapterFactory->getAdapterDesc(i, adapterDesc)) {
|
2021-05-11 23:07:20 +08:00
|
|
|
DEBUG_BREAK_IF(true);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (adapterDesc.type == AdapterFactory::AdapterDesc::Type::NotHardware) {
|
|
|
|
continue;
|
2020-05-20 23:06:32 +08:00
|
|
|
}
|
2021-05-11 23:07:20 +08:00
|
|
|
|
|
|
|
if (false == canUseAdapterBasedOnDriverDesc(adapterDesc.driverDescription.c_str())) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (false == isAllowedDeviceId(adapterDesc.deviceId)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-12-08 08:05:54 +08:00
|
|
|
auto hwDeviceId = createHwDeviceIdFromAdapterLuid(*osEnvironment, adapterDesc.luid, i);
|
2021-05-11 23:07:20 +08:00
|
|
|
if (hwDeviceId) {
|
2021-05-25 01:34:55 +08:00
|
|
|
hwDeviceIds.push_back(std::unique_ptr<HwDeviceId>(hwDeviceId.release()));
|
2021-05-11 23:07:20 +08:00
|
|
|
}
|
|
|
|
|
2021-06-18 03:26:11 +08:00
|
|
|
if (!hwDeviceIds.empty() && hwDeviceIds.size() == numRootDevices) {
|
2020-05-20 23:06:32 +08:00
|
|
|
break;
|
2020-02-17 23:14:22 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2020-05-20 23:06:32 +08:00
|
|
|
if (hwDeviceIds.empty()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (hwDeviceIds.size() < numRootDevices);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-02-17 23:14:22 +08:00
|
|
|
return hwDeviceIds;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-07-18 21:25:50 +08:00
|
|
|
bool Wddm::evict(const D3DKMT_HANDLE *handleList, uint32_t numOfHandles, uint64_t &sizeToTrim, bool evictNeeded) {
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_EVICT evict = {};
|
|
|
|
evict.AllocationList = handleList;
|
|
|
|
evict.hDevice = device;
|
|
|
|
evict.NumAllocations = numOfHandles;
|
|
|
|
evict.NumBytesToTrim = 0;
|
2022-07-26 05:33:42 +08:00
|
|
|
evict.Flags.EvictOnlyIfNecessary = adjustEvictNeededParameter(evictNeeded) ? 0 : 1;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
status = getGdi()->evict(&evict);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
sizeToTrim = evict.NumBytesToTrim;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2021-11-25 17:31:14 +08:00
|
|
|
kmDafListener->notifyEvict(featureTable->flags.ftrKmdDaf, getAdapter(), device, handleList, numOfHandles, getGdi()->escape);
|
2018-01-31 18:22:13 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-03-17 19:19:38 +08:00
|
|
|
bool Wddm::makeResident(const D3DKMT_HANDLE *handles, uint32_t count, bool cantTrimFurther, uint64_t *numberOfBytesToTrim, size_t totalSize) {
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2021-06-08 03:47:12 +08:00
|
|
|
D3DDDI_MAKERESIDENT makeResident = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
UINT priority = 0;
|
|
|
|
bool success = false;
|
|
|
|
|
2020-03-17 19:19:38 +08:00
|
|
|
perfLogResidencyReportAllocations(residencyLogger.get(), count, totalSize);
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
makeResident.AllocationList = handles;
|
|
|
|
makeResident.hPagingQueue = pagingQueue;
|
|
|
|
makeResident.NumAllocations = count;
|
|
|
|
makeResident.PriorityList = &priority;
|
|
|
|
makeResident.Flags.CantTrimFurther = cantTrimFurther ? 1 : 0;
|
2022-09-13 22:26:03 +08:00
|
|
|
makeResident.Flags.MustSucceed = 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-02-05 17:49:54 +08:00
|
|
|
status = getGdi()->makeResident(&makeResident);
|
2017-12-21 07:45:38 +08:00
|
|
|
if (status == STATUS_PENDING) {
|
2020-03-23 23:37:41 +08:00
|
|
|
perfLogResidencyMakeResident(residencyLogger.get(), true, makeResident.PagingFenceValue);
|
2019-06-06 00:41:42 +08:00
|
|
|
updatePagingFenceValue(makeResident.PagingFenceValue);
|
2017-12-21 07:45:38 +08:00
|
|
|
success = true;
|
|
|
|
} else if (status == STATUS_SUCCESS) {
|
2020-03-23 23:37:41 +08:00
|
|
|
perfLogResidencyMakeResident(residencyLogger.get(), false, makeResident.PagingFenceValue);
|
2017-12-21 07:45:38 +08:00
|
|
|
success = true;
|
|
|
|
} else {
|
|
|
|
DEBUG_BREAK_IF(true);
|
2020-03-17 19:19:38 +08:00
|
|
|
perfLogResidencyTrimRequired(residencyLogger.get(), makeResident.NumBytesToTrim);
|
2022-09-13 22:26:03 +08:00
|
|
|
if (numberOfBytesToTrim != nullptr) {
|
2017-12-21 07:45:38 +08:00
|
|
|
*numberOfBytesToTrim = makeResident.NumBytesToTrim;
|
2022-09-13 22:26:03 +08:00
|
|
|
}
|
|
|
|
return false;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2021-11-25 17:31:14 +08:00
|
|
|
kmDafListener->notifyMakeResident(featureTable->flags.ftrKmdDaf, getAdapter(), device, handles, count, getGdi()->escape);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-01-31 18:22:13 +08:00
|
|
|
return success;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-01-29 01:12:39 +08:00
|
|
|
bool Wddm::mapGpuVirtualAddress(AllocationStorageData *allocationStorageData) {
|
2021-04-03 01:01:51 +08:00
|
|
|
auto osHandle = static_cast<OsHandleWin *>(allocationStorageData->osHandleStorage);
|
|
|
|
return mapGpuVirtualAddress(osHandle->gmm,
|
|
|
|
osHandle->handle,
|
2019-12-03 17:21:33 +08:00
|
|
|
0u, MemoryConstants::maxSvmAddress, castToUint64(allocationStorageData->cpuPtr),
|
2021-04-03 01:01:51 +08:00
|
|
|
osHandle->gpuPtr);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
bool Wddm::mapGpuVirtualAddress(Gmm *gmm, D3DKMT_HANDLE handle, D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_VIRTUAL_ADDRESS preferredAddress, D3DGPU_VIRTUAL_ADDRESS &gpuPtr) {
|
2022-05-10 01:40:30 +08:00
|
|
|
D3DDDI_MAPGPUVIRTUALADDRESS mapGPUVA = {};
|
2021-06-08 03:47:12 +08:00
|
|
|
D3DDDIGPUVIRTUALADDRESS_PROTECTION_TYPE protectionType = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
protectionType.Write = TRUE;
|
|
|
|
|
2019-02-15 22:33:40 +08:00
|
|
|
uint64_t size = gmm->gmmResourceInfo->getSizeAllocation();
|
2018-07-12 21:42:46 +08:00
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
mapGPUVA.hPagingQueue = pagingQueue;
|
|
|
|
mapGPUVA.hAllocation = handle;
|
|
|
|
mapGPUVA.Protection = protectionType;
|
2021-08-06 18:46:00 +08:00
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
mapGPUVA.SizeInPages = size / MemoryConstants::pageSize;
|
|
|
|
mapGPUVA.OffsetInPages = 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
mapGPUVA.BaseAddress = preferredAddress;
|
|
|
|
mapGPUVA.MinimumAddress = minimumAddress;
|
|
|
|
mapGPUVA.MaximumAddress = maximumAddress;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
applyAdditionalMapGPUVAFields(mapGPUVA, gmm);
|
2021-08-06 18:46:00 +08:00
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
NTSTATUS status = getGdi()->mapGpuVirtualAddress(&mapGPUVA);
|
2022-04-29 21:28:15 +08:00
|
|
|
|
2022-06-08 16:23:02 +08:00
|
|
|
auto gmmHelper = gmm->getGmmHelper();
|
2022-05-10 01:40:30 +08:00
|
|
|
gpuPtr = gmmHelper->canonize(mapGPUVA.VirtualAddress);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (status == STATUS_PENDING) {
|
2022-05-10 01:40:30 +08:00
|
|
|
updatePagingFenceValue(mapGPUVA.PagingFenceValue);
|
2017-12-21 07:45:38 +08:00
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
DEBUG_BREAK_IF(true);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
kmDafListener->notifyMapGpuVA(featureTable->flags.ftrKmdDaf, getAdapter(), device, handle, mapGPUVA.VirtualAddress, getGdi()->escape);
|
2021-09-29 23:59:41 +08:00
|
|
|
bool ret = true;
|
2022-12-15 21:33:28 +08:00
|
|
|
auto &productHelper = rootDeviceEnvironment.getHelper<ProductHelper>();
|
|
|
|
if (gmm->isCompressionEnabled && productHelper.isPageTableManagerSupported(*rootDeviceEnvironment.getHardwareInfo())) {
|
2023-04-27 23:42:17 +08:00
|
|
|
for (auto rootDeviceIndex = 0u; rootDeviceIndex < rootDeviceEnvironment.executionEnvironment.rootDeviceEnvironments.size(); rootDeviceIndex++) {
|
|
|
|
if (rootDeviceEnvironment.executionEnvironment.rootDeviceEnvironments[rootDeviceIndex].get() == &rootDeviceEnvironment) {
|
|
|
|
for (auto &engine : rootDeviceEnvironment.executionEnvironment.memoryManager->getRegisteredEngines(rootDeviceIndex)) {
|
2023-04-26 18:36:25 +08:00
|
|
|
if (engine.commandStreamReceiver->pageTableManager.get()) {
|
|
|
|
ret &= engine.commandStreamReceiver->pageTableManager->updateAuxTable(gpuPtr, gmm, true);
|
|
|
|
}
|
|
|
|
}
|
2021-09-29 23:59:41 +08:00
|
|
|
}
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-01-25 22:10:07 +08:00
|
|
|
|
2021-09-29 23:59:41 +08:00
|
|
|
return ret;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-09-17 08:38:06 +08:00
|
|
|
D3DGPU_VIRTUAL_ADDRESS Wddm::reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS baseAddress,
|
|
|
|
D3DGPU_VIRTUAL_ADDRESS minimumAddress,
|
2019-02-26 15:28:41 +08:00
|
|
|
D3DGPU_VIRTUAL_ADDRESS maximumAddress,
|
|
|
|
D3DGPU_SIZE_T size) {
|
|
|
|
UNRECOVERABLE_IF(size % MemoryConstants::pageSize64k);
|
|
|
|
D3DDDI_RESERVEGPUVIRTUALADDRESS reserveGpuVirtualAddress = {};
|
2022-09-17 08:38:06 +08:00
|
|
|
reserveGpuVirtualAddress.BaseAddress = baseAddress;
|
2019-02-26 15:28:41 +08:00
|
|
|
reserveGpuVirtualAddress.MinimumAddress = minimumAddress;
|
|
|
|
reserveGpuVirtualAddress.MaximumAddress = maximumAddress;
|
|
|
|
reserveGpuVirtualAddress.hPagingQueue = this->pagingQueue;
|
|
|
|
reserveGpuVirtualAddress.Size = size;
|
|
|
|
|
2020-02-05 17:49:54 +08:00
|
|
|
NTSTATUS status = getGdi()->reserveGpuVirtualAddress(&reserveGpuVirtualAddress);
|
2019-02-26 15:28:41 +08:00
|
|
|
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
|
|
|
|
return reserveGpuVirtualAddress.VirtualAddress;
|
|
|
|
}
|
|
|
|
|
2019-01-24 23:25:26 +08:00
|
|
|
bool Wddm::freeGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size) {
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_FREEGPUVIRTUALADDRESS freeGpuva = {};
|
|
|
|
freeGpuva.hAdapter = getAdapter();
|
|
|
|
freeGpuva.BaseAddress = rootDeviceEnvironment.getGmmHelper()->decanonize(gpuPtr);
|
|
|
|
freeGpuva.Size = size;
|
|
|
|
status = getGdi()->freeGpuVirtualAddress(&freeGpuva);
|
2017-12-21 07:45:38 +08:00
|
|
|
gpuPtr = static_cast<D3DGPU_VIRTUAL_ADDRESS>(0);
|
2018-01-31 18:22:13 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
kmDafListener->notifyUnmapGpuVA(featureTable->flags.ftrKmdDaf, getAdapter(), device, freeGpuva.BaseAddress, getGdi()->escape);
|
2018-01-31 18:22:13 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-08-30 22:57:25 +08:00
|
|
|
NTSTATUS Wddm::createAllocation(const void *alignedCpuPtr, const Gmm *gmm, D3DKMT_HANDLE &outHandle, D3DKMT_HANDLE &outResourceHandle, uint64_t *outSharedHandle) {
|
2018-01-08 23:31:29 +08:00
|
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DDDI_ALLOCATIONINFO2 allocationInfo = {};
|
|
|
|
D3DKMT_CREATEALLOCATION createAllocation = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-05 22:00:45 +08:00
|
|
|
if (gmm == nullptr)
|
2017-12-21 07:45:38 +08:00
|
|
|
return false;
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
allocationInfo.pSystemMem = alignedCpuPtr;
|
|
|
|
allocationInfo.pPrivateDriverData = gmm->gmmResourceInfo->peekHandle();
|
|
|
|
allocationInfo.PrivateDriverDataSize = static_cast<uint32_t>(gmm->gmmResourceInfo->peekHandleSize());
|
|
|
|
createAllocation.NumAllocations = 1;
|
|
|
|
createAllocation.Flags.CreateShared = outSharedHandle ? TRUE : FALSE;
|
|
|
|
createAllocation.Flags.NtSecuritySharing = outSharedHandle ? TRUE : FALSE;
|
2022-08-16 19:14:55 +08:00
|
|
|
createAllocation.Flags.CreateResource = outSharedHandle ? TRUE : FALSE;
|
2022-05-12 22:04:41 +08:00
|
|
|
createAllocation.pAllocationInfo2 = &allocationInfo;
|
|
|
|
createAllocation.hDevice = device;
|
|
|
|
|
|
|
|
status = getGdi()->createAllocation2(&createAllocation);
|
2018-02-07 05:43:38 +08:00
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
DEBUG_BREAK_IF(true);
|
|
|
|
return status;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-01-31 18:22:13 +08:00
|
|
|
|
2022-06-08 19:52:47 +08:00
|
|
|
gmm->gmmResourceInfo->refreshHandle();
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
outHandle = allocationInfo.hAllocation;
|
|
|
|
outResourceHandle = createAllocation.hResource;
|
2020-02-26 01:58:09 +08:00
|
|
|
if (outSharedHandle) {
|
2021-08-30 22:57:25 +08:00
|
|
|
HANDLE ntSharedHandle = NULL;
|
|
|
|
status = this->createNTHandle(&outResourceHandle, &ntSharedHandle);
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
DEBUG_BREAK_IF(true);
|
|
|
|
[[maybe_unused]] auto destroyStatus = this->destroyAllocations(&outHandle, 1, outResourceHandle);
|
|
|
|
outHandle = NULL_HANDLE;
|
|
|
|
outResourceHandle = NULL_HANDLE;
|
|
|
|
DEBUG_BREAK_IF(destroyStatus != STATUS_SUCCESS);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
*outSharedHandle = castToUint64(ntSharedHandle);
|
2020-02-26 01:58:09 +08:00
|
|
|
}
|
2021-11-25 17:31:14 +08:00
|
|
|
kmDafListener->notifyWriteTarget(featureTable->flags.ftrKmdDaf, getAdapter(), device, outHandle, getGdi()->escape);
|
2018-02-07 05:43:38 +08:00
|
|
|
|
2018-01-08 23:31:29 +08:00
|
|
|
return status;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2021-07-14 22:51:47 +08:00
|
|
|
bool Wddm::createAllocation(const Gmm *gmm, D3DKMT_HANDLE &outHandle) {
|
|
|
|
D3DKMT_HANDLE outResourceHandle = NULL_HANDLE;
|
2021-08-30 22:57:25 +08:00
|
|
|
uint64_t *outSharedHandle = nullptr;
|
2021-07-14 22:51:47 +08:00
|
|
|
auto result = this->createAllocation(nullptr, gmm, outHandle, outResourceHandle, outSharedHandle);
|
|
|
|
return STATUS_SUCCESS == result;
|
|
|
|
}
|
|
|
|
|
2021-04-20 03:53:46 +08:00
|
|
|
bool Wddm::setAllocationPriority(const D3DKMT_HANDLE *handles, uint32_t allocationCount, uint32_t priority) {
|
|
|
|
D3DKMT_SETALLOCATIONPRIORITY setAllocationPriority = {};
|
|
|
|
|
|
|
|
StackVec<UINT, 4> priorities{};
|
|
|
|
|
|
|
|
priorities.resize(allocationCount);
|
|
|
|
for (auto i = 0u; i < allocationCount; i++) {
|
|
|
|
priorities[i] = priority;
|
|
|
|
}
|
|
|
|
|
|
|
|
setAllocationPriority.hDevice = device;
|
|
|
|
setAllocationPriority.AllocationCount = allocationCount;
|
2021-05-31 00:42:47 +08:00
|
|
|
setAllocationPriority.hResource = NULL_HANDLE;
|
2021-04-20 03:53:46 +08:00
|
|
|
setAllocationPriority.phAllocationList = handles;
|
|
|
|
setAllocationPriority.pPriorities = priorities.data();
|
|
|
|
|
|
|
|
auto status = getGdi()->setAllocationPriority(&setAllocationPriority);
|
|
|
|
|
|
|
|
DEBUG_BREAK_IF(STATUS_SUCCESS != status);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS == status;
|
|
|
|
}
|
|
|
|
|
2018-03-23 17:07:31 +08:00
|
|
|
NTSTATUS Wddm::createAllocationsAndMapGpuVa(OsHandleStorage &osHandles) {
|
|
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DDDI_ALLOCATIONINFO2 allocationInfo[maxFragmentsCount] = {};
|
|
|
|
D3DKMT_CREATEALLOCATION createAllocation = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
auto allocationCount = 0;
|
2018-10-22 20:20:05 +08:00
|
|
|
for (unsigned int i = 0; i < maxFragmentsCount; i++) {
|
2017-12-21 07:45:38 +08:00
|
|
|
if (!osHandles.fragmentStorageData[i].osHandleStorage) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-04-03 01:01:51 +08:00
|
|
|
auto osHandle = static_cast<OsHandleWin *>(osHandles.fragmentStorageData[i].osHandleStorage);
|
2021-05-25 01:34:55 +08:00
|
|
|
if ((osHandle->handle == (D3DKMT_HANDLE)0) && (osHandles.fragmentStorageData[i].fragmentSize)) {
|
2022-05-12 22:04:41 +08:00
|
|
|
allocationInfo[allocationCount].pPrivateDriverData = osHandle->gmm->gmmResourceInfo->peekHandle();
|
2021-05-20 21:48:33 +08:00
|
|
|
[[maybe_unused]] auto pSysMem = osHandles.fragmentStorageData[i].cpuPtr;
|
2022-05-12 22:04:41 +08:00
|
|
|
[[maybe_unused]] auto pSysMemFromGmm = osHandle->gmm->gmmResourceInfo->getSystemMemPointer();
|
|
|
|
DEBUG_BREAK_IF(pSysMemFromGmm != pSysMem);
|
|
|
|
allocationInfo[allocationCount].pSystemMem = osHandles.fragmentStorageData[i].cpuPtr;
|
|
|
|
allocationInfo[allocationCount].PrivateDriverDataSize = static_cast<unsigned int>(osHandle->gmm->gmmResourceInfo->peekHandleSize());
|
2017-12-21 07:45:38 +08:00
|
|
|
allocationCount++;
|
|
|
|
}
|
|
|
|
}
|
2018-03-23 17:07:31 +08:00
|
|
|
if (allocationCount == 0) {
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
createAllocation.hGlobalShare = 0;
|
|
|
|
createAllocation.PrivateRuntimeDataSize = 0;
|
|
|
|
createAllocation.PrivateDriverDataSize = 0;
|
|
|
|
createAllocation.Flags.Reserved = 0;
|
|
|
|
createAllocation.NumAllocations = allocationCount;
|
|
|
|
createAllocation.pPrivateRuntimeData = nullptr;
|
|
|
|
createAllocation.pPrivateDriverData = nullptr;
|
|
|
|
createAllocation.Flags.NonSecure = FALSE;
|
|
|
|
createAllocation.Flags.CreateShared = FALSE;
|
|
|
|
createAllocation.Flags.RestrictSharedAccess = FALSE;
|
|
|
|
createAllocation.Flags.CreateResource = FALSE;
|
|
|
|
createAllocation.pAllocationInfo2 = allocationInfo;
|
|
|
|
createAllocation.hDevice = device;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-03-23 17:07:31 +08:00
|
|
|
while (status == STATUS_UNSUCCESSFUL) {
|
2022-05-12 22:04:41 +08:00
|
|
|
status = getGdi()->createAllocation2(&createAllocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (status != STATUS_SUCCESS) {
|
2021-05-21 07:17:57 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s status: %d", __FUNCTION__, status);
|
2019-02-01 15:32:25 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_GRAPHICS_NO_VIDEO_MEMORY);
|
2017-12-21 07:45:38 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
auto allocationIndex = 0;
|
|
|
|
for (int i = 0; i < allocationCount; i++) {
|
2021-04-03 01:01:51 +08:00
|
|
|
while (static_cast<OsHandleWin *>(osHandles.fragmentStorageData[allocationIndex].osHandleStorage)->handle) {
|
2017-12-21 07:45:38 +08:00
|
|
|
allocationIndex++;
|
|
|
|
}
|
2022-05-12 22:04:41 +08:00
|
|
|
static_cast<OsHandleWin *>(osHandles.fragmentStorageData[allocationIndex].osHandleStorage)->handle = allocationInfo[i].hAllocation;
|
2019-01-29 01:12:39 +08:00
|
|
|
bool success = mapGpuVirtualAddress(&osHandles.fragmentStorageData[allocationIndex]);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-01-31 18:22:13 +08:00
|
|
|
if (!success) {
|
2019-06-18 19:53:14 +08:00
|
|
|
osHandles.fragmentStorageData[allocationIndex].freeTheFragment = true;
|
2021-05-21 07:17:57 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s mapGpuVirtualAddress: %d", __FUNCTION__, success);
|
2018-01-31 18:22:13 +08:00
|
|
|
DEBUG_BREAK_IF(true);
|
2019-06-18 19:53:14 +08:00
|
|
|
return STATUS_GRAPHICS_NO_VIDEO_MEMORY;
|
2018-01-31 18:22:13 +08:00
|
|
|
}
|
|
|
|
|
2019-06-18 19:53:14 +08:00
|
|
|
allocationIndex++;
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
kmDafListener->notifyWriteTarget(featureTable->flags.ftrKmdDaf, getAdapter(), device, allocationInfo[i].hAllocation, getGdi()->escape);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-03-23 17:07:31 +08:00
|
|
|
status = STATUS_SUCCESS;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-03-23 17:07:31 +08:00
|
|
|
return status;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-03-05 21:21:57 +08:00
|
|
|
bool Wddm::destroyAllocations(const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle) {
|
2021-05-27 05:45:38 +08:00
|
|
|
if ((0U == allocationCount) && (0U == resourceHandle)) {
|
|
|
|
return true;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_DESTROYALLOCATION2 destroyAllocation = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(!(allocationCount <= 1 || resourceHandle == 0));
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
destroyAllocation.hDevice = device;
|
|
|
|
destroyAllocation.hResource = resourceHandle;
|
|
|
|
destroyAllocation.phAllocationList = handles;
|
|
|
|
destroyAllocation.AllocationCount = allocationCount;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
destroyAllocation.Flags.AssumeNotInUse = 1;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
status = getGdi()->destroyAllocation2(&destroyAllocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
2020-07-31 22:52:41 +08:00
|
|
|
bool Wddm::verifySharedHandle(D3DKMT_HANDLE osHandle) {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_QUERYRESOURCEINFO queryResourceInfo = {};
|
|
|
|
queryResourceInfo.hDevice = device;
|
|
|
|
queryResourceInfo.hGlobalShare = osHandle;
|
|
|
|
auto status = getGdi()->queryResourceInfo(&queryResourceInfo);
|
2020-07-31 22:52:41 +08:00
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
bool Wddm::openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_QUERYRESOURCEINFO queryResourceInfo = {};
|
|
|
|
queryResourceInfo.hDevice = device;
|
|
|
|
queryResourceInfo.hGlobalShare = handle;
|
|
|
|
[[maybe_unused]] auto status = getGdi()->queryResourceInfo(&queryResourceInfo);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
if (queryResourceInfo.NumAllocations == 0) {
|
2017-12-22 00:28:17 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
std::unique_ptr<char[]> allocPrivateData(new char[queryResourceInfo.TotalPrivateDriverDataSize]);
|
|
|
|
std::unique_ptr<char[]> resPrivateData(new char[queryResourceInfo.ResourcePrivateDriverDataSize]);
|
|
|
|
std::unique_ptr<char[]> resPrivateRuntimeData(new char[queryResourceInfo.PrivateRuntimeDataSize]);
|
|
|
|
std::unique_ptr<D3DDDI_OPENALLOCATIONINFO2[]> allocationInfo(new D3DDDI_OPENALLOCATIONINFO2[queryResourceInfo.NumAllocations]);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_OPENRESOURCE openResource = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
openResource.hDevice = device;
|
|
|
|
openResource.hGlobalShare = handle;
|
|
|
|
openResource.NumAllocations = queryResourceInfo.NumAllocations;
|
|
|
|
openResource.pOpenAllocationInfo2 = allocationInfo.get();
|
|
|
|
openResource.pTotalPrivateDriverDataBuffer = allocPrivateData.get();
|
|
|
|
openResource.TotalPrivateDriverDataBufferSize = queryResourceInfo.TotalPrivateDriverDataSize;
|
|
|
|
openResource.pResourcePrivateDriverData = resPrivateData.get();
|
|
|
|
openResource.ResourcePrivateDriverDataSize = queryResourceInfo.ResourcePrivateDriverDataSize;
|
|
|
|
openResource.pPrivateRuntimeData = resPrivateRuntimeData.get();
|
|
|
|
openResource.PrivateRuntimeDataSize = queryResourceInfo.PrivateRuntimeDataSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
status = getGdi()->openResource(&openResource);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
|
2019-03-05 16:25:18 +08:00
|
|
|
alloc->setDefaultHandle(allocationInfo[0].hAllocation);
|
2022-05-12 22:04:41 +08:00
|
|
|
alloc->resourceHandle = openResource.hResource;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-06-29 17:48:19 +08:00
|
|
|
auto resourceInfo = const_cast<void *>(allocationInfo[0].pPrivateDriverData);
|
2022-04-27 18:20:10 +08:00
|
|
|
alloc->setDefaultGmm(new Gmm(rootDeviceEnvironment.getGmmHelper(), static_cast<GMM_RESOURCE_INFO *>(resourceInfo)));
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2017-12-22 00:28:17 +08:00
|
|
|
return true;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-07-31 22:52:41 +08:00
|
|
|
bool Wddm::verifyNTHandle(HANDLE handle) {
|
|
|
|
D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE queryResourceInfoFromNtHandle = {};
|
|
|
|
queryResourceInfoFromNtHandle.hDevice = device;
|
|
|
|
queryResourceInfoFromNtHandle.hNtHandle = handle;
|
|
|
|
auto status = getGdi()->queryResourceInfoFromNtHandle(&queryResourceInfoFromNtHandle);
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
bool Wddm::openNTHandle(HANDLE handle, WddmAllocation *alloc) {
|
|
|
|
D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE queryResourceInfoFromNtHandle = {};
|
|
|
|
queryResourceInfoFromNtHandle.hDevice = device;
|
|
|
|
queryResourceInfoFromNtHandle.hNtHandle = handle;
|
2021-06-09 21:53:41 +08:00
|
|
|
[[maybe_unused]] auto status = getGdi()->queryResourceInfoFromNtHandle(&queryResourceInfoFromNtHandle);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
|
|
|
|
std::unique_ptr<char[]> allocPrivateData(new char[queryResourceInfoFromNtHandle.TotalPrivateDriverDataSize]);
|
|
|
|
std::unique_ptr<char[]> resPrivateData(new char[queryResourceInfoFromNtHandle.ResourcePrivateDriverDataSize]);
|
|
|
|
std::unique_ptr<char[]> resPrivateRuntimeData(new char[queryResourceInfoFromNtHandle.PrivateRuntimeDataSize]);
|
|
|
|
std::unique_ptr<D3DDDI_OPENALLOCATIONINFO2[]> allocationInfo2(new D3DDDI_OPENALLOCATIONINFO2[queryResourceInfoFromNtHandle.NumAllocations]);
|
|
|
|
|
|
|
|
D3DKMT_OPENRESOURCEFROMNTHANDLE openResourceFromNtHandle = {};
|
|
|
|
|
|
|
|
openResourceFromNtHandle.hDevice = device;
|
|
|
|
openResourceFromNtHandle.hNtHandle = handle;
|
|
|
|
openResourceFromNtHandle.NumAllocations = queryResourceInfoFromNtHandle.NumAllocations;
|
|
|
|
openResourceFromNtHandle.pOpenAllocationInfo2 = allocationInfo2.get();
|
|
|
|
openResourceFromNtHandle.pTotalPrivateDriverDataBuffer = allocPrivateData.get();
|
|
|
|
openResourceFromNtHandle.TotalPrivateDriverDataBufferSize = queryResourceInfoFromNtHandle.TotalPrivateDriverDataSize;
|
|
|
|
openResourceFromNtHandle.pResourcePrivateDriverData = resPrivateData.get();
|
|
|
|
openResourceFromNtHandle.ResourcePrivateDriverDataSize = queryResourceInfoFromNtHandle.ResourcePrivateDriverDataSize;
|
|
|
|
openResourceFromNtHandle.pPrivateRuntimeData = resPrivateRuntimeData.get();
|
|
|
|
openResourceFromNtHandle.PrivateRuntimeDataSize = queryResourceInfoFromNtHandle.PrivateRuntimeDataSize;
|
|
|
|
|
2020-02-05 17:49:54 +08:00
|
|
|
status = getGdi()->openResourceFromNtHandle(&openResourceFromNtHandle);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
|
2022-04-19 20:11:45 +08:00
|
|
|
auto resourceInfo = const_cast<void *>(allocationInfo2[0].pPrivateDriverData);
|
|
|
|
|
|
|
|
alloc->setDefaultGmm(new Gmm(rootDeviceEnvironment.getGmmHelper(), static_cast<GMM_RESOURCE_INFO *>(resourceInfo), hwDeviceId->getUmKmDataTranslator()->enabled()));
|
|
|
|
|
2019-03-05 16:25:18 +08:00
|
|
|
alloc->setDefaultHandle(allocationInfo2[0].hAllocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
alloc->resourceHandle = openResourceFromNtHandle.hResource;
|
|
|
|
|
2017-12-22 00:28:17 +08:00
|
|
|
return true;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-03-17 19:19:38 +08:00
|
|
|
void *Wddm::lockResource(const D3DKMT_HANDLE &handle, bool applyMakeResidentPriorToLock, size_t size) {
|
2019-01-16 22:09:33 +08:00
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
if (applyMakeResidentPriorToLock) {
|
2020-03-17 19:19:38 +08:00
|
|
|
temporaryResources->makeResidentResource(handle, size);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
D3DKMT_LOCK2 lock2 = {};
|
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
lock2.hAllocation = handle;
|
2017-12-21 07:45:38 +08:00
|
|
|
lock2.hDevice = this->device;
|
|
|
|
|
2021-06-09 21:53:41 +08:00
|
|
|
[[maybe_unused]] NTSTATUS status = getGdi()->lock2(&lock2);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
kmDafLock(handle);
|
2017-12-21 07:45:38 +08:00
|
|
|
return lock2.pData;
|
|
|
|
}
|
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
void Wddm::unlockResource(const D3DKMT_HANDLE &handle) {
|
2017-12-21 07:45:38 +08:00
|
|
|
D3DKMT_UNLOCK2 unlock2 = {};
|
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
unlock2.hAllocation = handle;
|
2017-12-21 07:45:38 +08:00
|
|
|
unlock2.hDevice = this->device;
|
|
|
|
|
2021-06-09 21:53:41 +08:00
|
|
|
[[maybe_unused]] NTSTATUS status = getGdi()->unlock2(&unlock2);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
2018-01-31 18:22:13 +08:00
|
|
|
|
2021-11-25 17:31:14 +08:00
|
|
|
kmDafListener->notifyUnlock(featureTable->flags.ftrKmdDaf, getAdapter(), device, &handle, 1, getGdi()->escape);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
void Wddm::kmDafLock(D3DKMT_HANDLE handle) {
|
2021-11-25 17:31:14 +08:00
|
|
|
kmDafListener->notifyLock(featureTable->flags.ftrKmdDaf, getAdapter(), device, handle, 0, getGdi()->escape);
|
2018-03-23 04:13:45 +08:00
|
|
|
}
|
|
|
|
|
2023-01-24 20:14:14 +08:00
|
|
|
bool Wddm::isKmDafEnabled() const {
|
|
|
|
return featureTable->flags.ftrKmdDaf;
|
|
|
|
}
|
|
|
|
|
2022-05-10 21:53:48 +08:00
|
|
|
bool Wddm::setLowPriorityContextParam(D3DKMT_HANDLE contextHandle) {
|
|
|
|
D3DKMT_SETCONTEXTSCHEDULINGPRIORITY contextPriority = {};
|
|
|
|
|
|
|
|
contextPriority.hContext = contextHandle;
|
|
|
|
contextPriority.Priority = 1;
|
|
|
|
|
|
|
|
if (DebugManager.flags.ForceWddmLowPriorityContextValue.get() != -1) {
|
|
|
|
contextPriority.Priority = static_cast<INT>(DebugManager.flags.ForceWddmLowPriorityContextValue.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
auto status = getGdi()->setSchedulingPriority(&contextPriority);
|
|
|
|
|
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stdout,
|
|
|
|
"\nSet scheduling priority for Wddm context. Status: :%lu, context handle: %u, priority: %d \n",
|
|
|
|
status, contextHandle, contextPriority.Priority);
|
|
|
|
|
|
|
|
return (status == STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2019-03-01 19:21:30 +08:00
|
|
|
bool Wddm::createContext(OsContextWin &osContext) {
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_CREATECONTEXTVIRTUAL createContext = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
CREATECONTEXT_PVTDATA privateData = initPrivateData(osContext);
|
2021-12-16 10:13:00 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
privateData.ProcessID = NEO::getPid();
|
|
|
|
privateData.pHwContextId = &hwContextId;
|
|
|
|
privateData.NoRingFlushes = DebugManager.flags.UseNoRingFlushesKmdMode.get();
|
2021-12-16 10:13:00 +08:00
|
|
|
|
2023-01-02 16:41:11 +08:00
|
|
|
applyAdditionalContextFlags(privateData, osContext);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
createContext.EngineAffinity = 0;
|
|
|
|
createContext.Flags.NullRendering = static_cast<UINT>(DebugManager.flags.EnableNullHardware.get());
|
|
|
|
createContext.Flags.HwQueueSupported = wddmInterface->hwQueuesSupported();
|
2018-02-22 21:19:08 +08:00
|
|
|
|
2019-03-01 19:21:30 +08:00
|
|
|
if (osContext.getPreemptionMode() >= PreemptionMode::MidBatch) {
|
2022-05-12 22:04:41 +08:00
|
|
|
createContext.Flags.DisableGpuTimeout = getEnablePreemptionRegValue();
|
2018-02-22 21:19:08 +08:00
|
|
|
}
|
|
|
|
|
2021-05-03 04:41:01 +08:00
|
|
|
UmKmDataTempStorage<CREATECONTEXT_PVTDATA> internalRepresentation;
|
|
|
|
if (hwDeviceId->getUmKmDataTranslator()->enabled()) {
|
|
|
|
internalRepresentation.resize(hwDeviceId->getUmKmDataTranslator()->getSizeForCreateContextDataInternalRepresentation());
|
2022-05-12 22:04:41 +08:00
|
|
|
hwDeviceId->getUmKmDataTranslator()->translateCreateContextDataToInternalRepresentation(internalRepresentation.data(), internalRepresentation.size(), privateData);
|
|
|
|
createContext.pPrivateDriverData = internalRepresentation.data();
|
|
|
|
createContext.PrivateDriverDataSize = static_cast<uint32_t>(internalRepresentation.size());
|
2021-05-03 04:41:01 +08:00
|
|
|
} else {
|
2022-05-12 22:04:41 +08:00
|
|
|
createContext.PrivateDriverDataSize = sizeof(privateData);
|
|
|
|
createContext.pPrivateDriverData = &privateData;
|
2021-05-03 04:41:01 +08:00
|
|
|
}
|
2022-05-12 22:04:41 +08:00
|
|
|
createContext.NodeOrdinal = WddmEngineMapper::engineNodeMap(osContext.getEngineType());
|
2021-05-14 01:46:01 +08:00
|
|
|
if (ApiSpecificConfig::getApiType() == ApiSpecificConfig::L0) {
|
2022-05-12 22:04:41 +08:00
|
|
|
createContext.ClientHint = D3DKMT_CLIENTHINT_ONEAPI_LEVEL0;
|
2021-05-14 01:46:01 +08:00
|
|
|
} else {
|
2022-05-12 22:04:41 +08:00
|
|
|
createContext.ClientHint = D3DKMT_CLIENTHINT_OPENCL;
|
2021-05-14 01:46:01 +08:00
|
|
|
}
|
2022-05-12 22:04:41 +08:00
|
|
|
createContext.hDevice = device;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2023-04-12 15:44:12 +08:00
|
|
|
status = getGdi()->createContext(&createContext);
|
|
|
|
osContext.setWddmContextHandle(createContext.hContext);
|
2018-05-02 18:00:28 +08:00
|
|
|
|
2023-04-12 15:44:12 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stdout,
|
|
|
|
"\nCreated Wddm context. Status: :%lu, engine: %u, contextId: %u, deviceBitfield: %lu \n",
|
|
|
|
status, osContext.getEngineType(), osContext.getContextId(), osContext.getDeviceBitfield().to_ulong());
|
2022-05-10 21:53:48 +08:00
|
|
|
|
2023-04-12 15:44:12 +08:00
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (osContext.isLowPriority()) {
|
|
|
|
return setLowPriorityContextParam(osContext.getWddmContextHandle());
|
2022-05-10 21:53:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Wddm::destroyContext(D3DKMT_HANDLE context) {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_DESTROYCONTEXT destroyContext = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
|
|
|
|
|
|
|
if (context != static_cast<D3DKMT_HANDLE>(0)) {
|
2022-05-12 22:04:41 +08:00
|
|
|
destroyContext.hContext = context;
|
|
|
|
status = getGdi()->destroyContext(&destroyContext);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-05-02 18:00:28 +08:00
|
|
|
return status == STATUS_SUCCESS;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-12-16 22:42:13 +08:00
|
|
|
bool Wddm::submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) {
|
2018-08-10 22:41:44 +08:00
|
|
|
bool status = false;
|
2019-12-16 22:42:13 +08:00
|
|
|
if (currentPagingFenceValue > *pagingFenceAddress && !waitOnGPU(submitArguments.contextHandle)) {
|
2018-08-10 22:41:44 +08:00
|
|
|
return false;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2019-12-16 22:42:13 +08:00
|
|
|
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "currentFenceValue =", submitArguments.monitorFence->currentFenceValue);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-02-12 00:28:08 +08:00
|
|
|
if (DebugManager.flags.PrintDeviceAndEngineIdOnSubmission.get()) {
|
|
|
|
printf("%u: Wddm Submission with context handle %u and HwQueue handle %u\n", SysCalls::getProcessId(), submitArguments.contextHandle, submitArguments.hwQueueHandle);
|
|
|
|
}
|
|
|
|
|
2019-12-16 22:42:13 +08:00
|
|
|
status = wddmInterface->submit(commandBuffer, size, commandHeader, submitArguments);
|
2018-08-10 22:41:44 +08:00
|
|
|
if (status) {
|
2019-12-16 22:42:13 +08:00
|
|
|
submitArguments.monitorFence->lastSubmittedFence = submitArguments.monitorFence->currentFenceValue;
|
|
|
|
submitArguments.monitorFence->currentFenceValue++;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
getDeviceState();
|
|
|
|
|
2018-08-10 22:41:44 +08:00
|
|
|
return status;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-03-27 16:06:08 +08:00
|
|
|
void Wddm::getDeviceState() {
|
2017-12-21 07:45:38 +08:00
|
|
|
#ifdef _DEBUG
|
2021-05-21 07:17:57 +08:00
|
|
|
D3DKMT_GETDEVICESTATE GetDevState = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
GetDevState.hDevice = device;
|
|
|
|
GetDevState.StateType = D3DKMT_DEVICESTATE_EXECUTION;
|
|
|
|
|
2020-02-05 17:49:54 +08:00
|
|
|
status = getGdi()->getDeviceState(&GetDevState);
|
2018-03-27 16:06:08 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
2017-12-21 07:45:38 +08:00
|
|
|
if (status == STATUS_SUCCESS) {
|
2018-03-27 16:06:08 +08:00
|
|
|
DEBUG_BREAK_IF(GetDevState.ExecutionState != D3DKMT_DEVICEEXECUTION_ACTIVE);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-05-27 05:45:38 +08:00
|
|
|
unsigned int Wddm::getEnablePreemptionRegValue() {
|
|
|
|
return enablePreemptionRegValue;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-21 23:36:08 +08:00
|
|
|
bool Wddm::waitOnGPU(D3DKMT_HANDLE context) {
|
2022-05-12 22:04:41 +08:00
|
|
|
D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMGPU waitOnGpu = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
waitOnGpu.hContext = context;
|
|
|
|
waitOnGpu.ObjectCount = 1;
|
|
|
|
waitOnGpu.ObjectHandleArray = &pagingQueueSyncObject;
|
2017-12-21 07:45:38 +08:00
|
|
|
uint64_t localPagingFenceValue = currentPagingFenceValue;
|
|
|
|
|
2022-05-12 22:04:41 +08:00
|
|
|
waitOnGpu.MonitoredFenceValueArray = &localPagingFenceValue;
|
|
|
|
NTSTATUS status = getGdi()->waitForSynchronizationObjectFromGpu(&waitOnGpu);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-10-26 18:22:47 +08:00
|
|
|
bool Wddm::waitFromCpu(uint64_t lastFenceValue, const MonitoredFence &monitoredFence) {
|
2017-12-21 07:45:38 +08:00
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
2022-05-17 23:23:15 +08:00
|
|
|
if (!skipResourceCleanup() && lastFenceValue > *monitoredFence.cpuAddress) {
|
2021-06-08 03:47:12 +08:00
|
|
|
D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU waitFromCpu = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
waitFromCpu.ObjectCount = 1;
|
2018-10-26 18:22:47 +08:00
|
|
|
waitFromCpu.ObjectHandleArray = &monitoredFence.fenceHandle;
|
2017-12-21 07:45:38 +08:00
|
|
|
waitFromCpu.FenceValueArray = &lastFenceValue;
|
|
|
|
waitFromCpu.hDevice = device;
|
2021-05-31 00:42:47 +08:00
|
|
|
waitFromCpu.hAsyncEvent = NULL_HANDLE;
|
2020-02-05 17:49:54 +08:00
|
|
|
status = getGdi()->waitForSynchronizationObjectFromCpu(&waitFromCpu);
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(status != STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
return status == STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2022-02-05 00:03:36 +08:00
|
|
|
bool Wddm::isGpuHangDetected(OsContext &osContext) {
|
|
|
|
const auto osContextWin = static_cast<OsContextWin *>(&osContext);
|
|
|
|
const auto &monitoredFence = osContextWin->getResidencyController().getMonitoredFence();
|
2022-02-15 03:03:10 +08:00
|
|
|
bool hangDetected = monitoredFence.cpuAddress && *monitoredFence.cpuAddress == gpuHangIndication;
|
2022-02-05 00:03:36 +08:00
|
|
|
|
2022-02-15 03:03:10 +08:00
|
|
|
PRINT_DEBUG_STRING(hangDetected && DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "ERROR: GPU HANG detected!\n");
|
|
|
|
|
|
|
|
return hangDetected;
|
2022-02-05 00:03:36 +08:00
|
|
|
}
|
|
|
|
|
2020-12-24 02:28:16 +08:00
|
|
|
void Wddm::initGfxPartition(GfxPartition &outGfxPartition, uint32_t rootDeviceIndex, size_t numRootDevices, bool useExternalFrontWindowPool) const {
|
2019-03-01 23:14:28 +08:00
|
|
|
if (gfxPartition.SVM.Limit != 0) {
|
|
|
|
outGfxPartition.heapInit(HeapIndex::HEAP_SVM, gfxPartition.SVM.Base, gfxPartition.SVM.Limit - gfxPartition.SVM.Base + 1);
|
2019-07-18 21:33:20 +08:00
|
|
|
} else if (is32bit) {
|
|
|
|
outGfxPartition.heapInit(HeapIndex::HEAP_SVM, 0x0ull, 4 * MemoryConstants::gigaByte);
|
2019-03-01 23:14:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
outGfxPartition.heapInit(HeapIndex::HEAP_STANDARD, gfxPartition.Standard.Base, gfxPartition.Standard.Limit - gfxPartition.Standard.Base + 1);
|
|
|
|
|
2020-01-30 00:48:36 +08:00
|
|
|
// Split HEAP_STANDARD64K among root devices
|
|
|
|
auto gfxStandard64KBSize = alignDown((gfxPartition.Standard64KB.Limit - gfxPartition.Standard64KB.Base + 1) / numRootDevices, GfxPartition::heapGranularity);
|
|
|
|
outGfxPartition.heapInit(HeapIndex::HEAP_STANDARD64KB, gfxPartition.Standard64KB.Base + rootDeviceIndex * gfxStandard64KBSize, gfxStandard64KBSize);
|
2019-03-01 23:14:28 +08:00
|
|
|
|
|
|
|
for (auto heap : GfxPartition::heap32Names) {
|
2020-12-24 02:28:16 +08:00
|
|
|
if (useExternalFrontWindowPool && HeapAssigner::heapTypeExternalWithFrontWindowPool(heap)) {
|
2020-09-14 21:14:11 +08:00
|
|
|
outGfxPartition.heapInitExternalWithFrontWindow(heap, gfxPartition.Heap32[static_cast<uint32_t>(heap)].Base,
|
|
|
|
gfxPartition.Heap32[static_cast<uint32_t>(heap)].Limit - gfxPartition.Heap32[static_cast<uint32_t>(heap)].Base + 1);
|
2020-10-14 15:50:07 +08:00
|
|
|
size_t externalFrontWindowSize = GfxPartition::externalFrontWindowPoolSize;
|
2020-09-14 21:14:11 +08:00
|
|
|
outGfxPartition.heapInitExternalWithFrontWindow(HeapAssigner::mapExternalWindowIndex(heap), outGfxPartition.heapAllocate(heap, externalFrontWindowSize),
|
|
|
|
externalFrontWindowSize);
|
2020-10-14 15:50:07 +08:00
|
|
|
} else if (HeapAssigner::isInternalHeap(heap)) {
|
2020-12-24 02:28:16 +08:00
|
|
|
auto baseAddress = gfxPartition.Heap32[static_cast<uint32_t>(heap)].Base >= minAddress ? gfxPartition.Heap32[static_cast<uint32_t>(heap)].Base : minAddress;
|
|
|
|
|
|
|
|
outGfxPartition.heapInitWithFrontWindow(heap, baseAddress,
|
|
|
|
gfxPartition.Heap32[static_cast<uint32_t>(heap)].Limit - baseAddress + 1,
|
2020-10-14 15:50:07 +08:00
|
|
|
GfxPartition::internalFrontWindowPoolSize);
|
2020-12-24 02:28:16 +08:00
|
|
|
outGfxPartition.heapInitFrontWindow(HeapAssigner::mapInternalWindowIndex(heap), baseAddress, GfxPartition::internalFrontWindowPoolSize);
|
2020-09-14 21:14:11 +08:00
|
|
|
} else {
|
|
|
|
outGfxPartition.heapInit(heap, gfxPartition.Heap32[static_cast<uint32_t>(heap)].Base,
|
|
|
|
gfxPartition.Heap32[static_cast<uint32_t>(heap)].Limit - gfxPartition.Heap32[static_cast<uint32_t>(heap)].Base + 1);
|
|
|
|
}
|
2019-03-01 23:14:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-03 04:43:37 +08:00
|
|
|
uint64_t Wddm::getSystemSharedMemory() const {
|
|
|
|
return systemSharedMemory;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-07-29 20:32:37 +08:00
|
|
|
uint64_t Wddm::getDedicatedVideoMemory() const {
|
|
|
|
return dedicatedVideoMemory;
|
|
|
|
}
|
|
|
|
|
2018-03-03 04:43:37 +08:00
|
|
|
uint64_t Wddm::getMaxApplicationAddress() const {
|
2017-12-21 07:45:38 +08:00
|
|
|
return maximumApplicationAddress;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS Wddm::escape(D3DKMT_ESCAPE &escapeCommand) {
|
2020-02-05 17:49:54 +08:00
|
|
|
escapeCommand.hAdapter = getAdapter();
|
|
|
|
return getGdi()->escape(&escapeCommand);
|
2017-12-21 07:45:38 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
PFND3DKMT_ESCAPE Wddm::getEscapeHandle() const {
|
2020-02-05 17:49:54 +08:00
|
|
|
return getGdi()->escape;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-08-07 16:20:07 +08:00
|
|
|
bool Wddm::verifyAdapterLuid(LUID adapterLuid) const {
|
|
|
|
return adapterLuid.HighPart == hwDeviceId->getAdapterLuid().HighPart && adapterLuid.LowPart == hwDeviceId->getAdapterLuid().LowPart;
|
|
|
|
}
|
|
|
|
|
2020-12-11 21:11:00 +08:00
|
|
|
LUID Wddm::getAdapterLuid() const {
|
|
|
|
return hwDeviceId->getAdapterLuid();
|
|
|
|
}
|
|
|
|
|
2021-02-16 22:30:07 +08:00
|
|
|
bool Wddm::isShutdownInProgress() {
|
2021-05-27 05:45:38 +08:00
|
|
|
return NEO::isShutdownInProgress();
|
2021-02-16 22:30:07 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-01-30 22:07:58 +08:00
|
|
|
void Wddm::releaseReservedAddress(void *reservedAddress) {
|
|
|
|
if (reservedAddress) {
|
2021-09-27 21:17:26 +08:00
|
|
|
this->virtualFree(reservedAddress, 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-30 22:07:58 +08:00
|
|
|
bool Wddm::reserveValidAddressRange(size_t size, void *&reservedMem) {
|
2021-09-27 21:17:26 +08:00
|
|
|
reservedMem = this->virtualAlloc(nullptr, size, false);
|
2018-01-30 22:07:58 +08:00
|
|
|
if (reservedMem == nullptr) {
|
|
|
|
return false;
|
|
|
|
} else if (minAddress > reinterpret_cast<uintptr_t>(reservedMem)) {
|
|
|
|
StackVec<void *, 100> invalidAddrVector;
|
|
|
|
invalidAddrVector.push_back(reservedMem);
|
|
|
|
do {
|
2021-09-27 21:17:26 +08:00
|
|
|
reservedMem = this->virtualAlloc(nullptr, size, true);
|
2018-01-30 22:07:58 +08:00
|
|
|
if (minAddress > reinterpret_cast<uintptr_t>(reservedMem) && reservedMem != nullptr) {
|
|
|
|
invalidAddrVector.push_back(reservedMem);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (1);
|
|
|
|
for (auto &it : invalidAddrVector) {
|
2021-09-27 21:17:26 +08:00
|
|
|
this->virtualFree(it, 0);
|
2018-01-30 22:07:58 +08:00
|
|
|
}
|
|
|
|
if (reservedMem == nullptr) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-09-27 21:17:26 +08:00
|
|
|
void *Wddm::virtualAlloc(void *inPtr, size_t size, bool topDownHint) {
|
|
|
|
return osMemory->osReserveCpuAddressRange(inPtr, size, topDownHint);
|
2018-03-22 17:38:23 +08:00
|
|
|
}
|
2018-05-18 16:18:16 +08:00
|
|
|
|
2021-09-27 21:17:26 +08:00
|
|
|
void Wddm::virtualFree(void *ptr, size_t size) {
|
|
|
|
osMemory->osReleaseCpuAddressRange(ptr, size);
|
2018-03-22 17:38:23 +08:00
|
|
|
}
|
2018-08-23 17:29:39 +08:00
|
|
|
|
2019-07-12 22:50:14 +08:00
|
|
|
void Wddm::waitOnPagingFenceFromCpu() {
|
2020-03-23 23:37:41 +08:00
|
|
|
perfLogStartWaitTime(residencyLogger.get(), currentPagingFenceValue);
|
2019-01-16 22:09:33 +08:00
|
|
|
while (currentPagingFenceValue > *getPagingFenceAddress())
|
2020-03-17 19:19:38 +08:00
|
|
|
perfLogResidencyEnteredWait(residencyLogger.get());
|
|
|
|
|
2020-03-23 23:37:41 +08:00
|
|
|
perfLogResidencyWaitPagingeFenceLog(residencyLogger.get(), *getPagingFenceAddress());
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
|
|
|
|
2019-06-06 00:41:42 +08:00
|
|
|
void Wddm::updatePagingFenceValue(uint64_t newPagingFenceValue) {
|
2022-08-09 21:34:45 +08:00
|
|
|
NEO::MultiThreadHelpers::interlockedMax(currentPagingFenceValue, newPagingFenceValue);
|
2019-06-06 00:41:42 +08:00
|
|
|
}
|
|
|
|
|
2019-12-17 21:29:28 +08:00
|
|
|
WddmVersion Wddm::getWddmVersion() {
|
2021-11-25 17:31:14 +08:00
|
|
|
if (featureTable->flags.ftrWddmHwQueues) {
|
2019-12-17 21:29:28 +08:00
|
|
|
return WddmVersion::WDDM_2_3;
|
|
|
|
} else {
|
|
|
|
return WddmVersion::WDDM_2_0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-23 20:26:56 +08:00
|
|
|
uint32_t Wddm::getRequestedEUCount() const {
|
|
|
|
DEBUG_BREAK_IF(!gtSystemInfo);
|
|
|
|
// Always request even number od EUs
|
2022-05-10 00:21:21 +08:00
|
|
|
return (gtSystemInfo->EUCount / gtSystemInfo->SubSliceCount) & (~1u);
|
2020-03-23 20:26:56 +08:00
|
|
|
};
|
|
|
|
|
2020-03-17 19:19:38 +08:00
|
|
|
void Wddm::createPagingFenceLogger() {
|
|
|
|
if (DebugManager.flags.WddmResidencyLogger.get()) {
|
|
|
|
residencyLogger = std::make_unique<WddmResidencyLogger>(device, pagingFenceAddress);
|
|
|
|
}
|
|
|
|
}
|
2020-11-05 20:40:03 +08:00
|
|
|
|
|
|
|
PhysicalDevicePciBusInfo Wddm::getPciBusInfo() const {
|
2021-06-01 00:58:10 +08:00
|
|
|
if (adapterBDF.Data == std::numeric_limits<uint32_t>::max()) {
|
2022-05-10 01:40:30 +08:00
|
|
|
return PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::invalidValue, PhysicalDevicePciBusInfo::invalidValue, PhysicalDevicePciBusInfo::invalidValue, PhysicalDevicePciBusInfo::invalidValue);
|
2020-11-05 20:40:03 +08:00
|
|
|
}
|
2021-06-01 00:58:10 +08:00
|
|
|
return PhysicalDevicePciBusInfo(0, adapterBDF.Bus, adapterBDF.Device, adapterBDF.Function);
|
2020-11-05 20:40:03 +08:00
|
|
|
}
|
|
|
|
|
2022-10-14 21:02:37 +08:00
|
|
|
PhysicalDevicePciSpeedInfo Wddm::getPciSpeedInfo() const {
|
|
|
|
PhysicalDevicePciSpeedInfo speedInfo{};
|
2022-02-28 21:31:18 +08:00
|
|
|
return speedInfo;
|
|
|
|
}
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
} // namespace NEO
|