feature: Native GPU fence synchronization object implementation

Related-To: NEO-10811
Signed-off-by: Krzysztof Sprzaczkowski <krzysztof.sprzaczkowski@intel.com>
This commit is contained in:
Krzysztof Sprzaczkowski 2025-05-06 11:24:01 +00:00 committed by Compute-Runtime-Automation
parent fdb84aaa3d
commit de72e91269
32 changed files with 468 additions and 21 deletions

View File

@ -927,6 +927,7 @@ include_directories(${NEO_SHARED_DIRECTORY}/kernel/definitions${BRANCH_DIR_SUFFI
include_directories(${NEO_SHARED_DIRECTORY}/gen_common${BRANCH_DIR_SUFFIX}) include_directories(${NEO_SHARED_DIRECTORY}/gen_common${BRANCH_DIR_SUFFIX})
if(WIN32) if(WIN32)
include_directories(${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory${BRANCH_DIR_SUFFIX}) include_directories(${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory${BRANCH_DIR_SUFFIX})
include_directories(${NEO_SHARED_DIRECTORY}/os_interface/windows/wddm/definitions)
else() else()
include_directories(${NEO_LINUX_KMD_HEADERS_DIR} include_directories(${NEO_LINUX_KMD_HEADERS_DIR}
${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory ${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory
@ -934,6 +935,9 @@ else()
if("${BRANCH_TYPE}" STREQUAL "") if("${BRANCH_TYPE}" STREQUAL "")
include_directories(${NEO_SOURCE_DIR}/third_party/uapi/prelim) include_directories(${NEO_SOURCE_DIR}/third_party/uapi/prelim)
endif() endif()
if(NOT DISABLE_WDDM_LINUX)
include_directories(${NEO_SHARED_DIRECTORY}/os_interface/linux/wddm_linux/definitions)
endif()
endif() endif()
include_directories(${NEO_SHARED_DIRECTORY}/helpers/definitions${BRANCH_DIR_SUFFIX}) include_directories(${NEO_SHARED_DIRECTORY}/helpers/definitions${BRANCH_DIR_SUFFIX})
include_directories(${NEO_SHARED_DIRECTORY}/memory_properties${BRANCH_DIR_SUFFIX}) include_directories(${NEO_SHARED_DIRECTORY}/memory_properties${BRANCH_DIR_SUFFIX})

View File

@ -86,7 +86,7 @@ void WddmDirectSubmission<GfxFamily, Dispatcher>::ensureRingCompletion() {
template <typename GfxFamily, typename Dispatcher> template <typename GfxFamily, typename Dispatcher>
bool WddmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources() { bool WddmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources() {
bool ret = wddm->getWddmInterface()->createMonitoredFenceForDirectSubmission(ringFence, *this->osContextWin); bool ret = wddm->getWddmInterface()->createFenceForDirectSubmission(ringFence, *this->osContextWin);
perfLogResidencyVariadicLog(wddm->getResidencyLogger(), "ULLS resource allocation finished with: %d\n", ret); perfLogResidencyVariadicLog(wddm->getResidencyLogger(), "ULLS resource allocation finished with: %d\n", ret);
this->ringBufferEndCompletionTagData.tagAddress = this->semaphoreGpuVa + offsetof(RingSemaphoreData, tagAllocation); this->ringBufferEndCompletionTagData.tagAddress = this->semaphoreGpuVa + offsetof(RingSemaphoreData, tagAllocation);

View File

@ -116,8 +116,10 @@ if(DISABLE_WDDM_LINUX)
) )
else() else()
list(APPEND NEO_CORE_OS_INTERFACE_LINUX list(APPEND NEO_CORE_OS_INTERFACE_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/sys_calls_win.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/compatible_driver_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/compatible_driver_store.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/definitions/gdi_interface_logging.inl
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/sys_calls_win.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/wddm_interface_extra.cpp
) )
endif() endif()

View File

@ -0,0 +1,6 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/windows/wddm/wddm.h"
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
using namespace NEO;
bool WddmInterface32::createSyncObject(MonitoredFence &monitorFence) {
UNRECOVERABLE_IF(true);
return false;
}

View File

@ -45,7 +45,9 @@ set(NEO_CORE_OS_INTERFACE_WINDOWS
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_create_with_fallback.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_create_with_fallback.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.h ${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.h
${CMAKE_CURRENT_SOURCE_DIR}/wddm/definitions/gdi_interface_logging.inl
${CMAKE_CURRENT_SOURCE_DIR}/wddm/read_preemption_regkey.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm/read_preemption_regkey.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm_interface_extra.cpp
${CMAKE_CURRENT_SOURCE_DIR}/windows_inc.cpp ${CMAKE_CURRENT_SOURCE_DIR}/windows_inc.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm/${BRANCH_DIR_SUFFIX}/perf_wddm.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm/${BRANCH_DIR_SUFFIX}/perf_wddm.cpp
) )
@ -127,6 +129,7 @@ set(NEO_CORE_OS_INTERFACE_WDDM
${CMAKE_CURRENT_SOURCE_DIR}/sys_calls_wrapper.h ${CMAKE_CURRENT_SOURCE_DIR}/sys_calls_wrapper.h
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/init_context_private_data.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/init_context_private_data.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/wddm_debug_interface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/wddm_debug_interface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/wddm_features_extra.cpp
) )
if(NOT WIN32 AND NOT DISABLE_WDDM_LINUX) if(NOT WIN32 AND NOT DISABLE_WDDM_LINUX)

View File

@ -59,6 +59,7 @@ bool Gdi::getAllProcAddresses() {
createSynchronizationObject = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject"); createSynchronizationObject = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject");
createSynchronizationObject2 = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject2"); createSynchronizationObject2 = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject2");
destroySynchronizationObject = gdiDll->getProcAddress("D3DKMTDestroySynchronizationObject"); destroySynchronizationObject = gdiDll->getProcAddress("D3DKMTDestroySynchronizationObject");
createNativeFence = gdiDll->getProcAddress("D3DKMTCreateNativeFence");
signalSynchronizationObject = gdiDll->getProcAddress("D3DKMTSignalSynchronizationObject"); signalSynchronizationObject = gdiDll->getProcAddress("D3DKMTSignalSynchronizationObject");
waitForSynchronizationObject = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObject"); waitForSynchronizationObject = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObject");
waitForSynchronizationObjectFromCpu = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObjectFromCpu"); waitForSynchronizationObjectFromCpu = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObjectFromCpu");

View File

@ -13,6 +13,8 @@
#include <memory> #include <memory>
typedef struct _D3DKMT_CREATENATIVEFENCE D3DKMT_CREATENATIVEFENCE;
namespace NEO { namespace NEO {
#define DEFINE_THK_WRAPPER(TYPE, VAR) ThkWrapper<TYPE> VAR = ThkWrapper<TYPE>(this->profiler, #TYPE, this->gdiId++); #define DEFINE_THK_WRAPPER(TYPE, VAR) ThkWrapper<TYPE> VAR = ThkWrapper<TYPE>(this->profiler, #TYPE, this->gdiId++);
@ -46,6 +48,7 @@ class Gdi {
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT *, createSynchronizationObject); DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT *, createSynchronizationObject);
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *, createSynchronizationObject2); DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *, createSynchronizationObject2);
DEFINE_THK_WRAPPER(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *, destroySynchronizationObject); DEFINE_THK_WRAPPER(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *, destroySynchronizationObject);
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATENATIVEFENCE *, createNativeFence);
DEFINE_THK_WRAPPER(IN CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECT *, signalSynchronizationObject); DEFINE_THK_WRAPPER(IN CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECT *, signalSynchronizationObject);
DEFINE_THK_WRAPPER(IN CONST_FROM_WDK_10_0_18328_0 D3DKMT_WAITFORSYNCHRONIZATIONOBJECT *, waitForSynchronizationObject); DEFINE_THK_WRAPPER(IN CONST_FROM_WDK_10_0_18328_0 D3DKMT_WAITFORSYNCHRONIZATIONOBJECT *, waitForSynchronizationObject);
DEFINE_THK_WRAPPER(IN CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU *, waitForSynchronizationObjectFromCpu); DEFINE_THK_WRAPPER(IN CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU *, waitForSynchronizationObjectFromCpu);

View File

@ -466,6 +466,8 @@ template void logExit<CONST D3DKMT_SETALLOCATIONPRIORITY *>(NTSTATUS status, CON
template void logEnter<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param); template void logEnter<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param);
template void logExit<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(NTSTATUS status, CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param); template void logExit<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(NTSTATUS status, CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param);
#include "gdi_interface_logging.inl"
} // namespace GdiLogging } // namespace GdiLogging
} // namespace NEO } // namespace NEO

View File

@ -0,0 +1,14 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
template <>
void getEnterString<D3DKMT_CREATENATIVEFENCE *>(D3DKMT_CREATENATIVEFENCE *param, char *input, size_t size) {
snprintf_s(input, size, size, "D3DKMT_CREATENATIVEFENCE Info Type %u Info Flags 0x%x", param->Info.Type, param->Info.Flags.Value);
}
template void logEnter<D3DKMT_CREATENATIVEFENCE *>(D3DKMT_CREATENATIVEFENCE *param);
template void logExit<D3DKMT_CREATENATIVEFENCE *>(NTSTATUS status, D3DKMT_CREATENATIVEFENCE *param);

View File

@ -138,7 +138,10 @@ bool Wddm::init() {
rootDeviceEnvironment.initGmm(); rootDeviceEnvironment.initGmm();
this->rootDeviceEnvironment.getGmmClientContext()->setHandleAllocator(this->hwDeviceId->getUmKmDataTranslator()->createGmmHandleAllocator()); this->rootDeviceEnvironment.getGmmClientContext()->setHandleAllocator(this->hwDeviceId->getUmKmDataTranslator()->createGmmHandleAllocator());
if (WddmVersion::wddm23 == getWddmVersion()) { auto wddmVersion = getWddmVersion();
if (WddmVersion::wddm32 == wddmVersion) {
wddmInterface = std::make_unique<WddmInterface32>(*this);
} else if (WddmVersion::wddm23 == wddmVersion) {
wddmInterface = std::make_unique<WddmInterface23>(*this); wddmInterface = std::make_unique<WddmInterface23>(*this);
} else { } else {
wddmInterface = std::make_unique<WddmInterface20>(*this); wddmInterface = std::make_unique<WddmInterface20>(*this);
@ -1392,6 +1395,9 @@ void Wddm::updatePagingFenceValue(uint64_t newPagingFenceValue) {
WddmVersion Wddm::getWddmVersion() { WddmVersion Wddm::getWddmVersion() {
if (featureTable->flags.ftrWddmHwQueues) { if (featureTable->flags.ftrWddmHwQueues) {
if (isNativeFenceAvailable()) {
return WddmVersion::wddm32;
}
return WddmVersion::wddm23; return WddmVersion::wddm23;
} else { } else {
return WddmVersion::wddm20; return WddmVersion::wddm20;

View File

@ -106,6 +106,7 @@ class Wddm : public DriverModel {
MOCKABLE_VIRTUAL bool isShutdownInProgress(); MOCKABLE_VIRTUAL bool isShutdownInProgress();
MOCKABLE_VIRTUAL bool isDebugAttachAvailable(); MOCKABLE_VIRTUAL bool isDebugAttachAvailable();
MOCKABLE_VIRTUAL bool isNativeFenceAvailable();
bool isGpuHangDetected(OsContext &osContext) override; bool isGpuHangDetected(OsContext &osContext) override;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020-2023 Intel Corporation * Copyright (C) 2020-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -20,6 +20,7 @@ struct WddmSubmitArguments {
enum class WddmVersion : uint32_t { enum class WddmVersion : uint32_t {
wddm20 = 0, wddm20 = 0,
wddm23 wddm23,
wddm32
}; };
} // namespace NEO } // namespace NEO

View File

@ -0,0 +1,17 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/os_interface.h"
#include "shared/source/os_interface/windows/wddm/wddm.h"
namespace NEO {
bool Wddm::isNativeFenceAvailable() {
return false;
}
} // namespace NEO

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -97,7 +97,7 @@ bool WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *commandH
return STATUS_SUCCESS == status; return STATUS_SUCCESS == status;
} }
bool NEO::WddmInterface20::createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) { bool NEO::WddmInterface20::createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) {
auto ret = WddmInterface::createMonitoredFence(monitorFence); auto ret = WddmInterface::createMonitoredFence(monitorFence);
monitorFence.currentFenceValue = 1; monitorFence.currentFenceValue = 1;
return ret; return ret;
@ -177,9 +177,9 @@ bool WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandH
return status == STATUS_SUCCESS; return status == STATUS_SUCCESS;
} }
bool NEO::WddmInterface23::createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) { bool NEO::WddmInterface23::createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) {
MonitoredFence monitorFenceForResidency{}; MonitoredFence monitorFenceForResidency{};
auto ret = WddmInterface::createMonitoredFence(monitorFenceForResidency); auto ret = createSyncObject(monitorFenceForResidency);
auto &residencyController = osContext.getResidencyController(); auto &residencyController = osContext.getResidencyController();
auto lastSubmittedFence = residencyController.getMonitoredFence().lastSubmittedFence; auto lastSubmittedFence = residencyController.getMonitoredFence().lastSubmittedFence;
auto currentFenceValue = residencyController.getMonitoredFence().currentFenceValue; auto currentFenceValue = residencyController.getMonitoredFence().currentFenceValue;
@ -198,3 +198,8 @@ bool NEO::WddmInterface23::createMonitoredFenceForDirectSubmission(MonitoredFenc
return ret; return ret;
} }
bool WddmInterface23::createSyncObject(MonitoredFence &monitorFence) {
auto ret = WddmInterface::createMonitoredFence(monitorFence);
return ret;
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -31,7 +31,7 @@ class WddmInterface {
virtual void destroyMonitorFence(MonitoredFence &monitorFence) = 0; virtual void destroyMonitorFence(MonitoredFence &monitorFence) = 0;
virtual bool hwQueuesSupported() = 0; virtual bool hwQueuesSupported() = 0;
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) = 0; virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) = 0;
virtual bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) = 0; virtual bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) = 0;
Wddm &wddm; Wddm &wddm;
}; };
@ -44,7 +44,7 @@ class WddmInterface20 : public WddmInterface {
void destroyMonitorFence(MonitoredFence &monitorFence) override; void destroyMonitorFence(MonitoredFence &monitorFence) override;
bool hwQueuesSupported() override; bool hwQueuesSupported() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override; bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override;
bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override; bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override;
}; };
class WddmInterface23 : public WddmInterface { class WddmInterface23 : public WddmInterface {
@ -56,6 +56,13 @@ class WddmInterface23 : public WddmInterface {
void destroyMonitorFence(MonitoredFence &monitorFence) override; void destroyMonitorFence(MonitoredFence &monitorFence) override;
bool hwQueuesSupported() override; bool hwQueuesSupported() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override; bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override;
bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override; bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override;
virtual bool createSyncObject(MonitoredFence &monitorFence);
};
class WddmInterface32 : public WddmInterface23 {
public:
using WddmInterface23::WddmInterface23;
bool createSyncObject(MonitoredFence &monitorFence) override;
}; };
} // namespace NEO } // namespace NEO

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/windows/gdi_interface.h"
#include "shared/source/os_interface/windows/wddm/wddm.h"
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
using namespace NEO;
bool WddmInterface32::createSyncObject(MonitoredFence &monitorFence) {
UNRECOVERABLE_IF(wddm.getGdi()->createNativeFence == nullptr);
NTSTATUS status = STATUS_SUCCESS;
D3DKMT_CREATENATIVEFENCE createNativeFenceObject = {0};
createNativeFenceObject.hDevice = wddm.getDeviceHandle();
createNativeFenceObject.Info.Type = D3DDDI_NATIVEFENCE_TYPE_DEFAULT;
createNativeFenceObject.Info.InitialFenceValue = 0;
status = wddm.getGdi()->createNativeFence(&createNativeFenceObject);
DEBUG_BREAK_IF(STATUS_SUCCESS != status);
monitorFence.fenceHandle = createNativeFenceObject.hSyncObject;
monitorFence.cpuAddress = reinterpret_cast<uint64_t *>(createNativeFenceObject.Info.NativeFenceMapping.CurrentValueCpuVa);
monitorFence.gpuAddress = createNativeFenceObject.Info.NativeFenceMapping.CurrentValueGpuVa;
return status == STATUS_SUCCESS;
}

View File

@ -560,6 +560,10 @@ NTSTATUS __stdcall mockD3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESY
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS __stdcall mockD3DKMTCreateNativeFence(IN OUT D3DKMT_CREATENATIVEFENCE *synchObject) {
return STATUS_SUCCESS;
}
NTSTATUS __stdcall mockD3DKMTSetAllocationPriority(IN CONST D3DKMT_SETALLOCATIONPRIORITY *setAllocationPriority) { NTSTATUS __stdcall mockD3DKMTSetAllocationPriority(IN CONST D3DKMT_SETALLOCATIONPRIORITY *setAllocationPriority) {
if (setAllocationPriority == nullptr || setAllocationPriority->hDevice != DEVICE_HANDLE) { if (setAllocationPriority == nullptr || setAllocationPriority->hDevice != DEVICE_HANDLE) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;

View File

@ -29,6 +29,8 @@
#define GPUVA (static_cast<D3DGPU_VIRTUAL_ADDRESS>(0x80123000000)) #define GPUVA (static_cast<D3DGPU_VIRTUAL_ADDRESS>(0x80123000000))
typedef struct _D3DKMT_CREATENATIVEFENCE D3DKMT_CREATENATIVEFENCE;
void mockSetAdapterInfo(const void *pGfxPlatform, const void *pGTSystemInfo, uint64_t gpuAddressSpace); void mockSetAdapterInfo(const void *pGfxPlatform, const void *pGTSystemInfo, uint64_t gpuAddressSpace);
NTSTATUS __stdcall mockD3DKMTCreateAllocation(IN OUT D3DKMT_CREATEALLOCATION *allocation); NTSTATUS __stdcall mockD3DKMTCreateAllocation(IN OUT D3DKMT_CREATEALLOCATION *allocation);
NTSTATUS __stdcall mockD3DKMTCreateAllocation2(IN OUT D3DKMT_CREATEALLOCATION *allocation); NTSTATUS __stdcall mockD3DKMTCreateAllocation2(IN OUT D3DKMT_CREATEALLOCATION *allocation);
@ -47,6 +49,7 @@ NTSTATUS __stdcall mockD3DKMTQueryResourceInfo(IN OUT D3DKMT_QUERYRESOURCEINFO *
NTSTATUS __stdcall mockD3DKMTQueryResourceInfoFromNtHandle(IN OUT D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE *queryResourceInfo); NTSTATUS __stdcall mockD3DKMTQueryResourceInfoFromNtHandle(IN OUT D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE *queryResourceInfo);
NTSTATUS __stdcall mockD3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *synchObject); NTSTATUS __stdcall mockD3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *synchObject);
NTSTATUS __stdcall mockD3DKMTDestroySynchronizationObject(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *destroySynchronizationObject); NTSTATUS __stdcall mockD3DKMTDestroySynchronizationObject(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *destroySynchronizationObject);
NTSTATUS __stdcall mockD3DKMTCreateNativeFence(IN OUT D3DKMT_CREATENATIVEFENCE *synchObject);
NTSTATUS __stdcall mockD3DKMTCreatePagingQueue(IN OUT D3DKMT_CREATEPAGINGQUEUE *createQueue); NTSTATUS __stdcall mockD3DKMTCreatePagingQueue(IN OUT D3DKMT_CREATEPAGINGQUEUE *createQueue);
NTSTATUS __stdcall mockD3DKMTDestroyPagingQueue(IN OUT D3DDDI_DESTROYPAGINGQUEUE *destoryQueue); NTSTATUS __stdcall mockD3DKMTDestroyPagingQueue(IN OUT D3DDDI_DESTROYPAGINGQUEUE *destoryQueue);
NTSTATUS __stdcall mockD3DKMTLock2(IN OUT D3DKMT_LOCK2 *lock2); NTSTATUS __stdcall mockD3DKMTLock2(IN OUT D3DKMT_LOCK2 *lock2);

View File

@ -67,6 +67,9 @@ void *MockOsLibrary::getProcAddress(const std::string &procName) {
if (procName == "D3DKMTCreateSynchronizationObject2") { if (procName == "D3DKMTCreateSynchronizationObject2") {
return reinterpret_cast<void *>(mockD3DKMTCreateSynchronizationObject2); return reinterpret_cast<void *>(mockD3DKMTCreateSynchronizationObject2);
} }
if (procName == "D3DKMTCreateNativeFence") {
return reinterpret_cast<void *>(mockD3DKMTCreateNativeFence);
}
if (procName == "D3DKMTDestroySynchronizationObject") { if (procName == "D3DKMTDestroySynchronizationObject") {
return reinterpret_cast<void *>(mockD3DKMTDestroySynchronizationObject); return reinterpret_cast<void *>(mockD3DKMTDestroySynchronizationObject);
} }

View File

@ -128,6 +128,7 @@ if(WIN32 OR NOT DISABLE_WDDM_LINUX)
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface20.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface20.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface23.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface23.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface32.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_allocations_container.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_allocations_container.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_logger.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_logger.h
${CMAKE_CURRENT_SOURCE_DIR}/wddm_mock_helpers.h ${CMAKE_CURRENT_SOURCE_DIR}/wddm_mock_helpers.h

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2024 Intel Corporation * Copyright (C) 2024-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -20,6 +20,6 @@ class WddmMockInterface : public WddmInterface {
ADDMETHOD_NOBASE_VOIDRETURN(destroyMonitorFence, (MonitoredFence & monitorFence)); ADDMETHOD_NOBASE_VOIDRETURN(destroyMonitorFence, (MonitoredFence & monitorFence));
ADDMETHOD_NOBASE(hwQueuesSupported, bool, false, ()); ADDMETHOD_NOBASE(hwQueuesSupported, bool, false, ());
ADDMETHOD_NOBASE(submit, bool, true, (uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments)); ADDMETHOD_NOBASE(submit, bool, true, (uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments));
ADDMETHOD_NOBASE(createMonitoredFenceForDirectSubmission, bool, true, (MonitoredFence & monitorFence, OsContextWin &osContext)); ADDMETHOD_NOBASE(createFenceForDirectSubmission, bool, true, (MonitoredFence & monitorFence, OsContextWin &osContext));
}; };
} // namespace NEO } // namespace NEO

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019-2024 Intel Corporation * Copyright (C) 2019-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -33,7 +33,7 @@ class WddmMockInterface20 : public WddmInterface20 {
return WddmInterface::createMonitoredFence(monitorFence); return WddmInterface::createMonitoredFence(monitorFence);
} }
bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override { bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override {
return createMonitoredFence(monitorFence); return createMonitoredFence(monitorFence);
}; };

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
namespace NEO {
class WddmMockInterface32 : public WddmInterface32 {
public:
using WddmInterface32::WddmInterface32;
bool createHwQueue(OsContextWin &osContext) override {
createHwQueueCalled++;
createHwQueueResult = forceCreateHwQueueFail ? false : WddmInterface23::createHwQueue(osContext);
return createHwQueueResult;
}
void destroyMonitorFence(MonitoredFence &monitorFence) override {
destroyMonitorFenceCalled++;
WddmInterface32::destroyMonitorFence(monitorFence);
}
bool createSyncObject(MonitoredFence &monitorFence) override {
createSyncObjectCalled++;
WddmInterface32::createSyncObject(monitorFence);
return true;
}
uint32_t createHwQueueCalled = 0;
uint32_t createSyncObjectCalled = 0;
bool forceCreateHwQueueFail = false;
bool createHwQueueResult = false;
uint32_t destroyMonitorFenceCalled = 0;
};
} // namespace NEO

View File

@ -9,5 +9,6 @@ if(UNIX AND NOT DISABLE_WDDM_LINUX)
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/configure_device_address_space_drm_or_wddm_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/configure_device_address_space_drm_or_wddm_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ccs_mode_drm_or_wddm_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ccs_mode_drm_or_wddm_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm32_tests_extra.cpp
) )
endif() endif()

View File

@ -0,0 +1,15 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/unit_test/os_interface/windows/wddm32_tests.h"
using namespace NEO;
TEST_F(Wddm32Tests, whencreateMonitoredFenceForDirectSubmissionThenObtainHwQueueFenceAndReplaceResidencyControllerWithNewFence) {
MonitoredFence fence{};
EXPECT_THROW(wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext), std::exception);
}

View File

@ -1,5 +1,5 @@
# #
# Copyright (C) 2019-2024 Intel Corporation # Copyright (C) 2019-2025 Intel Corporation
# #
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
# #
@ -34,6 +34,7 @@ if(WIN32)
${CMAKE_CURRENT_SOURCE_DIR}/wddm_special_heap_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_special_heap_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_reservation_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_reservation_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm_windows_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_windows_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm32_tests_extra.cpp
${CMAKE_CURRENT_SOURCE_DIR}/${BRANCH_DIR_SUFFIX}/wddm_perf_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${BRANCH_DIR_SUFFIX}/wddm_perf_tests.cpp
) )
endif() endif()
@ -43,6 +44,7 @@ if(WIN32 OR(UNIX AND NOT DISABLE_WDDM_LINUX))
${IGDRCL_SRC_tests_wddm_interface} ${IGDRCL_SRC_tests_wddm_interface}
${CMAKE_CURRENT_SOURCE_DIR}/wddm20_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm20_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm23_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm23_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm32_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gdi_interface_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gdi_interface_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm_address_space_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_address_space_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wddm_mapper_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_mapper_tests.cpp

View File

@ -348,7 +348,7 @@ TEST_F(Wddm20WithMockGdiDllTests, GivenCpuValueDifferentThanGpuHangIndicationWhe
TEST_F(Wddm20WithMockGdiDllTests, whencreateMonitoredFenceForDirectSubmissionThenCreateFence) { TEST_F(Wddm20WithMockGdiDllTests, whencreateMonitoredFenceForDirectSubmissionThenCreateFence) {
MonitoredFence fence{}; MonitoredFence fence{};
wddm->getWddmInterface()->createMonitoredFenceForDirectSubmission(fence, *osContext); wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext);
EXPECT_EQ(wddmMockInterface->createMonitoredFenceCalled, 1u); EXPECT_EQ(wddmMockInterface->createMonitoredFenceCalled, 1u);
EXPECT_NE(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle); EXPECT_NE(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle);
wddm->getWddmInterface()->destroyMonitorFence(fence); wddm->getWddmInterface()->destroyMonitorFence(fence);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -114,7 +114,7 @@ TEST_F(Wddm23Tests, whencreateMonitoredFenceForDirectSubmissionThenObtainHwQueue
osContext->getResidencyController().getMonitoredFence().currentFenceValue = 2u; osContext->getResidencyController().getMonitoredFence().currentFenceValue = 2u;
osContext->getResidencyController().getMonitoredFence().lastSubmittedFence = 1u; osContext->getResidencyController().getMonitoredFence().lastSubmittedFence = 1u;
MonitoredFence fence{}; MonitoredFence fence{};
wddm->getWddmInterface()->createMonitoredFenceForDirectSubmission(fence, *osContext); wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext);
EXPECT_EQ(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle); EXPECT_EQ(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle);
EXPECT_NE(osContext->getResidencyController().getMonitoredFence().fenceHandle, osContext->getHwQueue().progressFenceHandle); EXPECT_NE(osContext->getResidencyController().getMonitoredFence().fenceHandle, osContext->getHwQueue().progressFenceHandle);
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().currentFenceValue, 2u); EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().currentFenceValue, 2u);

View File

@ -0,0 +1,179 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/unit_test/os_interface/windows/wddm32_tests.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/variable_backup.h"
using namespace NEO;
TEST_F(Wddm32Tests, whenGetDedicatedVideoMemoryIsCalledThenCorrectValueIsReturned) {
EXPECT_EQ(wddm->dedicatedVideoMemory, wddm->getDedicatedVideoMemory());
}
TEST_F(Wddm32Tests, whenCreateContextIsCalledThenEnableHwQueues) {
EXPECT_TRUE(wddm->wddmInterface->hwQueuesSupported());
EXPECT_EQ(1u, getCreateContextDataFcn()->Flags.HwQueueSupported);
}
TEST_F(Wddm32Tests, givenPreemptionModeWhenCreateHwQueueCalledThenSetGpuTimeoutIfEnabled) {
auto &gfxCoreHelper = this->executionEnvironment.rootDeviceEnvironments[0]->getHelper<GfxCoreHelper>();
auto defaultEngine = gfxCoreHelper.getGpgpuEngineInstances(*this->executionEnvironment.rootDeviceEnvironments[0])[0];
OsContextWin osContextWithoutPreemption(*wddm, 0, 0u,
EngineDescriptorHelper::getDefaultDescriptor(defaultEngine, PreemptionMode::Disabled));
OsContextWin osContextWithPreemption(*wddm, 0, 0, EngineDescriptorHelper::getDefaultDescriptor(defaultEngine, PreemptionMode::MidBatch));
wddm->wddmInterface->createHwQueue(osContextWithoutPreemption);
EXPECT_EQ(0u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
wddm->wddmInterface->createHwQueue(osContextWithPreemption);
EXPECT_EQ(1u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
}
TEST_F(Wddm32Tests, whenDestroyHwQueueCalledThenPassExistingHandle) {
D3DKMT_HANDLE hwQueue = 123;
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
hwQueue = 0;
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
EXPECT_NE(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0
}
TEST_F(Wddm32Tests, whenObjectIsDestructedThenDestroyHwQueue) {
D3DKMT_HANDLE hwQueue = 123;
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
osContext.reset();
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
}
TEST_F(Wddm32Tests, givenCmdBufferWhenSubmitCalledThenSetAllRequiredFiledsAndUpdateMonitoredFence) {
uint64_t cmdBufferAddress = 123;
size_t cmdSize = 456;
auto hwQueue = osContext->getHwQueue();
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
EXPECT_EQ(0u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
WddmSubmitArguments submitArgs = {};
submitArgs.contextHandle = osContext->getWddmContextHandle();
submitArgs.hwQueueHandle = hwQueue.handle;
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader, submitArgs);
EXPECT_EQ(cmdBufferAddress, getSubmitCommandToHwQueueDataFcn()->CommandBuffer);
EXPECT_EQ(static_cast<UINT>(cmdSize), getSubmitCommandToHwQueueDataFcn()->CommandLength);
EXPECT_EQ(hwQueue.handle, getSubmitCommandToHwQueueDataFcn()->hHwQueue);
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().lastSubmittedFence, getSubmitCommandToHwQueueDataFcn()->HwQueueProgressFenceId);
EXPECT_EQ(&cmdBufferHeader, getSubmitCommandToHwQueueDataFcn()->pPrivateDriverData);
EXPECT_EQ(static_cast<UINT>(sizeof(COMMAND_BUFFER_HEADER)), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceVA);
EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceValue);
EXPECT_EQ(2u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
}
TEST_F(Wddm32Tests, givenDebugVariableSetWhenSubmitCalledThenUseCmdBufferHeaderSizeForPrivateDriverDataSize) {
DebugManagerStateRestore restore;
debugManager.flags.UseCommandBufferHeaderSizeForWddmQueueSubmission.set(true);
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
WddmSubmitArguments submitArgs = {};
submitArgs.contextHandle = osContext->getWddmContextHandle();
submitArgs.hwQueueHandle = osContext->getHwQueue().handle;
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
wddm->submit(123, 456, &cmdBufferHeader, submitArgs);
EXPECT_EQ(static_cast<UINT>(sizeof(COMMAND_BUFFER_HEADER)), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
debugManager.flags.UseCommandBufferHeaderSizeForWddmQueueSubmission.set(false);
cmdBufferHeader = {};
submitArgs = {};
submitArgs.contextHandle = osContext->getWddmContextHandle();
submitArgs.hwQueueHandle = osContext->getHwQueue().handle;
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
wddm->submit(123, 456, &cmdBufferHeader, submitArgs);
EXPECT_EQ(static_cast<UINT>(MemoryConstants::pageSize), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
}
TEST_F(Wddm32Tests, whenMonitoredFenceIsCreatedThenSetupAllRequiredFields) {
wddm->wddmInterface->createMonitoredFence(*osContext);
auto hwQueue = osContext->getHwQueue();
EXPECT_EQ(hwQueue.progressFenceCpuVA, osContext->getResidencyController().getMonitoredFence().cpuAddress);
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
EXPECT_EQ(hwQueue.progressFenceHandle, osContext->getResidencyController().getMonitoredFence().fenceHandle);
EXPECT_EQ(hwQueue.progressFenceGpuVA, osContext->getResidencyController().getMonitoredFence().gpuAddress);
EXPECT_EQ(0u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
}
TEST_F(Wddm32Tests, givenCurrentPendingFenceValueGreaterThanPendingFenceValueWhenSubmitCalledThenCallWaitOnGpu) {
uint64_t cmdBufferAddress = 123;
size_t cmdSize = 456;
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
WddmSubmitArguments submitArgs = {};
submitArgs.contextHandle = osContext->getWddmContextHandle();
submitArgs.hwQueueHandle = osContext->getHwQueue().handle;
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
VariableBackup<volatile uint64_t> pagingFenceBackup(wddm->pagingFenceAddress);
*wddm->pagingFenceAddress = 1;
wddm->currentPagingFenceValue = 1;
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader, submitArgs);
EXPECT_EQ(0u, wddm->waitOnGPUResult.called);
wddm->currentPagingFenceValue = 2;
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader, submitArgs);
EXPECT_EQ(1u, wddm->waitOnGPUResult.called);
}
TEST_F(Wddm32Tests, givenDestructionOsContextWinWhenCallingDestroyMonitorFenceThenDoNotCallDestroy) {
osContext.reset(nullptr);
EXPECT_EQ(0u, wddmMockInterface->destroyMonitorFenceCalled);
EXPECT_EQ(0u, getDestroySynchronizationObjectDataFcn()->hSyncObject);
}
TEST_F(Wddm32TestsWithoutWddmInit, whenInitCalledThenInitializeNewGdiDDIsAndCallToCreateHwQueue) {
EXPECT_EQ(nullptr, wddm->getGdi()->createHwQueue.mFunc);
EXPECT_EQ(nullptr, wddm->getGdi()->destroyHwQueue.mFunc);
EXPECT_EQ(nullptr, wddm->getGdi()->submitCommandToHwQueue.mFunc);
init();
EXPECT_EQ(1u, wddmMockInterface->createHwQueueCalled);
EXPECT_NE(nullptr, wddm->getGdi()->createHwQueue.mFunc);
EXPECT_NE(nullptr, wddm->getGdi()->destroyHwQueue.mFunc);
EXPECT_NE(nullptr, wddm->getGdi()->submitCommandToHwQueue.mFunc);
}
TEST_F(Wddm32TestsWithoutWddmInit, whenCreateHwQueueFailedThenReturnFalseFromInit) {
wddmMockInterface->forceCreateHwQueueFail = true;
EXPECT_ANY_THROW(init());
}
TEST_F(Wddm32TestsWithoutWddmInit, givenFailureOnGdiInitializationWhenCreatingHwQueueThenReturnFailure) {
struct MyMockGdi : public Gdi {
bool setupHwQueueProcAddresses() override {
return false;
}
};
auto myMockGdi = new MyMockGdi();
wddm->resetGdi(myMockGdi);
EXPECT_ANY_THROW(init());
EXPECT_EQ(1u, wddmMockInterface->createHwQueueCalled);
EXPECT_FALSE(wddmMockInterface->createHwQueueResult);
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/command_stream/preemption.h"
#include "shared/source/helpers/gfx_core_helper.h"
#include "shared/source/os_interface/windows/gdi_interface.h"
#include "shared/source/os_interface/windows/os_context_win.h"
#include "shared/test/common/helpers/engine_descriptor_helper.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_wddm.h"
#include "shared/test/common/mocks/mock_wddm_interface32.h"
#include "shared/test/common/os_interface/windows/gdi_dll_fixture.h"
#include "shared/test/common/test_macros/hw_test.h"
using namespace NEO;
struct Wddm32TestsWithoutWddmInit : public ::testing::Test, GdiDllFixture {
void SetUp() override {
GdiDllFixture::setUp();
wddm = static_cast<WddmMock *>(Wddm::createWddm(nullptr, *executionEnvironment.rootDeviceEnvironments[0].get()));
auto &osInterface = executionEnvironment.rootDeviceEnvironments[0]->osInterface;
osInterface = std::make_unique<OSInterface>();
osInterface->setDriverModel(std::unique_ptr<DriverModel>(wddm));
wddm->featureTable->flags.ftrWddmHwQueues = true;
wddmMockInterface = new WddmMockInterface32(*wddm);
wddm->wddmInterface.reset(wddmMockInterface);
}
void init() {
auto preemptionMode = PreemptionHelper::getDefaultPreemptionMode(*defaultHwInfo);
wddmMockInterface = static_cast<WddmMockInterface32 *>(wddm->wddmInterface.release());
wddm->init();
wddm->wddmInterface.reset(wddmMockInterface);
auto &gfxCoreHelper = this->executionEnvironment.rootDeviceEnvironments[0]->getHelper<GfxCoreHelper>();
osContext = std::make_unique<OsContextWin>(*wddm, 0, 0u,
EngineDescriptorHelper::getDefaultDescriptor(gfxCoreHelper.getGpgpuEngineInstances(*this->executionEnvironment.rootDeviceEnvironments[0])[0], preemptionMode));
osContext->ensureContextInitialized(false);
}
void TearDown() override {
GdiDllFixture::tearDown();
}
MockExecutionEnvironment executionEnvironment;
std::unique_ptr<OsContextWin> osContext;
WddmMock *wddm = nullptr;
WddmMockInterface32 *wddmMockInterface = nullptr;
};
struct Wddm32Tests : public Wddm32TestsWithoutWddmInit {
using Wddm32TestsWithoutWddmInit::TearDown;
void SetUp() override {
Wddm32TestsWithoutWddmInit::SetUp();
init();
}
};

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/unit_test/os_interface/windows/wddm32_tests.h"
using namespace NEO;
TEST_F(Wddm32Tests, whencreateMonitoredFenceForDirectSubmissionThenObtainHwQueueFenceAndReplaceResidencyControllerWithNewFence) {
MonitoredFence fence{};
wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext);
EXPECT_EQ(wddmMockInterface->createSyncObjectCalled, 1u);
}