2017-12-21 07:45:38 +08:00
/*
2025-01-05 03:04:33 +08:00
* Copyright ( C ) 2018 - 2025 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"
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"
2023-05-19 00:27:44 +08:00
# include "shared/source/gmm_helper/client_context/map_gpu_va_gmm.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-05-09 09:56:50 +08:00
# include "shared/source/helpers/compiler_product_helper.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"
# 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 )
2023-12-14 00:09:52 +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 ) ;
2023-06-07 20:38:53 +08:00
gfxPlatform . reset ( new PLATFORM_KMD ) ;
2024-03-06 18:03:52 +08:00
gfxFeatureTable . reset ( new SKU_FEATURE_TABLE_KMD ) ;
gfxWorkaroundTable . reset ( new WA_TABLE_KMD ) ;
2018-03-03 04:43:37 +08:00
memset ( gtSystemInfo . get ( ) , 0 , sizeof ( * gtSystemInfo ) ) ;
memset ( gfxPlatform . get ( ) , 0 , sizeof ( * gfxPlatform ) ) ;
2021-05-27 05:45:38 +08:00
this - > enablePreemptionRegValue = NEO : : readEnablePreemptionRegKey ( ) ;
2025-01-09 08:11:44 +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 ( ) ;
2023-05-29 22:06:01 +08:00
bool forceCheck = false ;
# if _DEBUG
forceCheck = true ;
# endif
2023-11-30 16:32:25 +08:00
checkDeviceState = ( debugManager . flags . EnableDeviceStateVerification . get ( ) ! = - 1 ) ? debugManager . flags . EnableDeviceStateVerification . get ( ) : forceCheck ;
pagingFenceDelayTime = debugManager . flags . WddmPagingFenceCpuWaitDelayTime . get ( ) ;
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
}
2023-10-05 18:47:44 +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 ( ) ;
2024-09-12 21:00:25 +08:00
rootDeviceEnvironment . initializeGfxCoreHelperFromHwInfo ( ) ;
2023-11-28 23:15:25 +08:00
rootDeviceEnvironment . initAilConfigurationHelper ( ) ;
if ( false = = rootDeviceEnvironment . initAilConfiguration ( ) ) {
return false ;
}
2023-05-08 22:54:35 +08:00
populateIpVersion ( * hardwareInfo ) ;
2023-04-13 22:16:49 +08:00
rootDeviceEnvironment . initReleaseHelper ( ) ;
2023-09-15 18:28:08 +08:00
rootDeviceEnvironment . setRcsExposure ( ) ;
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-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
2023-12-19 18:17:17 +08:00
if ( WddmVersion : : wddm23 = = 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
}
2024-07-30 01:46:50 +08:00
if ( ! buildTopologyMapping ( ) ) {
return false ;
}
2022-07-28 21:09:14 +08:00
2023-12-04 20:06:22 +08:00
setProcessPowerThrottling ( ) ;
2024-01-12 23:43:57 +08:00
setThreadPriority ( ) ;
2023-12-04 20:06:22 +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 =
2023-11-30 16:32:25 +08:00
debugManager . flags . PlaformSupportEvictIfNecessaryFlag . get ( ) ;
2022-08-22 20:11:44 +08:00
if ( overridePlatformSupportsEvictIfNecessary ! = - 1 ) {
platformSupportsEvictIfNecessary = ! ! overridePlatformSupportsEvictIfNecessary ;
2022-07-26 05:33:42 +08:00
}
2023-11-30 16:32:25 +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 ) ;
2024-03-28 04:53:04 +08:00
// subSliceIndex is used to track the index number of subslices from all SS or DSS in this slice
2022-07-28 21:09:14 +08:00
int subSliceIndex = - 1 ;
2024-07-15 23:40:39 +08:00
bool dssEnabled = false ;
2022-07-28 21:09:14 +08:00
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 ;
}
2024-07-15 23:40:39 +08:00
dssEnabled = true ;
2022-07-28 21:09:14 +08:00
subSliceCount + + ;
subSliceIndices . push_back ( subSliceIndex ) ;
euCount + = gtSystemInfo . SliceInfo [ x ] . DSSInfo [ dss ] . SubSlice [ y ] . EuEnabledCount ;
}
}
2024-07-15 23:40:39 +08:00
if ( ! dssEnabled ) {
subSliceIndex = - 1 ;
2024-03-28 04:53:04 +08:00
for ( uint32_t sss = 0 ; sss < GT_MAX_SUBSLICE_PER_SLICE ; sss + + ) {
subSliceIndex + + ;
if ( ! gtSystemInfo . SliceInfo [ x ] . SubSliceInfo [ sss ] . Enabled ) {
continue ;
}
subSliceCount + + ;
subSliceIndices . push_back ( subSliceIndex ) ;
euCount + = gtSystemInfo . SliceInfo [ x ] . SubSliceInfo [ sss ] . EuEnabledCount ;
}
}
2022-07-28 21:09:14 +08:00
// 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 ) ) ;
2023-06-07 20:38:53 +08:00
memcpy_s ( gfxPlatform . get ( ) , sizeof ( PLATFORM_KMD ) , & adapterInfo . GfxPlatform , sizeof ( PLATFORM_KMD ) ) ;
2024-03-06 18:03:52 +08:00
memcpy_s ( gfxFeatureTable . get ( ) , sizeof ( SKU_FEATURE_TABLE_KMD ) , & adapterInfo . SkuTable , sizeof ( SKU_FEATURE_TABLE_KMD ) ) ;
memcpy_s ( gfxWorkaroundTable . get ( ) , sizeof ( WA_TABLE_KMD ) , & adapterInfo . WaTable , sizeof ( WA_TABLE_KMD ) ) ;
2023-09-28 00:41:09 +08:00
2023-11-30 16:32:25 +08:00
if ( debugManager . flags . ForceDeviceId . get ( ) ! = " unk " ) {
gfxPlatform - > usDeviceID = static_cast < unsigned short > ( std : : stoi ( debugManager . flags . ForceDeviceId . get ( ) , nullptr , 16 ) ) ;
2023-07-26 19:23:48 +08:00
}
2018-03-03 04:43:37 +08:00
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
2025-01-15 09:11:43 +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 ) ;
2023-11-30 16:32:25 +08:00
if ( false = = umKmDataTranslator - > enabled ( ) & & ! debugManager . flags . DoNotValidateDriverPath . get ( ) ) {
2022-05-12 22:04:41 +08:00
if ( false = = validDriverStorePath ( osEnvironment , openAdapterData . hAdapter ) ) {
2025-01-10 01:28:35 +08:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " Driver path is not a valid DriverStore path. Try running with debug key: DoNotValidateDriverPath=1. \n " ) ;
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 ;
2023-11-30 16:32:25 +08:00
if ( debugManager . flags . CreateMultipleRootDevices . get ( ) ) {
numRootDevices = debugManager . flags . CreateMultipleRootDevices . get ( ) ;
2020-05-20 23:06:32 +08:00
}
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 ;
}
2023-12-12 22:49:00 +08:00
if ( adapterDesc . type = = AdapterFactory : : AdapterDesc : : Type : : notHardware ) {
2021-05-11 23:07:20 +08:00
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 ) {
2024-11-26 21:29:50 +08:00
if ( numOfHandles = = 0 ) {
return true ;
}
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 ) ;
2024-11-27 18:45:37 +08:00
DEBUG_BREAK_IF ( status ! = STATUS_SUCCESS ) ;
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 {
2024-06-25 22:05:54 +08:00
DEBUG_BREAK_IF ( cantTrimFurther ) ;
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 ) ;
2023-06-29 20:53:36 +08:00
this - > setNewResourceBoundToPageTable ( ) ;
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 ) ,
2024-04-12 19:05:44 +08:00
osHandle - > gpuPtr , AllocationType : : externalHostPtr ) ;
2017-12-21 07:45:38 +08:00
}
2024-04-12 19:05:44 +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 , AllocationType type ) {
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
2024-04-12 19:05:44 +08:00
applyAdditionalMapGPUVAFields ( mapGPUVA , gmm , type ) ;
2023-06-15 23:06:26 +08:00
MapGpuVirtualAddressGmm gmmMapGpuVa = { & mapGPUVA , gmm - > gmmResourceInfo . get ( ) , & gpuPtr , getGdi ( ) } ;
2023-05-19 00:27:44 +08:00
auto status = gmm - > getGmmHelper ( ) - > getClientContext ( ) - > mapGpuVirtualAddress ( & gmmMapGpuVa ) ;
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 > ( ) ;
2024-03-25 22:44:36 +08:00
if ( gmm - > isCompressionEnabled ( ) & & productHelper . isPageTableManagerSupported ( * rootDeviceEnvironment . getHardwareInfo ( ) ) ) {
2023-08-07 21:33:24 +08:00
this - > forEachContextWithinWddm ( [ & ] ( const EngineControl & engine ) {
if ( engine . commandStreamReceiver - > pageTableManager . get ( ) ) {
ret & = engine . commandStreamReceiver - > pageTableManager - > updateAuxTable ( gpuPtr , gmm , true ) ;
2021-09-29 23:59:41 +08:00
}
2023-08-07 21:33:24 +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
}
2023-04-27 04:16:48 +08:00
NTSTATUS Wddm : : reserveGpuVirtualAddress ( D3DGPU_VIRTUAL_ADDRESS baseAddress ,
D3DGPU_VIRTUAL_ADDRESS minimumAddress ,
D3DGPU_VIRTUAL_ADDRESS maximumAddress ,
D3DGPU_SIZE_T size ,
D3DGPU_VIRTUAL_ADDRESS * reservedAddress ) {
2019-02-26 15:28:41 +08:00
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 ) ;
2023-04-27 04:16:48 +08:00
* reservedAddress = reserveGpuVirtualAddress . VirtualAddress ;
return status ;
2019-02-26 15:28:41 +08:00
}
2023-05-19 00:27:44 +08:00
uint64_t Wddm : : freeGmmGpuVirtualAddress ( Gmm * gmm , D3DGPU_VIRTUAL_ADDRESS & gpuPtr , uint64_t size ) {
uint64_t status = STATUS_SUCCESS ;
2023-06-15 23:06:26 +08:00
FreeGpuVirtualAddressGmm freeGpuva = { getAdapter ( ) , rootDeviceEnvironment . getGmmHelper ( ) - > decanonize ( gpuPtr ) , size , gmm - > gmmResourceInfo . get ( ) , getGdi ( ) } ;
2023-05-19 00:27:44 +08:00
status = gmm - > getGmmHelper ( ) - > getClientContext ( ) - > freeGpuVirtualAddress ( & freeGpuva ) ;
return status ;
}
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 ;
2025-01-31 03:43:45 +08:00
createAllocation . Flags . ReadOnly = getReadOnlyFlagValue ( alignedCpuPtr ) ;
2022-05-12 22:04:41 +08:00
createAllocation . pAllocationInfo2 = & allocationInfo ;
createAllocation . hDevice = device ;
2024-07-16 18:25:32 +08:00
bool allowNotZeroForCompressed = false ;
if ( NEO : : debugManager . flags . AllowNotZeroForCompressedOnWddm . get ( ) ! = - 1 ) {
allowNotZeroForCompressed = ! ! NEO : : debugManager . flags . AllowNotZeroForCompressedOnWddm . get ( ) ;
}
if ( allowNotZeroForCompressed & & gmm - > isCompressionEnabled ( ) ) {
createAllocation . Flags . AllowNotZeroed = 1 ;
}
2022-05-12 22:04:41 +08:00
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 ;
2025-01-31 03:43:45 +08:00
createAllocation . Flags . ReadOnly = getReadOnlyFlagValue ( allocationInfo [ 0 ] . pSystemMem ) ;
2022-05-12 22:04:41 +08:00
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 ) {
2023-11-30 16:32:25 +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 ;
2023-11-30 16:32:25 +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 ;
}
2024-10-23 18:26:49 +08:00
2017-12-21 07:45:38 +08:00
NTSTATUS status = STATUS_SUCCESS ;
2024-10-23 18:26:49 +08:00
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 ;
2024-10-23 18:26:49 +08:00
destroyAllocation . Flags . AssumeNotInUse = debugManager . flags . SetAssumeNotInUse . get ( ) ;
2017-12-21 07:45:38 +08:00
2024-10-23 18:26:49 +08:00
DeallocateGmm deallocateGmm { & destroyAllocation , getGdi ( ) } ;
2017-12-21 07:45:38 +08:00
2024-10-23 18:26:49 +08:00
if ( debugManager . flags . DestroyAllocationsViaGmm . get ( ) ) {
status = static_cast < NTSTATUS > ( this - > rootDeviceEnvironment . getGmmClientContext ( ) - > deallocate2 ( & deallocateGmm ) ) ;
} else {
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
2024-06-18 20:10:24 +08:00
bool Wddm : : openSharedHandle ( const MemoryManager : : OsHandleData & osHandleData , WddmAllocation * alloc ) {
2022-05-12 22:04:41 +08:00
D3DKMT_QUERYRESOURCEINFO queryResourceInfo = { } ;
queryResourceInfo . hDevice = device ;
2024-06-07 00:56:16 +08:00
queryResourceInfo . hGlobalShare = osHandleData . handle ;
2022-05-12 22:04:41 +08:00
[[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 ;
}
2025-01-09 08:11:44 +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_OPENALLOCATIONINFO [ ] > allocationInfo ( new D3DDDI_OPENALLOCATIONINFO [ 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 ;
2024-06-07 00:56:16 +08:00
openResource . hGlobalShare = osHandleData . handle ;
2022-05-12 22:04:41 +08:00
openResource . NumAllocations = queryResourceInfo . NumAllocations ;
2024-06-12 23:32:01 +08:00
openResource . pOpenAllocationInfo = allocationInfo . get ( ) ;
2022-05-12 22:04:41 +08:00
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 ) ;
2024-06-12 23:32:01 +08:00
auto allocationInfoIndex = osHandleData . arrayIndex < queryResourceInfo . NumAllocations ? osHandleData . arrayIndex : 0 ;
alloc - > setDefaultHandle ( allocationInfo [ allocationInfoIndex ] . hAllocation ) ;
2024-03-25 22:44:36 +08:00
alloc - > setResourceHandle ( openResource . hResource ) ;
2017-12-21 07:45:38 +08:00
2024-06-12 23:32:01 +08:00
auto resourceInfo = const_cast < void * > ( allocationInfo [ allocationInfoIndex ] . 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 ;
}
2024-06-18 20:10:24 +08:00
bool Wddm : : openNTHandle ( const MemoryManager : : OsHandleData & osHandleData , WddmAllocation * alloc ) {
2017-12-21 07:45:38 +08:00
D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE queryResourceInfoFromNtHandle = { } ;
queryResourceInfoFromNtHandle . hDevice = device ;
2024-06-12 18:50:02 +08:00
queryResourceInfoFromNtHandle . hNtHandle = reinterpret_cast < HANDLE > ( static_cast < uintptr_t > ( osHandleData . 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 ) ;
2024-06-25 02:07:45 +08:00
if ( queryResourceInfoFromNtHandle . NumAllocations = = 0 ) {
return false ;
}
2025-01-09 08:11:44 +08:00
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 ] ) ;
2017-12-21 07:45:38 +08:00
D3DKMT_OPENRESOURCEFROMNTHANDLE openResourceFromNtHandle = { } ;
openResourceFromNtHandle . hDevice = device ;
2024-06-12 18:50:02 +08:00
openResourceFromNtHandle . hNtHandle = reinterpret_cast < HANDLE > ( static_cast < uintptr_t > ( osHandleData . handle ) ) ;
2017-12-21 07:45:38 +08:00
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 ) ;
2024-06-12 23:32:01 +08:00
auto allocationInfoIndex = osHandleData . arrayIndex < queryResourceInfoFromNtHandle . NumAllocations ? osHandleData . arrayIndex : 0 ;
auto resourceInfo = const_cast < void * > ( allocationInfo2 [ allocationInfoIndex ] . pPrivateDriverData ) ;
2022-04-19 20:11:45 +08:00
alloc - > setDefaultGmm ( new Gmm ( rootDeviceEnvironment . getGmmHelper ( ) , static_cast < GMM_RESOURCE_INFO * > ( resourceInfo ) , hwDeviceId - > getUmKmDataTranslator ( ) - > enabled ( ) ) ) ;
2024-06-12 23:32:01 +08:00
alloc - > setDefaultHandle ( allocationInfo2 [ allocationInfoIndex ] . hAllocation ) ;
2024-03-25 22:44:36 +08:00
alloc - > setResourceHandle ( openResourceFromNtHandle . hResource ) ;
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-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 ;
2023-08-16 18:40:07 +08:00
NTSTATUS status = getGdi ( ) - > lock2 ( & lock2 ) ;
if ( status ! = STATUS_SUCCESS ) {
return nullptr ;
}
2017-12-21 07:45:38 +08:00
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 ;
2023-08-16 18:40:07 +08:00
NTSTATUS status = getGdi ( ) - > unlock2 ( & unlock2 ) ;
if ( status ! = STATUS_SUCCESS ) {
return ;
}
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 ;
2024-06-18 17:53:11 +08:00
contextPriority . Priority = - 7 ;
2022-05-10 21:53:48 +08:00
2023-11-30 16:32:25 +08:00
if ( debugManager . flags . ForceWddmLowPriorityContextValue . get ( ) ! = - 1 ) {
contextPriority . Priority = static_cast < INT > ( debugManager . flags . ForceWddmLowPriorityContextValue . get ( ) ) ;
2022-05-10 21:53:48 +08:00
}
auto status = getGdi ( ) - > setSchedulingPriority ( & contextPriority ) ;
2023-11-30 16:32:25 +08:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stdout ,
2022-05-10 21:53:48 +08:00
" \n Set 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
2024-07-22 23:52:02 +08:00
privateData . ProcessID = NEO : : SysCalls : : getProcessId ( ) ;
2022-05-12 22:04:41 +08:00
privateData . pHwContextId = & hwContextId ;
2023-11-30 16:32:25 +08:00
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 ;
2023-11-30 16:32:25 +08:00
createContext . Flags . NullRendering = static_cast < UINT > ( debugManager . flags . EnableNullHardware . get ( ) ) ;
2022-05-12 22:04:41 +08:00
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-11-30 16:32:25 +08:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stdout ,
2023-04-12 15:44:12 +08:00
" \n Created 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
2023-11-30 16:32:25 +08:00
if ( debugManager . flags . PrintDeviceAndEngineIdOnSubmission . get ( ) ) {
2022-02-12 00:28:08 +08:00
printf ( " %u: Wddm Submission with context handle %u and HwQueue handle %u \n " , SysCalls : : getProcessId ( ) , submitArguments . contextHandle , submitArguments . hwQueueHandle ) ;
}
2023-06-27 22:53:54 +08:00
status = getDeviceState ( ) ;
if ( ! status ) {
return false ;
}
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 + + ;
2023-11-30 16:32:25 +08:00
} else if ( debugManager . flags . EnableDeviceStateVerificationAfterFailedSubmission . get ( ) = = 1 ) {
2023-11-29 23:15:54 +08:00
getDeviceState ( ) ;
2017-12-21 07:45:38 +08:00
}
2018-08-10 22:41:44 +08:00
return status ;
2017-12-21 07:45:38 +08:00
}
2023-10-30 23:45:17 +08:00
bool Wddm : : getDeviceExecutionState ( D3DKMT_DEVICESTATE_TYPE stateType , void * privateData ) {
D3DKMT_GETDEVICESTATE getDevState = { } ;
NTSTATUS status = STATUS_SUCCESS ;
2017-12-21 07:45:38 +08:00
2023-10-30 23:45:17 +08:00
getDevState . hDevice = device ;
getDevState . StateType = stateType ;
2017-12-21 07:45:38 +08:00
2023-10-30 23:45:17 +08:00
status = getGdi ( ) - > getDeviceState ( & getDevState ) ;
DEBUG_BREAK_IF ( status ! = STATUS_SUCCESS ) ;
if ( status ! = STATUS_SUCCESS ) {
return false ;
}
if ( stateType = = D3DKMT_DEVICESTATE_PAGE_FAULT ) {
if ( privateData ! = nullptr ) {
* reinterpret_cast < D3DKMT_DEVICEPAGEFAULT_STATE * > ( privateData ) = getDevState . PageFaultState ;
}
return true ;
} else if ( stateType = = D3DKMT_DEVICESTATE_EXECUTION ) {
if ( privateData ! = nullptr ) {
* reinterpret_cast < D3DKMT_DEVICEEXECUTION_STATE * > ( privateData ) = getDevState . ExecutionState ;
}
return true ;
} else {
return false ;
}
}
bool Wddm : : getDeviceState ( ) {
if ( checkDeviceState ) {
D3DKMT_DEVICEEXECUTION_STATE executionState = D3DKMT_DEVICEEXECUTION_ACTIVE ;
auto status = getDeviceExecutionState ( D3DKMT_DEVICESTATE_EXECUTION , & executionState ) ;
if ( status ) {
if ( executionState = = D3DKMT_DEVICEEXECUTION_ERROR_OUTOFMEMORY ) {
PRINT_DEBUG_STRING ( true , stderr , " Device execution error, out of memory %d \n " , executionState ) ;
} else if ( executionState = = D3DKMT_DEVICEEXECUTION_ERROR_DMAPAGEFAULT ) {
PRINT_DEBUG_STRING ( true , stderr , " Device execution error, page fault \n " , executionState ) ;
D3DKMT_DEVICEPAGEFAULT_STATE pageFaultState = { } ;
status = getDeviceExecutionState ( D3DKMT_DEVICESTATE_PAGE_FAULT , & pageFaultState ) ;
if ( status ) {
PRINT_DEBUG_STRING ( true , stderr , " faulted gpuva 0x% " PRIx64 " , " , pageFaultState . FaultedVirtualAddress ) ;
PRINT_DEBUG_STRING ( true , stderr , " pipeline stage %d, bind table entry %u, flags 0x%x, error code(is device) %u, error code %u \n " ,
pageFaultState . FaultedPipelineStage , pageFaultState . FaultedBindTableEntry , pageFaultState . PageFaultFlags ,
2024-02-23 19:18:20 +08:00
pageFaultState . FaultErrorCode . IsDeviceSpecificCode , pageFaultState . FaultErrorCode . IsDeviceSpecificCode ? pageFaultState . FaultErrorCode . DeviceSpecificCode : static_cast < UINT > ( pageFaultState . FaultErrorCode . GeneralErrorCode ) ) ;
2024-05-23 16:23:44 +08:00
DBG_LOG ( ResidencyDebugEnable , " Residency: " , __FUNCTION__ , " Page fault detected at address = " , std : : hex , pageFaultState . FaultedVirtualAddress ) ;
2023-10-30 23:45:17 +08:00
}
} else if ( executionState ! = D3DKMT_DEVICEEXECUTION_ACTIVE ) {
PRINT_DEBUG_STRING ( true , stderr , " Device execution error %d \n " , executionState ) ;
}
2024-02-23 19:18:20 +08:00
DEBUG_BREAK_IF ( executionState ! = D3DKMT_DEVICEEXECUTION_ACTIVE ) ;
2023-10-30 23:45:17 +08:00
return executionState = = D3DKMT_DEVICEEXECUTION_ACTIVE ;
2023-05-29 22:06:01 +08:00
}
2023-06-27 22:53:54 +08:00
return false ;
2017-12-21 07:45:38 +08:00
}
2023-06-27 22:53:54 +08:00
return true ;
2017-12-21 07:45:38 +08:00
}
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 ) {
2023-07-27 03:10:25 +08:00
perfLogStartWaitTime ( residencyLogger . get ( ) , currentPagingFenceValue ) ;
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
2023-07-27 03:10:25 +08:00
perfLogResidencyWaitPagingeFenceLog ( residencyLogger . get ( ) , * getPagingFenceAddress ( ) , true ) ;
2017-12-21 07:45:38 +08:00
return status = = STATUS_SUCCESS ;
}
2023-09-08 20:08:28 +08:00
bool Wddm : : waitFromCpu ( uint64_t lastFenceValue , const MonitoredFence & monitoredFence , bool busyWait ) {
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 ) {
2023-08-07 21:33:24 +08:00
if ( lastFenceValue > monitoredFence . lastSubmittedFence ) {
2024-12-09 22:05:54 +08:00
this - > forEachContextWithinWddm ( [ & monitoredFence ] ( const EngineControl & engine ) {
auto & contextMonitoredFence = static_cast < OsContextWin * > ( engine . osContext ) - > getResidencyController ( ) . getMonitoredFence ( ) ;
if ( contextMonitoredFence . cpuAddress = = monitoredFence . cpuAddress ) {
auto lock = engine . commandStreamReceiver - > obtainUniqueOwnership ( ) ;
engine . commandStreamReceiver - > flushMonitorFence ( ) ;
}
2023-08-07 21:33:24 +08:00
} ) ;
}
2023-09-08 20:08:28 +08:00
if ( busyWait ) {
constexpr int64_t timeout = 20 ;
int64_t timeDiff = 0u ;
auto waitStartTime = std : : chrono : : high_resolution_clock : : now ( ) ;
while ( lastFenceValue > * monitoredFence . cpuAddress & & timeDiff < timeout ) {
auto currentTime = std : : chrono : : high_resolution_clock : : now ( ) ;
timeDiff = std : : chrono : : duration_cast < std : : chrono : : microseconds > ( currentTime - waitStartTime ) . count ( ) ;
}
}
if ( lastFenceValue > * monitoredFence . cpuAddress ) {
D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU waitFromCpu = { } ;
waitFromCpu . ObjectCount = 1 ;
waitFromCpu . ObjectHandleArray = & monitoredFence . fenceHandle ;
waitFromCpu . FenceValueArray = & lastFenceValue ;
waitFromCpu . hDevice = device ;
waitFromCpu . hAsyncEvent = NULL_HANDLE ;
status = getGdi ( ) - > waitForSynchronizationObjectFromCpu ( & waitFromCpu ) ;
DEBUG_BREAK_IF ( status ! = STATUS_SUCCESS ) ;
}
2017-12-21 07:45:38 +08:00
}
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
2023-11-30 16:32:25 +08:00
PRINT_DEBUG_STRING ( hangDetected & & debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s " , " ERROR: GPU HANG detected! \n " ) ;
2022-02-15 03:03:10 +08:00
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 ) {
2023-12-12 16:58:42 +08:00
outGfxPartition . heapInit ( HeapIndex : : heapSvm , gfxPartition . SVM . Base , gfxPartition . SVM . Limit - gfxPartition . SVM . Base + 1 ) ;
2019-07-18 21:33:20 +08:00
} else if ( is32bit ) {
2023-12-12 16:58:42 +08:00
outGfxPartition . heapInit ( HeapIndex : : heapSvm , 0x0ull , 4 * MemoryConstants : : gigaByte ) ;
2019-03-01 23:14:28 +08:00
}
2023-12-12 16:58:42 +08:00
outGfxPartition . heapInit ( HeapIndex : : heapStandard , gfxPartition . Standard . Base , gfxPartition . Standard . Limit - gfxPartition . Standard . Base + 1 ) ;
2019-03-01 23:14:28 +08:00
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 ) ;
2023-12-12 16:58:42 +08:00
outGfxPartition . heapInit ( HeapIndex : : heapStandard64KB , 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
2024-08-07 00:13:06 +08:00
void Wddm : : waitOnPagingFenceFromCpu ( uint64_t pagingFenceValueToWait , bool isKmdWaitNeeded ) {
perfLogStartWaitTime ( residencyLogger . get ( ) , pagingFenceValueToWait ) ;
if ( pagingFenceValueToWait > * getPagingFenceAddress ( ) ) {
2023-11-07 22:09:43 +08:00
if ( isKmdWaitNeeded ) {
2023-11-02 22:37:19 +08:00
perfLogResidencyEnteredWait ( residencyLogger . get ( ) ) ;
2023-11-07 22:09:43 +08:00
D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU waitFromCpu = { } ;
waitFromCpu . ObjectCount = 1 ;
waitFromCpu . ObjectHandleArray = & pagingQueueSyncObject ;
2024-08-07 00:13:06 +08:00
waitFromCpu . FenceValueArray = & pagingFenceValueToWait ;
2023-11-07 22:09:43 +08:00
waitFromCpu . hDevice = device ;
waitFromCpu . hAsyncEvent = NULL_HANDLE ;
[[maybe_unused]] auto status = getGdi ( ) - > waitForSynchronizationObjectFromCpu ( & waitFromCpu ) ;
DEBUG_BREAK_IF ( status ! = STATUS_SUCCESS ) ;
} else {
2024-08-07 00:13:06 +08:00
while ( pagingFenceValueToWait > * getPagingFenceAddress ( ) ) {
2023-11-07 22:09:43 +08:00
perfLogResidencyEnteredWait ( residencyLogger . get ( ) ) ;
}
2023-11-02 22:37:19 +08:00
}
if ( pagingFenceDelayTime > 0 ) {
delayPagingFenceFromCpu ( pagingFenceDelayTime ) ;
}
}
2020-03-17 19:19:38 +08:00
2023-07-27 03:10:25 +08:00
perfLogResidencyWaitPagingeFenceLog ( residencyLogger . get ( ) , * getPagingFenceAddress ( ) , false ) ;
2019-01-16 22:09:33 +08:00
}
2023-11-02 22:37:19 +08:00
void Wddm : : delayPagingFenceFromCpu ( int64_t delayTime ) {
int64_t timeDiff = 0u ;
auto waitStartTime = std : : chrono : : high_resolution_clock : : now ( ) ;
while ( timeDiff < delayTime ) {
auto currentTime = std : : chrono : : high_resolution_clock : : now ( ) ;
timeDiff = std : : chrono : : duration_cast < std : : chrono : : microseconds > ( currentTime - waitStartTime ) . count ( ) ;
}
}
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 ) {
2023-12-19 18:17:17 +08:00
return WddmVersion : : wddm23 ;
2019-12-17 21:29:28 +08:00
} else {
2023-12-19 18:17:17 +08:00
return WddmVersion : : wddm20 ;
2019-12-17 21:29:28 +08:00
}
}
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 ( ) {
2023-11-30 16:32:25 +08:00
if ( debugManager . flags . WddmResidencyLogger . get ( ) ) {
residencyLogger = std : : make_unique < WddmResidencyLogger > ( device , pagingFenceAddress , debugManager . flags . WddmResidencyLoggerOutputDirectory . get ( ) ) ;
2020-03-17 19:19:38 +08:00
}
}
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 ;
}
2023-06-07 20:38:53 +08:00
void Wddm : : populateIpVersion ( HardwareInfo & hwInfo ) {
hwInfo . ipVersion . value = gfxPlatform - > sRenderBlockID . Value ;
if ( hwInfo . ipVersion . value = = 0 ) {
auto & compilerProductHelper = rootDeviceEnvironment . getHelper < CompilerProductHelper > ( ) ;
hwInfo . ipVersion . value = compilerProductHelper . getHwIpVersion ( hwInfo ) ;
}
}
2023-06-29 20:53:36 +08:00
void Wddm : : setNewResourceBoundToPageTable ( ) {
2023-12-24 14:46:47 +08:00
if ( ! this - > rootDeviceEnvironment . getProductHelper ( ) . isTlbFlushRequired ( ) ) {
2023-06-29 20:53:36 +08:00
return ;
}
2023-08-07 21:33:24 +08:00
this - > forEachContextWithinWddm ( [ ] ( const EngineControl & engine ) { engine . osContext - > setNewResourceBound ( ) ; } ) ;
2023-06-29 20:53:36 +08:00
}
2019-03-26 18:59:46 +08:00
} // namespace NEO